.. -*- coding: utf-8 -*-Tutoriel : créer votre première application web pour Google AppEngine=====================================================================[TRANSLATE ME TO FRENCH]This tutorial will guide you step by step to build a blog application and discover the unique features of `LAX`. It assumes that you followedthe :ref:`installation` guidelines and that both the `AppEngine SDK` and the`LAX` framework are setup on your computer.Creating a new application--------------------------We choosed in this tutorial to develop a blog as an example of web applicationand will go through each required steps/actions to have it running with `LAX`.When you installed `LAX`, you saw a directory named ``skel``. Make a copy ofthis directory and call it ``BlogDemo``.The location of this directory does not matter. But once decided, make sure your ``PYTHONPATH`` is properly set (:ref:`installation`).Defining a schema-----------------With `LAX`, the schema/datamodel is the core of the application. This is whereyou will define the type of content you have to hanlde in your application.Let us start with something simple and improve on it iteratively. In schema.py, we define two entities: ``Blog`` and ``BlogEntry``.:: class Blog(EntityType): title = String(maxsize=50, required=True) description = String() class BlogEntry(EntityType): title = String(maxsize=100, required=True) publish_date = Date(default='TODAY') text = String(fulltextindexed=True) category = String(vocabulary=('important','business')) entry_of = SubjectRelation('Blog', cardinality='?*')A Blog has a title and a description. The title is a string that isrequired by the class EntityType and must be less than 50 characters. The description is a string that is not constrained.A BlogEntry has a title, a publish_date and a text. The title is astring that is required and must be less than 100 characters. Thepublish_date is a Date with a default value of TODAY, meaning thatwhen a BlogEntry is created, its publish_date will be the current dayunless it is modified. The text is a string that will be indexed inthe full-text index and has no constraint.A BlogEntry also has a relationship ``entry_of`` that link it to aBlog. The cardinality ``?*`` means that a BlogEntry can be part ofzero or one Blog (``?`` means `zero or one`) and that a Blog canhave any number of BlogEntry (``*`` means `any number includingzero`). For completeness, remember that ``+`` means `one or more`.Running the application-----------------------Defining this simple schema is enough to get us started. Make sure youfollowed the setup steps described in detail in the installationchapter (especially visiting http://localhost:8080/_load as anadministrator), then launch the application with the command:: python dev_appserver.py BlogDemoand point your browser at http://localhost:8080/ (if it is easier foryou, use the on-line demo at http://lax.appspot.com/)... image:: images/lax-book.00-login.en.png :alt: login screenAfter you log in, you will see the home page of your application. Itlists the entity types: Blog and BlogEntry. If these links read``blog_plural`` and ``blogentry_plural`` it is becauseinternationalization (i18n) is not working for you yet. Please ignorethis for now... image:: images/lax-book.01-start.en.png :alt: home pageCreating system entities------------------------You can only create new users if you decided not to use google authentication.[WRITE ME : create users manages permissions etc]Creating application entites----------------------------Create a Blog~~~~~~~~~~~~~Let us create a few of these entities. Click on the [+] at the rightof the link Blog. Call this new Blog ``Tech-blog`` and type in``everything about technology`` as the description, then validate theform by clicking on ``Validate``... image:: images/lax-book.02-create-blog.en.png :alt: from to create blogClick on the logo at top left to get back to the home page, thenfollow the Blog link that will list for you all the existing Blog.You should be seeing a list with a single item ``Tech-blog`` youjust created... image:: images/lax-book.03-list-one-blog.en.png :alt: displaying a list of a single blogClicking on this item will get you to its detailed description exceptthat in this case, there is not much to display besides the name andthe phrase ``everything about technology``... image:: images/lax-book.04-detail-one-blog.en.png :alt: displaying the detailed view of a blogNow get back to the home page by clicking on the top-left logo, thencreate a new Blog called ``MyLife`` and get back to the home pageagain to follow the Blog link for the second time. The list nowhas two items... image:: images/lax-book.05-list-two-blog.en.png :alt: displaying a list of two blogsCreate a BlogEntry~~~~~~~~~~~~~~~~~~Get back to the home page and click on [+] at the right of the linkBlogEntry. Call this new entry ``Hello World`` and type in some textbefore clicking on ``Validate``. You added a new blog entry withoutsaying to what blog it belongs. There is a box on the left entitled``actions``, click on the menu item ``modify``. You are back to the formto edit the blog entry you just created, except that the form now hasanother section with a combobox titled ``add relation``. Chose``entry_of`` in this menu and a second combobox appears where you pick``MyLife``. You could also have, at the time you started to fill the form for anew entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the combobox titled ``add relation`` would have showed up... image:: images/lax-book.06-add-relation-entryof.en.png :alt: editing a blog entry to add a relation to a blogValidate the changes by clicking ``Validate``. The entity BlogEntrythat is displayed now includes a link to the entity Blog named``MyLife``... image:: images/lax-book.07-detail-one-blogentry.en.png :alt: displaying the detailed view of a blogentryRemember that all of this was handled by the framework and that theonly input that was provided so far is the schema. To get a graphicalview of the schema, run the ``laxctl genschema BlogDemo`` command asexplained in the installation section and point your browser to theURL http://localhost:8080/schema.. image:: images/lax-book.08-schema.en.png :alt: graphical view of the schema (aka data-model)Site configuration------------------.. image:: images/lax-book.03-site-config-panel.en.pngThis panel allows you to configure the appearance of your application site.Six menus are available and we will go through each of them to explain howto use them.Navigation~~~~~~~~~~This menu provides you a way to adjust some navigation options depending onyour needs, such as the number of entities to display by page of results.Follows the detailled list of available options:* navigation.combobox-limit: maximum number of entities to display in related combo box (sample format: 23)* navigation.page-size: maximum number of objects displayed by page of results (sample format: 23)* navigation.related-limit: maximum number of related entities to display in the primary view (sample format: 23)* navigation.short-line-size: maximum number of characters in short description (sample format: 23)UI~~This menu provides you a way to customize the user interface settings such asdate format or encoding in the produced html.Follows the detailled list of available options:* ui.date-format : how to format date in the ui ("man strftime" for format description)* ui.datetime-format : how to format date and time in the ui ("man strftime" for format description)* ui.default-text-format : default text format for rich text fields.* ui.encoding : user interface encoding* ui.fckeditor : should html fields being edited using fckeditor (a HTML WYSIWYG editor). You should also select text/html as default text format to actually get fckeditor.* ui.float-format : how to format float numbers in the ui* ui.language : language of the user interface* ui.main-template : id of main template used to render pages* ui.site-title : site title, which is displayed right next to the logo in the header* ui.time-format : how to format time in the ui ("man strftime" for format description)Actions~~~~~~~This menu provides a way to configure the context in which you expect the actionsto be displayed to the user and if you want the action to be visible or not. You must have notice that when you view a list of entities, an action box is available on the left column which display some actions as well as a drop-down menu for more actions. The context available are:* mainactions : actions listed in the left box* moreactions : actions listed in the `more` menu of the left box* addrelated : add actions listed in the left box* useractions : actions listed in the first section of drop-down menu accessible from the right corner user login link* siteactions : actions listed in the second section of drop-down menu accessible from the right corner user login link* hidden : select this to hide the specific actionBoxes~~~~~The application has already a pre-defined set of boxes you can use right away. This configuration section allows you to place those boxes where you want in theapplication interface to customize it. The available boxes are:* actions box : box listing the applicable actions on the displayed data* boxes_blog_archives_box : box listing the blog archives * possible views box : box listing the possible views for the displayed data* rss box : RSS icon to get displayed data as a RSS thread* search box : search box* startup views box : box listing the configuration options available for the application site, such as `Preferences` and `Site Configuration`Components~~~~~~~~~~[WRITE ME]Contextual components~~~~~~~~~~~~~~~~~~~~~[WRITE ME]Set-up a workflow-----------------Before starting, make sure you refresh your mind by reading [link todefinition_workflow chapter].We want to create a workflow to control the quality of the BlogEntry submitted on your application. When a BlogEntry is created by a userits state should be `submitted`. To be visible to all, it needs tobe in the state `published`. To move from `submitted` to `published`we need a transition that we can name `approve_blogentry`.We do not want every user to be allowed to change the state of a BlogEntry. We need to define a group of user, `moderators`, and this group will have appropriate permissions to approve BlogEntryto be published and visible to all.There are two ways to create a workflow, form the user interface,and also by defining it in ``migration/postcreate.py``. This scriptis executed each time a new ``./bin/laxctl db-init`` is done. If you create the states and transitions through the user interfacethis means that next time you will need to initialize the databaseyou will have to re-create all the entities. We strongly recommand you create the workflow in ``migration\postcreate.py``and we will now show you how.The user interface would only be a reference for you to view the states and transitions but is not the appropriate interface to define yourapplication workflow.Update the schema~~~~~~~~~~~~~~~~~To enable a BlogEntry to have a State, we have to define a relation``in_state`` in the schema of BlogEntry. Please do as follows, addthe line ``in_state (...)``:: class BlogEntry(EntityType): title = String(maxsize=100, required=True) publish_date = Date(default='TODAY') text_format = String(meta=True, internationalizable=True, maxsize=50, default='text/rest', constraints=[format_constraint]) text = String(fulltextindexed=True) category = String(vocabulary=('important','business')) entry_of = SubjectRelation('Blog', cardinality='?*') in_state = SubjectRelation('State', cardinality='1*')As you updated the schema, you will have re-execute ``./bin/laxctl db-init``to initialize the database and migrate your existing entities.[WRITE ABOUT MIGRATION]Create states, transitions and group permissions~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~At the time the ``postcreate.py`` script is executed, several methodscan be used. They are all defined in the ``class ServerMigrationHelper``.We will only discuss the method we use to create a wrokflow here.To define our workflow for BlogDemo, please add the following linesto ``migration/postcreate.py``:: _ = unicode moderators = add_entity('CWGroup', name=u"moderators") submitted = add_state(_('submitted'), 'BlogEntry', initial=True) published = add_state(_('published'), 'BlogEntry') add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),) checkpoint()``add_entity`` is used here to define the new group of users that weneed to define the transitions, `moderators`.If this group required by the transition is not defined before thetransition is created, it will not create the relation `transition require the group moderator`.``add_state`` expects as the first argument the name of the state you arewilling to create, then the entity type on which the state can be applied, and an optionnal argument to set if the state is the initial stateof the entity type or not.``add_transition`` expects as the first argument the name of the transition, then the entity type on which we can apply the transition,then the list of possible initial states from which the transitioncan be applied, the target state of the transition, and the permissions(e.g. list of the groups of users who can apply the transition)... image:: images/lax-book.03-transitions-view.en.pngYou can now notice that in the actions box of a BlogEntry, the stateis now listed as well as the possible transitions from this statedefined by the workflow. This transition, as defined in the workflow,will only being displayed for the users belonging to the groupmoderators of managers.Change view permission~~~~~~~~~~~~~~~~~~~~~~Conclusion----------Exercise~~~~~~~~Create new blog entries in ``Tech-blog``.What we learned~~~~~~~~~~~~~~~Creating a simple schema was enough to set up a new application thatcan store blogs and blog entries. What is next ?~~~~~~~~~~~~~~Although the application is fully functionnal, its look is verybasic. In the following section we will learn to create views tocustomize how data is displayed.