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