|
1 .. -*- coding: utf-8 -*- |
|
2 |
|
3 .. _Overview: |
|
4 |
|
5 Aperçu rapide de `CubicWeb` |
|
6 =========================== |
|
7 |
|
8 `CubicWeb` nous permet de développer des instances d'applications web |
|
9 basées sur un ou plusieurs `cube`. |
|
10 |
|
11 Ce à quoi nous réferrons en parlant de `cube` est un modèle définissant |
|
12 des types de données et des vues. Un `cube` est un composant re-utilisable |
|
13 regroupé avec d'autres cubes sur le système de fichiers. |
|
14 |
|
15 Un `instance` réferre à une installation spécifique d'un ou plusieurs cubes |
|
16 où sont regroupés tous les fichiers de configuration de l'application web finale. |
|
17 |
|
18 Dans ce document, nous allons vous montrer comment créer un cube et l'utiliser |
|
19 dans une instance pour votre application web. |
|
20 |
|
21 Créez votre cube |
|
22 ---------------- |
|
23 |
|
24 Après avoir installé votre environement de développement `CubicWeb`, vous pouvez |
|
25 commencer à construire votre premier cube: :: |
|
26 |
|
27 cubicweb-ctl newcube blog |
|
28 |
|
29 Cela va créer dans ``/path/to/forest/cubes`` une répertoire contenant :: |
|
30 |
|
31 blog/ |
|
32 | |
|
33 |-- data/ |
|
34 | |-- cubes.blog.css |
|
35 | |-- cubes.blog.js |
|
36 | |-- external_resources |
|
37 | |
|
38 |-- debian/ |
|
39 | |-- changelog |
|
40 | |-- compat |
|
41 | |-- control |
|
42 | |-- copyright |
|
43 | |-- cubicweb-blog.prerm |
|
44 | |-- rules |
|
45 | |
|
46 |-- entities.py |
|
47 | |
|
48 |-- i18n/ |
|
49 | |-- en.po |
|
50 | |-- fr.po |
|
51 | |
|
52 |-- __init__.py |
|
53 | |
|
54 |-- MANIFEST.in |
|
55 | |
|
56 |-- migration/ |
|
57 | |-- postcreate.py |
|
58 | |-- precreate.py |
|
59 | |
|
60 |-- __pkginfo__.py |
|
61 | |
|
62 |-- schema.py |
|
63 | |
|
64 |-- setup.py |
|
65 | |
|
66 |-- site_cubicweb.py |
|
67 | |
|
68 |-- sobjects.py |
|
69 | |
|
70 |-- test/ |
|
71 | |-- data/ |
|
72 | |-- bootstrap_cubes |
|
73 | |-- pytestconf.py |
|
74 | |-- realdb_test_blog.py |
|
75 | |-- test_blog.py |
|
76 | |
|
77 |-- views.py |
|
78 |
|
79 Toute modification apportée à votre modele de données devra |
|
80 etre effectué dans ce répertoire. |
|
81 |
|
82 |
|
83 |
|
84 Définissez votre schéma de données |
|
85 ---------------------------------- |
|
86 |
|
87 Le modèle de données ou schéma est au coeur d'une application `CubicWeb`. |
|
88 C'est là où vous allez devoir définir le type de contenu que votre application |
|
89 devra gérer. |
|
90 |
|
91 Votre modele de données est défini dans le fichier ``schema.py`` de votre cube |
|
92 ``blog`` comme suit. |
|
93 |
|
94 :: |
|
95 |
|
96 from cubicweb.schema import format_constraint |
|
97 class Blog(EntityType): |
|
98 title = String(maxsize=50, required=True) |
|
99 description = String() |
|
100 |
|
101 class BlogEntry(EntityType): |
|
102 title = String(required=True, fulltextindexed=True, maxsize=256) |
|
103 publish_date = Date(default='TODAY') |
|
104 content = String(required=True, fulltextindexed=True) |
|
105 entry_of = SubjectRelation('Blog', cardinality='?*') |
|
106 |
|
107 Un ``Blog`` a un titre et une description. Le titre est une chaîne |
|
108 de caractères requise par la classe parente EntityType et ne doit |
|
109 pas excéder 50 caractères. La description est une chaîne de |
|
110 caractères sans contraintes. |
|
111 |
|
112 Une ``BlogEntry`` a un titre, une date de publication et du texte |
|
113 étant son contenu. Le titre est une chaîne de caractères qui ne |
|
114 doit pas excéder 100 caractères. La date de publication est de type Date et a |
|
115 pour valeur par défaut TODAY, ce qui signifie que lorsqu'une |
|
116 ``BlogEntry`` sera créée, sa date de publication sera la date |
|
117 courante a moins de modifier ce champ. Le texte est une chaîne de |
|
118 caractères qui sera indexée en plein texte et sans contraintes. |
|
119 |
|
120 Une ``BlogEntry`` a aussi une relation nommée ``entry_of`` qui la |
|
121 relie à un ``Blog``. La cardinalité ``?*`` signifie que BlogEntry |
|
122 peut faire partie de zero a un Blog (``?`` signifie `zero ou un`) et |
|
123 qu'un Blog peut avoir une infinité de BlogEntry (``*`` signifie |
|
124 `n'importe quel nombre incluant zero`). |
|
125 Par soucis de complétude, nous rappellerons que ``+`` signifie |
|
126 `un ou plus`. |
|
127 |
|
128 |
|
129 Créez votre instance |
|
130 -------------------- |
|
131 |
|
132 :: |
|
133 |
|
134 cubicweb-ctl create blog blogdemo |
|
135 |
|
136 Cette commande va créer un répertoire ``~/etc/cubicweb.d/blogdemo`` |
|
137 contenant tous les fichiers de configuration nécessaire au lancement |
|
138 de votre application web. |
|
139 |
|
140 L'instance ``blogdemo`` est construite sur le cube ``blog``. |
|
141 |
|
142 Bienvenue dans votre application web |
|
143 ------------------------------------ |
|
144 |
|
145 Lancez votre application en exécutant : :: |
|
146 |
|
147 cubicweb-ctl start -D blogdemo |
|
148 |
|
149 |
|
150 Vous pouvez à présent accéder à votre application web vous permettant de |
|
151 créer des blogs et d'y poster des messages en visitant l'URL http://localhost:8080/. |
|
152 Un premier formulaire d'authentification va vous être proposé. Par défaut, |
|
153 l'application n'autorisera pas d'utilisateur anonyme à accéder a votre |
|
154 application. Vous devrez donc utiliser l'utilisateur administrateur que |
|
155 vous aurez crée lors de l'initialisation de votre base de données via |
|
156 ``cubicweb-ctl create``. |
|
157 |
|
158 .. image:: images/login-form.png |
|
159 |
|
160 |
|
161 Une fois authentifié, vous pouvez commencer à jouer avec votre |
|
162 application et créer des entités. Bravo ! |
|
163 |
|
164 .. image:: images/blog-demo-first-page.png |
|
165 |
|
166 |
|
167 Rappelez-vous que pour le moment, tout a été géré par la plate-forme |
|
168 `CubicWeb` et que la seule chose qui a été fournie est le schéma de |
|
169 données. |
|
170 |
|
171 Créons des entités |
|
172 ------------------ |
|
173 |
|
174 Nous allons maintenant créer quelques entités dans notre application. |
|
175 |
|
176 Créez un Blog |
|
177 ~~~~~~~~~~~~~ |
|
178 |
|
179 Créons à présent quelques entités. Cliquez sur `[+]` sur la |
|
180 droite du lien Blog. Appelez cette nouvelle entité Blog ``Tech-Blog`` |
|
181 et tapez pour la description ``everything about technology``, |
|
182 puis validez le formulaire d'édition en cliquant sur le bouton |
|
183 ``Validate``. |
|
184 |
|
185 .. image:: images/cbw-create-blog.fr.png |
|
186 :alt: from to create blog |
|
187 |
|
188 En cliquant sur le logo situé dans le coin gauche de la fenêtre, |
|
189 vous allez être redirigé vers la page d'accueil. Ensuite, si vous allez |
|
190 sur le lien Blog, vous devriez voir la liste des entités Blog, en particulier |
|
191 celui que vous venez juste de créer ``Tech-Blog``. |
|
192 |
|
193 .. image:: images/cbw-list-one-blog.fr.png |
|
194 :alt: displaying a list of a single blog |
|
195 |
|
196 Si vous cliquez sur ``Tech-Blog`` vous devriez obtenir une description |
|
197 détaillée, ce qui dans notre cas, n'est rien de plus que le titre |
|
198 et la phrase ``everything about technology`` |
|
199 |
|
200 Maintenant retournons sur la page d'accueil et créons un nouveau |
|
201 Blog ``MyLife`` et retournons sur la page d'accueil, puis suivons |
|
202 le lien Blog et nous constatons qu'à présent deux blogs sont listés. |
|
203 |
|
204 .. image:: images/cbw-list-two-blog.fr.png |
|
205 :alt: displaying a list of two blogs |
|
206 |
|
207 Créons un article |
|
208 ~~~~~~~~~~~~~~~~~ |
|
209 |
|
210 Revenons sur la page d'accueil et cliquons sur `[+]` à droite du lien |
|
211 `articles`. Appellons cette nouvelle entité ``Hello World`` et introduisons |
|
212 un peut de texte avant de ``Valider``. Vous venez d'ajouter un article |
|
213 sans avoir précisé à quel Blog il appartenait. Dans la colonne de gauche |
|
214 se trouve une boite intitulé ``actions``, cliquez sur le menu ``modifier``. |
|
215 Vous êtes de retour sur le formulaire d'édition de l'article que vous |
|
216 venez de créer, à ceci près que ce formulaire a maintenant une nouvelle |
|
217 section intitulée ``ajouter relation``. Choisissez ``entry_of`` dans ce menu, |
|
218 cela va faire apparaitre une deuxième menu déroulant dans lequel vous |
|
219 allez pouvoir séléctionner le Blog ``MyLife``. |
|
220 |
|
221 Vous auriez pu aussi, au moment où vous avez crée votre article, sélectionner |
|
222 ``appliquer`` au lieu de ``valider`` et le menu ``ajouter relation`` serait apparu. |
|
223 |
|
224 .. image:: images/cbw-add-relation-entryof.fr.png |
|
225 :alt: editing a blog entry to add a relation to a blog |
|
226 |
|
227 Validez vos modifications en cliquant sur ``Valider``. L'entité article |
|
228 qui est listée contient maintenant un lien vers le Blog auquel il |
|
229 appartient, ``MyLife``. |
|
230 |
|
231 .. image:: images/cbw-detail-one-blogentry.fr.png |
|
232 :alt: displaying the detailed view of a blogentry |
|
233 |
|
234 Rappelez-vous que pour le moment, tout a été géré par la plate-forme |
|
235 `CubicWeb` et que la seule chose qui a été fournie est le schéma de |
|
236 données. D'ailleurs pour obtenir une vue graphique du schéma, visitez |
|
237 le lien `Application schema`` a l'URL suivante : |
|
238 http://localhost:8080/view?vid=schema |
|
239 |
|
240 .. image:: images/cbw-schema.fr.png |
|
241 :alt: graphical view of the schema (aka data-model) |
|
242 |
|
243 |
|
244 Définissez les vues de vos données |
|
245 ---------------------------------- |
|
246 |
|
247 Le principe de sélection des vues |
|
248 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
249 |
|
250 Une vue est une classe Python qui inclut: |
|
251 |
|
252 - un identifiant (tous les objets dans `CubicWeb` sont listés |
|
253 dans un registre et cet identifiant est utilisé comme la clé) |
|
254 |
|
255 - un filtre de sélection de `result sets` auxquels il |
|
256 peut s'appliquer |
|
257 |
|
258 `CubicWeb` fournit un ensemble de vues standard pour le type d'objet |
|
259 `EntityView`. vous poubez les trouver listées dans ``cubicweb/web/views``. |
|
260 |
|
261 Une vue est appliquée sur un `result set` qui représente l'ensemble |
|
262 des entités que nous cherchons à appliquer. `CubicWeb` utilise un |
|
263 sélecteur qui permet de calculer un score et d'identifier la vue |
|
264 la plus adaptée au `result set` que nous voulons afficher. La librarie |
|
265 standard des sélecteurs se trouve dans ``cubicweb.common.selector`` |
|
266 et une librairie des méthodes utilisées pour calculer les scores |
|
267 est dans ``cubicweb.vregistry.vreq``. |
|
268 |
|
269 |
|
270 Il est possible de définir plusieurs vues ayant le meme identifiant |
|
271 et d'y associer des sélecteurs et des filtres afin de permettre à |
|
272 l'application de s'adapter au mieux aux données que nous avons |
|
273 besoin d'afficher. Nous verrons cela plus en détails dans :ref:`DefinitionVues`. |
|
274 |
|
275 On peut citer l'exemple de la vue nommée ``primary`` qui est celle utilisée |
|
276 pour visualiser une entité seule. Nous allons vous montrer comment modifier |
|
277 cette vue. |
|
278 |
|
279 Modification des vues |
|
280 ~~~~~~~~~~~~~~~~~~~~~ |
|
281 Si vous souhaitez modifier la manière dont est rendue un article (`Blogentry`), |
|
282 vous devez surcharger la vue ``primary`` définie dans le module ``views`` de |
|
283 votre cube, ``cubes/blog/views.py``. |
|
284 |
|
285 Nous pourrions par exemple ajouter devant la date de publication un préfixe |
|
286 indiquant que la date visualisée est la date de publication. |
|
287 |
|
288 Pour cela appliquez les modifications suivantes: |
|
289 |
|
290 :: |
|
291 |
|
292 from cubicweb.web.views import baseviews |
|
293 |
|
294 |
|
295 class BlogEntryPrimaryView(baseviews.PrimaryView): |
|
296 |
|
297 accepts = ('BlogEntry',) |
|
298 |
|
299 def render_entity_title(self, entity): |
|
300 self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title())) |
|
301 |
|
302 def content_format(self, entity): |
|
303 return entity.view('reledit', rtype='content_format') |
|
304 |
|
305 def cell_call(self, row, col): |
|
306 entity = self.entity(row, col) |
|
307 |
|
308 # display entity attributes with prefixes |
|
309 self.w(u'<h1>%s</h1>' % entity.title) |
|
310 self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d')) |
|
311 self.w(u'<p>%s</p>' % entity.content) |
|
312 |
|
313 # display relations |
|
314 siderelations = [] |
|
315 if self.main_related_section: |
|
316 self.render_entity_relations(entity, siderelations) |
|
317 |
|
318 .. note:: |
|
319 Lors qu'une vue est modifiée il n'est pas nécessaire de relancer |
|
320 l'application. Sauvez juste le fichier Python et rechargez la page |
|
321 dans votre navigateur afin de visualiser les modifications. |
|
322 |
|
323 |
|
324 Nous pouvons voir que la date de publication est préfixée comme souhaitée. |
|
325 |
|
326 |
|
327 .. image:: images/cbw-update-primary-view.fr.png |
|
328 :alt: modified primary view |
|
329 |
|
330 |
|
331 |
|
332 Le code que nous avons modifié définit une vue primaire pour une entité de |
|
333 type `BlogEntry`. |
|
334 |
|
335 Etant donné que les vues sont appliquées sur des `result sets` et que |
|
336 les `result sets` peuvent être des tableaux de données, il est indispensable |
|
337 de récupérer l'entité selon ses coordonnées (row,col). |
|
338 |
|
339 La méthode ``self.w()`` est utilisée pour afficher des données. En particulier |
|
340 dans notre exemple, nous l'utilisons pour afficher des tags HTML et des valeurs |
|
341 des attributs de notre entité. |
|
342 |
|
343 |