1 .. -*- coding: utf-8 -*- |
|
2 |
|
3 .. _Overview: |
|
4 |
|
5 Quick overview of `CubicWeb` |
|
6 ============================ |
|
7 |
|
8 `CubicWeb` allows us to develop web applications instances based on |
|
9 one or more `cubes`. |
|
10 |
|
11 What we call a `cube` is a model defining the data types and views. |
|
12 A `cube` is a reusable component grouped with others cubes in the file |
|
13 system. |
|
14 |
|
15 An `instance` refers to a specific installation of one or more `cubes` |
|
16 where are grouped configuration files of the final web application. |
|
17 |
|
18 In this document, we will show you how to create a `cube` and how to use it |
|
19 in an `instance` for your web application. |
|
20 |
|
21 Create your cube |
|
22 ---------------- |
|
23 |
|
24 After you installed your `CubicWeb` development environment, you can start |
|
25 to build your first cube: :: |
|
26 |
|
27 cubicweb-ctl newcube blog |
|
28 |
|
29 This will create in ``/path/to/forest/cubes`` a directory containing: :: |
|
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 Any changes applied to your data model should be done in this |
|
80 directory. |
|
81 |
|
82 |
|
83 Define your data schema |
|
84 ----------------------- |
|
85 |
|
86 The data model or schema is hte core of your `CubicWeb` application. |
|
87 This is where is defined the type of content you application will handle. |
|
88 |
|
89 The data model is defined in the file ``schema.py`` of your cube |
|
90 ``blog`` such as follows. |
|
91 |
|
92 :: |
|
93 |
|
94 from cubicweb.schema import format_constraint |
|
95 class Blog(EntityType): |
|
96 title = String(maxsize=50, required=True) |
|
97 description = String() |
|
98 |
|
99 class BlogEntry(EntityType): |
|
100 title = String(required=True, fulltextindexed=True, maxsize=256) |
|
101 publish_date = Date(default='TODAY') |
|
102 content = String(required=True, fulltextindexed=True) |
|
103 entry_of = SubjectRelation('Blog', cardinality='?*') |
|
104 |
|
105 |
|
106 A Blog has a title and a description. The title is a string that is |
|
107 required by the class EntityType and must be less than 50 characters. |
|
108 The description is a string that is not constrained. |
|
109 |
|
110 A BlogEntry has a title, a publish_date and a content. The title is a |
|
111 string that is required and must be less than 100 characters. The |
|
112 publish_date is a Date with a default value of TODAY, meaning that |
|
113 when a BlogEntry is created, its publish_date will be the current day |
|
114 unless it is modified. The content is a string that will be indexed in |
|
115 the full-text index and has no constraint. |
|
116 |
|
117 A BlogEntry also has a relationship ``entry_of`` that links it to a |
|
118 Blog. The cardinality ``?*`` means that a BlogEntry can be part of |
|
119 zero or one Blog (``?`` means `zero or one`) and that a Blog can |
|
120 have any number of BlogEntry (``*`` means `any number including |
|
121 zero`). For completeness, remember that ``+`` means `one or more`. |
|
122 |
|
123 |
|
124 Create your instance |
|
125 -------------------- |
|
126 |
|
127 :: |
|
128 |
|
129 cubicweb-ctl create blog blogdemo |
|
130 |
|
131 |
|
132 This command will create a directory ``~/etc/cubicweb.d/blogdemo`` |
|
133 which will contain all the configuration files required to start |
|
134 you web application. |
|
135 |
|
136 The instance ``blogdemo`` is based on the cube ``blog``. |
|
137 |
|
138 |
|
139 Welcome in your web application |
|
140 ------------------------------- |
|
141 |
|
142 Run your application with the following command: :: |
|
143 |
|
144 cubicweb-ctl start -D blogdemo |
|
145 |
|
146 |
|
147 You can now access to your web application to create blogs and post messages |
|
148 by visitin the URL http://localhost:8080/. |
|
149 A login form will first be prompted. By default, the application will not allow |
|
150 anonymous user to get in the application. You should then use the admin |
|
151 account you created at the time you initialized the database with |
|
152 ``cubicweb-ctl create``. |
|
153 |
|
154 .. image:: images/login-form.png |
|
155 |
|
156 |
|
157 Once authenticated, you can start playing with your application |
|
158 and create entities. Bravo! |
|
159 |
|
160 .. image:: images/blog-demo-first-page.png |
|
161 |
|
162 Please notice that so far, `CubicWeb` franework managed all aspects of |
|
163 the web application based in the schema provided at first. |
|
164 |
|
165 |
|
166 Create entities |
|
167 --------------- |
|
168 |
|
169 We will now create a couple of entities in our web application. |
|
170 |
|
171 Create a Blog |
|
172 ~~~~~~~~~~~~~ |
|
173 |
|
174 Let us create a few of these entities. Click on the `[+]` at the right |
|
175 of the link Blog. Call this new Blog ``Tech-blog`` and type in |
|
176 ``everything about technology`` as the description, then validate the |
|
177 form by clicking on ``Validate``. |
|
178 |
|
179 .. image:: images/cbw-create-blog.en.png |
|
180 :alt: from to create blog |
|
181 |
|
182 Click on the logo at top left to get back to the home page, then |
|
183 follow the Blog link that will list for you all the existing Blog. |
|
184 You should be seeing a list with a single item ``Tech-blog`` you |
|
185 just created. |
|
186 |
|
187 .. image:: images/cbw-list-one-blog.en.png |
|
188 :alt: displaying a list of a single blog |
|
189 |
|
190 Clicking on this item will get you to its detailed description except |
|
191 that in this case, there is not much to display besides the name and |
|
192 the phrase ``everything about technology``. |
|
193 |
|
194 Now get back to the home page by clicking on the top-left logo, then |
|
195 create a new Blog called ``MyLife`` and get back to the home page |
|
196 again to follow the Blog link for the second time. The list now |
|
197 has two items. |
|
198 |
|
199 .. image:: images/cbw-list-two-blog.en.png |
|
200 :alt: displaying a list of two blogs |
|
201 |
|
202 Create a BlogEntry |
|
203 ~~~~~~~~~~~~~~~~~~ |
|
204 |
|
205 Get back to the home page and click on [+] at the right of the link |
|
206 BlogEntry. Call this new entry ``Hello World`` and type in some text |
|
207 before clicking on ``Validate``. You added a new blog entry without |
|
208 saying to what blog it belongs. There is a box on the left entitled |
|
209 ``actions``, click on the menu item ``modify``. You are back to the form |
|
210 to edit the blog entry you just created, except that the form now has |
|
211 another section with a combobox titled ``add relation``. Chose |
|
212 ``entry_of`` in this menu and a second combobox appears where you pick |
|
213 ``MyLife``. |
|
214 |
|
215 You could also have, at the time you started to fill the form for a |
|
216 new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the |
|
217 combobox titled ``add relation`` would have showed up. |
|
218 |
|
219 |
|
220 .. image:: images/cbw-add-relation-entryof.en.png |
|
221 :alt: editing a blog entry to add a relation to a blog |
|
222 |
|
223 Validate the changes by clicking ``Validate``. The entity BlogEntry |
|
224 that is displayed now includes a link to the entity Blog named |
|
225 ``MyLife``. |
|
226 |
|
227 .. image:: images/cbw-detail-one-blogentry.en.png |
|
228 :alt: displaying the detailed view of a blogentry |
|
229 |
|
230 Please notice that so far, `CubicWeb` franework managed all aspects of |
|
231 the web application based in the schema provided at first. |
|
232 Also if you wish to get a graphical view of the schema, visit |
|
233 the link `Application schema`` which will direct you to : |
|
234 http://localhost:8080/view?vid=schema |
|
235 |
|
236 .. image:: images/cbw-schema.en.png |
|
237 :alt: graphical view of the schema (aka data-model) |
|
238 |
|
239 |
|
240 Define your entities views |
|
241 -------------------------- |
|
242 |
|
243 The views selection principle |
|
244 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
245 |
|
246 A view is defined by a Python class which includes: |
|
247 |
|
248 - an identifier (all objects in `CubicWeb` are entered in a registry |
|
249 and this identifier will be used as a key) |
|
250 |
|
251 - a filter to select the resulsets it can be applied to |
|
252 |
|
253 |
|
254 `CubicWeb` provides a lot of standard views for the type |
|
255 `EntityView`, for a complete list, you |
|
256 will have to read the code in directory ``cubicweb/web/views/`` |
|
257 |
|
258 A view is applied on a `result set` which contains a set of |
|
259 entities we are trying to display. `CubicWeb` uses a selector |
|
260 mecanism which computes a score used to identify which view |
|
261 is the best to apply for the `result set` we are trying to |
|
262 display. The standard library of selectors is in |
|
263 ``cubicweb.common.selector`` and a library of methods used to |
|
264 compute scores is available in ``cubicweb.vregistry.vreq``. |
|
265 |
|
266 It is possible to define multiple views for the same identifier |
|
267 and to associate selectors and filters to allow the application |
|
268 to find the best way to render the data. We will see more details |
|
269 on this in :ref:`DefinitionVues`. |
|
270 |
|
271 For example, the view named ``primary`` is the one used to display |
|
272 a single entity. We will now show you hos to customize this view. |
|
273 |
|
274 |
|
275 View customization |
|
276 ~~~~~~~~~~~~~~~~~~ |
|
277 |
|
278 If you wish to modify the way a `BlogEntry` is rendered, you will have to |
|
279 overwrite the `primary` view defined in the module ``views`` of the cube |
|
280 ``cubes/blog/views.py``. |
|
281 |
|
282 We can by example add in front of the pulication date a prefix specifying |
|
283 the date we see is the publication date. |
|
284 |
|
285 To do so, please apply the following changes: |
|
286 |
|
287 :: |
|
288 |
|
289 from cubicweb.web.views import baseviews |
|
290 |
|
291 |
|
292 class BlogEntryPrimaryView(baseviews.PrimaryView): |
|
293 |
|
294 accepts = ('BlogEntry',) |
|
295 |
|
296 def render_entity_title(self, entity): |
|
297 self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title())) |
|
298 |
|
299 def content_format(self, entity): |
|
300 return entity.view('reledit', rtype='content_format') |
|
301 |
|
302 def cell_call(self, row, col): |
|
303 entity = self.entity(row, col) |
|
304 |
|
305 # display entity attributes with prefixes |
|
306 self.w(u'<h1>%s</h1>' % entity.title) |
|
307 self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d')) |
|
308 self.w(u'<p>%s</p>' % entity.content) |
|
309 |
|
310 # display relations |
|
311 siderelations = [] |
|
312 if self.main_related_section: |
|
313 self.render_entity_relations(entity, siderelations) |
|
314 |
|
315 .. note:: |
|
316 When a view is modified, it is not required to restart the application |
|
317 server. Save the Python file and reload the page in your web browser |
|
318 to view the changes. |
|
319 |
|
320 You can now see that the publication date has a prefix. |
|
321 |
|
322 .. image:: images/cbw-update-primary-view.en.png |
|
323 :alt: modified primary view |
|
324 |
|
325 |
|
326 The above source code defines a new primary view for |
|
327 ``BlogEntry``. |
|
328 |
|
329 Since views are applied to resultsets and resulsets can be tables of |
|
330 data, it is needed to recover the entity from its (row,col) |
|
331 coordinates. We will get to this in more detail later. |
|
332 |
|
333 The view has a ``self.w()`` method that is used to output data. In our |
|
334 example we use it to output HTML tags and values of the entity's attributes. |
|
335 |
|