Design template concept

DRG CMS has 3 main collections which are used to display web site data. These collections are:

 

dc_site: Since DRG CMS can handle multiple sites on single Rails instance, dc_site documents define parameters for each site. Site name, home page, menu, page model, policies, common  parts, site level settings ....

dc_page: Dc_page (usually) caries main data which will be rendered as result of visit. It holds HTML elements, picture elements, page title, dates. But most importantly it must define design, which will be used to render data.

dc_design: Defines Ruby on Rails view template which is used to paint (render) data in browser.

 

Here is an example of design used to render this site home page before it was changed to mobile friendly design. It is contained in body field of dc_design document.

 

<div id="site">
  <div id="site-top-bg">
    <div id="site-top"><%= dc_render(:dc_piece, name: 'site-top') %>
      <div id="login"><%= dc_render(:common, method: 'login') %></div>
    </div>
    <div id="site-menu"><%= dc_render(:dc_simple_menu, method: 'as_table') %></div>
  </div>


  <div id="site-main">
    <div id="site-left">
     <div id="page"><%= dc_render(:dc_page) %></div>
    </div>
    <div id="site-right">
      <div id="ad-right"><%= dc_render(:dc_ad, position: 'ad-right') %></div>
    </div>
    <div style="clear: both;"></div>
  </div>
</div>

<div id="site-bottom">
    <%= dc_render(:dc_piece, name: 'site-bottom') %>
</div>

 

As you can see the template follows standard web design. It has site-top div with menu, site-main div, divided into left part with page data and right part with ads and site-bottom containing page footer. Then there are various calls to dc_render helper which produces code that is inserted into template. How does it all work?

 

dc_render is a Rails helper which can be found in dc_application_helper.rb file. It will take first parameter (ex. :dc_piece) and instatinate DcPieceRenderer class which must be (by convention) declared in dc_piece_renderer.rb source file. Source file can be located either in controller or in helper directory, Rails will find it automagically. (Since renderes are more like helpers then controllers I prefer to save them to helpers directory). Render class must contains at least four methods. initialize, render_html, render_css and the method which will produce html code. Additional parameters can be send as hash to dc_render method. Most important of them is method: parameter, which defines method which will produce html code. If method: parameter is not specified, method with name 'default' will be called.

 

Lets sum it all again. dc_render(:dc_simple_menu, method: 'as_table') will instatinate DcSimpleMenuRenderer class and use 'as_table' method to render html code. dc_render(:dc_ad, position: 'ad-right') will instatinate DcAdRenderer class use 'default' method and pass position: 'ad-right' parameter to it. <%= dc_render(:dc_page) %> will instatinate DcPageRenderer class and call its 'default' method.

 

And if you look at dc_page_renderer.rb (the simplest of them) you will see this:

def default
  html = ''
  html << dc_page_edit_menu() if @opts[:edit_mode] > 1
  html << @page.body
end

 

Third line will create edit option (when in edit mode) and fourth line will just add body part of page document to html code. This really is the simplest way to put some html code on the output and it is the way www.drgcms.com home page is rendered. For the rest of the code look into dc_page_renderer.rb file.

 

View can also be defined in standard rails view file. Just fill rails_view field with name of view filename (eg. designs/myview) and put myview.html.erb into views/designs folder. But you have to insert two lines of code into each file.

 

Put this line at the top of file:

 

<%= dc_page_top %>

 

and this line at the bottom of file:

 

<%= dc_page_bottom %>

 

Top line will add CMS menu when in ''edit'' mode and the bottom line will add css and javascript code generated by renderers to generated page source.

 

After designing few sites I realized that most of design code is the same except the main part which differs depending on data displayed. Suddenly changing small part of design resulted in updating a lot of design documents. So It was decided that design template can also be defined in site document which has got two fields. Design and rails_view. Design document now defines only code that differs from other designs and main template code is saved in site document. Design code mostly looks like this now:
 

<% main = %(<div id="docs">\<\%= dc_render(:dc_book) \%\></div>) %>

<%= dc_replace_in_design(replace: '[main]', with: main) %> 


There is main part which in this case is used to render book data. dc_replace_in_design helper method will use template from site document and simply replace occurrence of [main] with what is defined by main variable.

 

Remark: There is probably better and more Ruby way of doing this. For now I am satisfied with this solution.


Last update: 25.01.2022