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