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