Describing portal collections, documents and program code

Published on, September 17, 2018

In first two parts of this blog series I explained tools required to develop DRG CMS portal application, how to install them and how to create a working internal portal application skeleton. In this third part I will try to explain, how is everything connected together, which collections are required, what is defined in documents and program code behind­.


We ended our last session at http://localhost:3000 URL address. Now click on CMS link at top left corner. Main CMS menu will be displayed with two menu sections. CMS main tables and CMS advanced.


Expand CMS main tables menu and click on Sites. You should see two documents. Test and The only purpose of test document is to point to actual portal document which is If you open test document, you will see Alias for field, with value DRG CMS can handle multiple web sites on single Ruby on Rails instance. Test document defines, which site will be active during development or testing.


Now open document and browse through tabs. Explaining all fields is beyond this text, so I will explain just fields that are important for portal application and are filled in.
HomePage link: Defines document which will be displayed when root ( / ) of the application is called (in our example defines Home Page document with home link ).

Files directory: Default upload/download directory relative to web public directory (will be public/files)

Layout: Rails layout for render web page data. Value content defines this layout file.

Page table, Page class: Define which collection holds page documents. dc_page is for collection name and DcPage is for model class name. (One of them is redundant)

Menu class: Defines which model class is used for menu system of the site. In our case it is DcMenu. (It could also be DcSimpleMenu or custom menu defined by developer)

Menu id: Points to Menu document inside of collection defined by Menu class. This document will be used to draw site menu.

Settings: Options defined here can be used as site wide settings. They must be entered in YAML format. These options can be accessed anywhere inside application execution code as @options[‘key’].  Entered options are used for CkEditor HTML data entry element and can be accessed from program code as @options[‘ckeditor’][‘config_file’].

Access policy declarations: Access policies define which User roles (found under CMS advanced menu) are recognized by this portal and what access rights they have. Policies define three possible states. User has no access, user can see document and user can edit document. Renderers may check access policy defined in individual documents or web elements and hide them or allow user to edit them. If you look at default policy you will see that superadmin role has edit rights and guest role has no access. Policy has also defined default error message which can be obtained if user has no access to element. You can read more about policies here.

We will continue with documents found under Designs in CMS main menu. Designs are similar to landing pages found on other CMS-es and define HTML code and document data which together make a web page. As you will see in hereafter Pages section, every page must have design  defined.

HTML code can be defined in design or in file system, depending of flexibility you need. If HTML control code is defined in design document, changes in design are visible immediately. If defined in file system, you have to push code changes into production for design change.


Portal design is defined in file designs/portal(.erb) (source code). Result would be the same, if code found in the file, would be copied to Body field (leaving out top and bottom line) and Rails view filename would be left blank.


Our next stop are documents in Pages collection. Collection has four documents, each representing a link found in the menu.  First document has Subject value Home page and Subject link home. DRG CMS does not follow standard Rails practice where routes defined in routes.rb lead to controller code. Look at routes.rb file where you will find this last statement:

get '*path' => 'portal#page'


If the route is not defined, code in PortalController page method will be executed and execution will eventually find page document which Subject link is is equal to path parameter. This is much more flexible then routes, especially when multiple web sites are handled by single ROR instance.


Back to our page document. On advanced tab you will find Design field which points to previously described design document. Below is a field which defines Menu corresponding to this document and after that which Site does document belong to and which Access policy will be enforced, when rendering document. If Access policy field is left blank, “Default policy” will be used. For portal application there is only one important field left. Parameters field. Values in this field must be entered in YAML format and data entered in this field is added or overwrites data defined in Site settings field.

If you leave Home page document and open Login document, you will see that Parameters field has value:

render: "dc_render(:dc_poll, poll_id: 'login', div: 'login')"


Lets go back to our design source file portal.erb and look at this code:


<div id="page">
  <% if @options['render'] %>
    <%= dc_render_design_part @options['render'] %>   
  <% else %>
    <%= dc_render( @options['renderer'] || @page.subject_link ) %>
  <% end %>


Default design is flexible about its output. It can use parts which are defined in other parts of program or external gems (using poll document as login form, as defined in login document) or when renderer parameter is set, use particular renderer object or when left blank, use renderer defined by Subject link field. In our case HomeRenderer, DiaryRenderer and BlankRenderer found here.

DiaryRenderer and BlankRenderer default method defines application menu, while HomeRenderer uses Dashboard object for displaying statuses or reminders from all parts of application. If you want to add additional dashboard elements, do this by extending Dashboard class and add your own methods to it.

This is the end of part three. In the next part we will see how to extend DcUser object, add additional fields and controls and extend form which is used for user editing.