
The
story continues about the 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 you may encounter and their possible solutions
- a little philosophical reasoning about how Diem is fundamentally different (for the better) from colleagues
- interesting facts related to topic
- as well as screenshots and code samples
It turned out to be voluminous and informative.
Practice
Foreword
Over the past two months I have written 6 sites on this CMS from 5-page to 2000-page, two sites are located on a virtual hosting, two on a VPS server. Memory is 128 MB everywhere.
Tar
Oh, this practice, which showed that the use of Diem on conventional virtual hosting at the moment does not promise anything good ...
First, a memory limit of less than 48Mb can cause
Fatal error: Allowed memory size of X bytes exhausted
, about 8Mb is used when servicing pages, but for system calls (like a configuration update, search engine Zend_Search_Lucene) the memory is used a lot more (it is possible that the developers in some places forgot about the memory filling control when performing long cycles)
Secondly, in the absence of APC caching with standard settings
./configure
, Diem fulfills the page for about two seconds (this is at 200ms on the same configuration, but with APC) ...
approx. This is my guess, the fact is that the script on the virtual hosting runs 2000ms, and on the VPS 200ms, APC is installed there and there, but the virtual hosting does not have POSIX shared memory system support. I think this is the case, although other options are not excluded.
In the process of setting up an APC with different configurations, I was helped to figure out what this document is for:
in-depth review and study of apc caching from facebook
Honey
From the pleasant: despite the apparent heaviness of the system, on the cheapest VPS from reg.ru I now have five websites that get along quietly, there is enough memory for everyone, the pages are sent 200ms after the request. I am quite satisfied with this fact, given that Diem is fraught with many more advantages than disadvantages, which I will tell you about later, but not in this, so in the following posts.
Pleases and small, but responsive community. Judging by the speed of responses, the developers visit the community every day and willingly respond, and do not send to Google. (Pruvlinki:
1 ,
2 )
In the best traditions of Symfony, Diem is supported by high-quality and understandable documentation, which includes:
- week Diem
immersion in development in 7 days, in practice in 2 hours you can do all the steps of the week course
- how-to tips for common tasks
- and a detailed step by step description of all the features of CMS
')
In addition, there is a forum and a Google Group where you can ask the community for advice.
All of this is on off.sayte
diem-project.org
Oh yes. I completely forgot, those who are not strong in English will be useful
diem-project.ru - a partially translated clone diem-project.org, its creator Vladislav Lezhnev got in touch after the last post, we talked a little about Diem and in general agreed in the opinion that this CMS is worthy of attention and should be used.

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 a conventional CMS has an atomic content unit as a page (whether it is a text or a photo gallery), and the use of blocks on the page is implemented additionally and often very inconvenient, then in Diem the atomic content is a block (also known as 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, defined page zones on which widgets can be placed. At this code ends, and begins managing the site. We can create pages, drag necessary blocks into zones, edit blocks individually. If you need some special functionality, we write a module (module development example 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. This can be done by the client.
For example, before I often had the need to swap some of the blocks in the sidebar (the blocks were hardcoded in the template), this was done of course quickly and simply, but in the handles and in the code. And here are the minuses: a long time change for the customer, the probability of making an error when editing. Now the client himself can rearrange the blocks in some places, when he pleases.
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 picture, we see an open media gallery, a window for editing the breadcrumbs widget and a panel of widgets that can be added to the page.
We try 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 the division by country and of course the possibility of administration. How do you think it will take time? We'll see…
Step 1.
First of all, we design the database (using Doctrine and YAML files is a pleasure to do):
Hotel :<br/> actAs : [ DmSortable, DmGallery ] <br/> columns :<br/> name : { type : string( 255 ), notnull : true } <br/> country_id : { type : integer } <br/> url : { type : string( 255 ) } <br/> text : { type : clob, extra : ckeditor } <br/> is_active : { type : boolean, notnull : true , default : true } <br/> rating : { type : float } <br/> status : { type : integer( 4 ), default : 0 } <br/> votes : { type : integer } <br/> relations :<br/> Products : { foreignAlias : Hotels, class : Product, refClass : ProductHotel } <br/> Country : { foreignAlias : Hotels } <br/> <br/> Country :<br/> columns :<br/> name : { type : string( 255 ), notnull : true } <br/> slug : { type : string( 255 ), notnull : true } <br/>
It seems that all that we need is indicated: a table of hotels, a table of countries, the relationship between them. In this code, there are several Diem-notation, which globally for the whole project define the behavior of the table, namely:
is_active, DmSortable, DmGallery extra: ckeditor.
The meaning of
is_active
lies in the fact that now diem knows that there are "active" and "inactive" objects for hotel lists. When managing, we will be able to manage the activity via ajax, and when viewed on the page only active records will be displayed.
extra: ckeditor
adds when editing WISIWYG.
DmSortable
- allows you to manually sort the list of hotels
DmGallery
- allows you 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 do not need to write your own handlers for loading images, trimming to size using different methods, moreover, in templates you can specify any image sizes, Diem will generate a picture of the desired size on the fly.
Step 2.
Now we need to tell the system how we want to organize the entries in the
modules and components : this is done again with the help of YAML in the corresponding configuration file.
"" :<br/> <br/> hotel :<br/> model : Hotel<br/> page : true <br/> name : '|' <br/> admin : true <br/> components :<br/> searchForm :<br/> name : ' ' <br/> searchResults :<br/> name : ' ' <br/> show :<br/> <br/> country :<br/> model : Country<br/> name : '|' <br/> admin : true <br/>
What we did: they said that the hotel-records would be pages, hotels and countries should have an admin interface, and for the frontend we would need blocks: the hotel review, the hotel search form and the search form results. In addition, the keywords
list show
in the name of the frontend components allow you to automatically generate a selection of a list or a single object (no need to write queries to the database), it remains only to complete.
After describing the database schema and module schema, execute in the console:
symfony doctrine:generate-migrations-diff
symfony doctrine:migrate
symfony dm:setup
We get the generated ORM models, Doctrine filters and forms, admin modules for hotels and countries with all the necessary set of actions and patterns.
Not bad for 20 minutes of time spent and about 200 characters printed. As a lazy person, I was delighted with the possibilities of generating standard functionality, and as a person who loves powerful and high-quality functionality, I was just shocked, for example, the form of the filter besides its immediate purpose: filtering by specific fields, also allows you to perform full-text search throughout the content module.
"And that's not all!" (C)
As a gift, you get the generated templates for the frontend, which are available for dragging to any area of the page. Unfortunately, Diem doesn’t know how to read thoughts, impose and create a design; therefore, we have to do this work ourselves, but here we also have some pleasant surprises. Because The article has already become inflated, I will just give an example for the block "hotel list":
<?php <br/> <br/> echo _open( 'div.product_list' );<br/> <br/> echo _open( 'ul.smartcolumns' );<br/> <br/> foreach ( $hotels as $hotel )<br/>{<br/> $url = _link( $hotel )->getHref();<br/> $data = 'infotext' ;<br/> <br/> ?> <br/> <li style= "cursor:pointer;" onclick= "window.location = '<?php echo $url ?>';" ><div class = "block hotel" ><br/> <a href= "<?php echo $url ?>" ><br/> <?php if ( $hotel ->getNbMedias()) echo _media( $hotel ->getFirstMedia())->width( 100 ) ?> <br/> </a><br/> <div class = "txt" ><br/> <a href= "<?php echo $url ?>" ><b class = "name" > <?php echo $hotel ->name ?> </b></a><br /><br/> <div class = "txt2" > <?php echo $hotel ->rating ?> </div><br/> <?php echo $data ?> <br /><br/> </div><br/> </div></li><br/> <?php <br/>}<br/> <br/> echo _close( 'ul' );<br/> <br/> echo _close( 'div' );<br/> <br/>use_javascript( '/js/smartcolumns.js' ); <br/>
And an example of an action for auto-filling a search form:
<? php
/ **
* 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' )
-> limit ( $ limit ) ;
$ 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 will point out what difficulties you may face while developing (the system is still raw and open source)
1. The Russian-language files are not renamed when loaded, while generating the url-of-course conversion to url-valid characters, but I had problems with the fact 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 using outdated functions instead of mb_string_functions. Although the French had to deal with UTF-8 strings ... In general, I didn’t dig in particular, being treated by converting the file name to url-valid characters, for example a-z0-9_-
2. Memory consumption with each access to the media gallery increases with the growth of files, which is not acceptable for large projects. For the database of hotels with 500 MB of images, the media library refused to open.
Going deeper into the code, I found a synchronization call every time the media library object was accessed, this is done so that the information about the structure of folders and storage files in the database is up to date (all of a sudden we will load a file over an FTP file).
Thing resource-intensive and not very necessary, because Files are supposed to be uploaded only through the admin interface, we comment on the synchronization call line and calm down.
3. Diem minifitsiruet and combines all CSS and JavaScript files to speed up the rendering of pages. And javascript is included at the end of the page, as we were
taught zadroty specialists from Yahoo. If you want to use javascript in templates and use, say, jQuery, then it is necessary that the jquery library be included in the page header. To do this, you need to specify which javascript files should be included in the header in config / dm / config.yml. You can also specify the use of Google CDN for downloading jquery libraries.
Results
1. Now you know what Diem CMS is, what advantages in development 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, and on virtual 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 the example of developing your own module and, I hope, made sure that with Diem you can do it with a full hand easily and quickly.
4. You have learned what difficulties may arise and how to overcome them.
Not everything that I wanted to tell fit into the article. Questions of SEO-optimization, user access control settings and a small modification of CSS eliminating some layout bugs remained unlit. I plan to fit these topics in the next article.
PS: whoever notices an error cannot be silent and writes in a personal - I will be grateful and immediately correct.