Website development on Diem CMS: advantages, philosophy, examples and pitfalls

    Continuation of the story about a wonderful initiative of a group of French web developers called Diem CMS.

    This article is waiting for you


    - a few examples of how Diem can make life easier for the webmaster
    - pitfalls that you may encounter and their possible solutions
    - some philosophical discussions about how Diem is fundamentally different (for the better) from colleagues
    - interesting facts related to the topic
    - as well as screenshots and code examples.
    It turned out to be voluminous and informative.

    Practice


    Preface
    Over the past two months, I have written 6 sites on this CMS from 5-page to 2,000-page, two sites are located on a shared hosting, two on a VPS server. 128 MB of memory everywhere.
    Tar
    Oh, this practice, which showed that using Diem on ordinary shared hosting services at the moment does not bode well ...
    Firstly, a memory limit less than 48MB can cause Fatal error: Allowed memory size of X bytes exhausted, when serving pages it uses about 8MB, but with system calls (like updating the configuration , search engines crawl Zend_Search_Lucene) memory is used much longer (it is possible that the developers here and forget about the memory is full control of when the long cycle)
    Second, in the absence of a standard APC caching bubbled settings./configureDiem processes the page for about two seconds (this is at 200ms on a similar configuration, but with APC) ... approx. this is my guess, the fact is that the script runs on virtual hosting for 2000ms, and for VPS 200ms, APC is installed both there and there, but there is no system support for POSIX shared memory on shared hosting. I think this is the case, although other options are not ruled out.
    In the process of configuring APC with a different configuration, I was helped to figure out what this document was all about: an in-
    imagedepth review and study of APC caching from facebook
    Honey
    From the pleasant: despite the seemingly heavy system, on the cheapest VPS from reg.ru I now have five sites coexist calmly, there is enough memory for everyone, pages are returned 200ms after the request. I am quite satisfied with this fact, considering that Diem is fraught with many more advantages than disadvantages, which I will talk about later, not in this, but in the following posts.
    The small but responsive community is also pleasing. Judging by the speed of responses, developers visit the community every day and are willing to respond, and not sent to Google. (Provlinki: 1 , 2 )

    In the best traditions of Symfony, Diem is supported by high-quality and clear documentation, which includes:
    - Diem week
    immersion in development in 7 days, in practice in 2 hours you can do all the steps of the weekly course
    - how-to tips for common tasks
    - and a detailed step-by-step description of all the CMS features.

    In addition, there is a forum and a Google group where you can ask the community for advice.
    All this is on off.site diem-project.org

    Oh yes. I completely forgot that diem-project.ru will be useful for those who are not strong in English - a partially translated clone of diem-project.org, its creator Vladislav Lezhnev got in touch after the last post, we talked a bit about Diem and basically agreed in the opinions that this CMS is worthy of attention and should be used.

    image An interesting fact: most of the project was written by one person in the period from 08/23/2009 to 01/31/2010 after which about 5 more developers appeared in the project.

    Philosophy


    The main idea in content management is blocking. If in conventional CMS the atomic content unit is the page (whether it is text or a photo gallery), and the use of blocks on the page is implemented additionally and is often very inconvenient, then in Diem the atomic content is a block (it is also a widget).

    As a result, the content structure is as follows: templates -> zones -> pages -> widgets

    For example, we create two templates: two-column and three-column, we defined the page zones on which it will be possible to place widgets. This ends the coding, and starts managing the site. We can create pages, drag the necessary blocks into zones, and edit blocks individually. If you need some special functionality, we write a module (an example of module development below), the module is responsible for the specific processing of blocks and content for this block. And then we add new specific blocks where we want and when we want. A client-customer can do this.

    For example, in the past I often had the need to swap some blocks in the sidebar (the block locations were hardcoded in the template), of course, this was done quickly and easily, but with the handles and in the code. And here are the cons: a long time of change for the customer, the likelihood of making a mistake when editing. Now, the client himself can rearrange the blocks in places, when he wants to.

    I give examples of managing the content of the page:


    In this figure, we see that the page is divided into zones and widgets (blocks), and that they can be dragged.


    In this figure, we see an open media gallery, a breadcrumbs widget editing window, and a widget panel that can be added to the page.

    We are trying to write our own module


    I will give an example from the life of the last project: it is necessary to create a database of hotels with a division by country and, naturally, the possibility of administration. How long do you think this will take? Let's see ...

    Step 1.
    First of all, we design the database (using Doctrine and YAML files, this is a pleasure to do):
    Hotel:
      actAs: [ DmSortable, DmGallery ]
      columns:
        name: { type: string(255), notnull: true }
        country_id: { type: integer }
        url: { type: string(255) }
        text: { type: clob, extra: ckeditor }
        is_active: { type: boolean, notnull: true, default: true }
        rating: { type: float }
        status: { type: integer(4), default:  0 }
        votes: { type: integer }
      relations:
        Products: { foreignAlias: Hotels, class: Product, refClass: ProductHotel }
        Country: { foreignAlias: Hotels }
     
    Country:
      columns:
        name: { type: string(255), notnull: true }
        slug: { type: string(255), notnull: true }


    It seems that everything we need was indicated: a table of hotels, a table of countries, the relationship between them. This code contains several Diem designations that globally define the table behavior for the entire project, namely: is_active, DmSortable, DmGallery и extra: ckeditor.
    The meaning is_activeis that now diem knows that there are “active” and “inactive” objects for hotel lists. Under management, we will be able to manage via ajax activity, and when viewed on the page, only active records will be displayed.
    extra: ckeditoradds when editing WISIWYG.
    DmSortable- allows you to manually sort the list of hotels
    DmGallery- makes it possible to attach an unlimited number of photos to each hotel. All files are stored and managed in Diem using the Media component, i.e. you don’t need to write your own handlers for loading pictures, cropping to size using various methods, moreover, you can specify any sizes of images in templates, Diem will generate a picture of the right size on the fly.

    Step 2.
    Now we need to tell the system how we want to organize entries in modules and components : this is done again using YAML in the corresponding configuration file.

    "Каталог":
     
      hotel:
        model: Hotel
        page: true
        name: 'Отель|Отели'
        admin: true
        components:
          searchForm:
            name: 'Форма поиска'
          searchResults:
            name: 'Результаты поиска'
          show:
     
      country:
        model: Country
        name: 'Страна|Страны'
        admin: true


    What we did: they said that hotel entries would be pages, hotels and countries should have an admin interface, and for the frontend we would need blocks: hotel view, hotel search form and search form results. In addition, the keywords list и show in the name of the components of the frontend allow you to automatically generate a selection of a list or a single object (no need to write database queries), it remains only to complete.

    After describing the database schema and module schema, we execute in the console: We get the generated ORM models, filters and Doctrine forms, admin modules for managing hotels and countries with all the necessary set of actions and templates.
    symfony doctrine:generate-migrations-diff
    symfony doctrine:migrate
    symfony dm:setup







    Not bad for 20 minutes of time spent and about 200 characters printed. I, as a lazy person, was delighted with the possibilities of generating standard functionality, and as a person who loves powerful and high-quality functionality, I was just shocked, well, for example, the shape of the filter, in addition to its immediate purpose: filtering by specific fields, also allows for full-text search in all content module.

    "And that's not all!" (c)
    As a gift, you get generated templates for the frontend, which become available for drag and drop to any area of ​​the page. Unfortunately, Diem does not know how to read minds, typeset and create designs - therefore, this work will have to be done by myself, but here we will have pleasant surprises. Because the article is already bloated, I’ll just give an example for the “hotel list” block:

     
    echo _open('div.product_list');
     
    echo _open('ul.smartcolumns');
     
    foreach($hotels as $hotel)
    {
        $url = _link($hotel)->getHref();
        $data = 'infotext';
     
        ?>
        

  •         
                getNbMedias()) echo _media($hotel->getFirstMedia())->width(100) ?>
            

            

                name ?>

                
    rating ?>

                

            

        

  •     }
     
    echo _close('ul');
     
    echo _close('div');
     
    use_javascript('/js/smartcolumns.js');


    And an example of an action to autocomplete a search form:
     
    / **
     * Hotel actions
     * /
    class hotelActions extends myFrontModuleActions
    {
     
        public function executeAutocomplete (dmWebRequest $ request)
        {
            $ query = $ request-> getParameter ('query', 0);
            if ($ query)
            {
                $ limit = 10;
                $ q = RequestFilter :: sanitizeString ($ query);
     
                $ query = Doctrine_Query :: create ()
                    -> select ('h.id, h.name')
                    -> from ('Hotel h')
                    -> where ("LOWER (name) REGEXP '^ {$ q}. * | [^ -] [-] {$ q} [^)] * $ '")
                    -> orderBy (' h.rating DESC, h.name ASC ')
                    ->
     
                $ res = $ query-> execute ();
     
                if (count ($ res))
                {
                    $ json = array (
                        'suggestions' => array (),
                        'data' => array (),
                    );
     
                    foreach ($ res as $ key => $ val)
                    {
                        $ json ['suggestions'] [] = $ val-> name;
                        $ json ['data'] [] = $ val-> id;
                    }
     
                    $ this-> getResponse () -> setContentType ('application / json');
                    return $ this-> renderText (json_encode ($ json));
                }
            }
     
            return sfView :: NONE;

     


    The layout and actions for all the described functionality took about two hours.

    Underwater rocks


    In a nutshell, I’ll indicate what difficulties may await you during development (the system is still raw and open source)

    1. Russian-language files are not renamed when loading, when generating url, of course there is a conversion to url-valid characters, but I had problems with that some files simply disappeared after loading. More precisely, they remained in the file system and in the database, but Diem did not see them. I think the reason here may be in the use of deprecated functions instead of mb_string_functions. Although the French were supposed to encounter UTF-8 lines ... In general, I didn’t dig too much, I was treated by converting the file name to characters valid for url, for example a-z0-9_-

    2. The memory consumption with each call to the media gallery increases with the growth of files, which is not acceptable for large projects. For a hotel database with 500MB of images, the media library refused to open.
    Having delved into the code, I found a synchronization call every time I access the library object, this is done so that the information about the structure of folders and files in the database is up-to-date (suddenly we upload a file via ftp).
    The thing is resource-intensive and not very necessary, because files are supposed to be downloaded only through the admin interface, comment out the line for synchronization and calm down.

    3. Diem minifies and combines all CSS and JavaScript files to speed up page rendering. And javascript is included at the end of the page, as we were taught by nerdsspecialists from Yahoo. If you want to use javascript in templates and use say jQuery, then you need the jquery library to be connected in the page header. To do this, in config / dm / config.yml you need to specify which javascript files should be included in the header. You can also specify the use of Google CDN to download jquery libraries there.

    Summary


    1. Now you know what Diem CMS is, what development advantages you get using this CMS and how the content management paradigm differs from other CMS.
    2. You know that you can use Diem on VPS or dedicated servers, but on shared hosting it is better not to try. (Although, for the sake of experiment, I think everyone will be interested to know how many milliseconds it takes to generate a page on your hosting)
    3. You got acquainted with an example of developing your own module and, I hope, made sure that with Diem you can do this with a full hand quickly and easily.
    4. You learned what difficulties may arise and how to overcome them.

    Not everything that I wanted to tell fit into the article. The questions of SEO optimization, user access control settings and a small CSS modification that eliminates some layout bugs remained unexplained. I plan to fit these topics into the next article.

    PS: whoever sees the error, will not be able to remain silent and write in a personal letter - I will be grateful and will immediately correct it.

    Also popular now: