Data has been entered into the system, stored in a database and occasionally changed as a result of processes based on time and event. Now the data has to be displayed or reported. The following sub-sections will describe, in detail, how the data is displayed on the administrative system and as a second part of each sub-section, how you may access the data on a front-end website, or possibly a smart device such as phone, tablet or some other internet connected device.

Cascading configurations

The majority of the display facilities described in the following sections conform to the following explanation of cascading configurations.

We have coined three words to describe the three levels in the cascade:

    1. Service
    2. Collection
    3. Model

Each level consists of three possible locations where the data of the configuration can be stored.

The first is a physical file which contains an array of information in TOML format. It will stored in a config/ directory , within the appropriate views directory; where admin/config/, /views/config/, /mobile/config/ and /install/config/ are all examples. These files all have the extension .cfg and the convention is that the name is related to their purpose such as datagrid.cfg. In the overall Cliqon scheme and design, these files are used for development purposes only. Their contents will be copied to the text field of the appropriate database record.

The second location, which is used for production purposes, is a record in the database - thus there are records in the dbcollection (and could be in the dbitem table as well) where the tabletype (c_type) is service, collection and model. Although there are several elements to the record, the key entries are the reference (c_reference) which will be in the form table_tabletype, and a text field (stored c_options) which holds the TOML formatted array of configuration values.

The third location which is generated automatically and needs no user intervention, is a cached version of either the configuration file or database record.

The Cliqon framework scripts will attempt to read these configurations in the following order:

    • First - cached version (fastest)
    • Second - if cached version does not exist, read configuration from database and create a cached version
    • Third - if both cached version and database version do not exist, then read configuration from the file, create a database record and also a cached version

Thus, you will observe that the process of moving from development file to cached version is entirely automatic.

Although most developers will prepare configuration files off-line, we do provide an on-line editor to edit development files from within the Cliqon system itself.

What we do not yet provide is a form based mechanism for editing the configuration files. It is a low priority to produce this as a Cliqon facility but if the demand arises, the programming of this facility will be re-prioritised.

We have explained above where the use of the expression "cascading configuration" is relevant, now we will explain the second.

Model configurations overwrite or cascade over Collection configurations and again over Service configurations. In PHP terminology, we utilise the function "array_replace_recursive" to achieve this result. The entire process is encapsulated in the call to Method stdModel in Class Model.

$model = $clq->resolve('Model');

$dgcfg = $model->stdModel('datagrid', $table, $tabletype);

Although a Model configuration, can and will, on occasions, overwrite values at the lowest level in the Service configuration, the general rule is to write configuration files with keys and value (or value arrays) that are unlikely to overwritten at a higher or later level. We give as an example, the configuration of the Pager in datagrid. Paging is an essential and integral part of all Cliqon datagrids, therefore the configuration for it is included in the Service record:


limit = 15

rightControls = false

sizes.0 = 10

sizes.1 = 15

sizes.2 = 20

The decision to include this configuration snippet at the base level is enhanced by the practical fact that Gijgo hides the pagination bar when there is no need to display it by reason of too few records.

In our experience the only time we have encountered a need to modify the base snippet was a need to display 10 records instead of 15 records as the default number of records per page. This was then included in the Model configuration.

In a similar way but dealing with other configuration requirements, the Collection records for dbcollection (eg dbcollection.cfg) contain all the default form fields for all the structured data fields in the table. As an example, dbitem.cfg has c_level set at 60:60:60, which is correct for tabletypes: news, event, gallery and library etc.

The final element in the cascade, is the Model configuration. It is in this configuration you would expect to find all the JSON and multi-language fields such as d_text, d_title, d_description and d_image etc.

The Method in Model is insensitive to the fact of whether a configuration file exists at a given level. Therefore it is acceptable that a new facility created by a developer, only exists at the "model" level. Purely by way of example, we could imagine a situation where the Developer has created a completely new table called "dbcharts" and the only configuration file that exists is dbcharts.chart.cfg.

$model = $clq->resolve('Model');

$cgcfg = $model->stdModel('chart', 'dbcharts', 'chart');

This would be entirely acceptable.


Just a quick note about the display of the Breadcrumb Navigation. At present it is for display purposes only and is part of the component template, such as "admdatacard.tpl". It could be further animated but this not a priority at present. There may be occasions when it might be useful to use its history capabilities, especially for paged forms that need to return to Datatable.

Top buttons

Buttons displayed on the right side of the Breadcrumb bar, are common to every component template in Cliqon Administration and thus are handled by a callable static method in Cliq.Php (Q::topButtons($dgcfg, $vars, 'datagrid')). The first argument is the generated Model array, the second argument is the $vars array that holds all the arguments passed to the Component by the AJAX call, especially $table and $tabletype. Finally the type of component is declared. The configuration will be created as a TOML array in the Service, Collection or Model record. The possible properties are:

    • key = action, such as add a record, display help etc.
    • class = the significant part of the Bootstrap button class that provides the colour (btn-warning). Because of the way the Class is used, you could add an additional value to this, if there was some reason.
    • icon =  the significant part of a Fontawesome icon (fa-plus), to add an icon to the left of the text of the button
    • title = Administrative string reference
    • formid = If the button invokes a form, the ID of the form, for example "dataform"
    • formtype = If the button invokes a form, which type of form will it be - column, popup or page? (columnform, popupform or pageform respectively)
    • order = an alphabetical character, which will dictate the order of the button in the display of buttons. This helps with the cascading of buttons
    • submenu = A button can be just a button invoking a dropdown menu. This is particularly relevant for a Reports or Utilities menu

The following code snippet is an example from the Collection record for Dbcollection.

       ; Top buttons


               class = 'danger'

               icon = 'plus'

               title = '100:Add'

               formid = 'columnform'

               formtype = 'columnform'

               order = 'a'


               class = 'primary'

               icon = 'flag-o'

               title = '287:Report'

               order = 'b'


               class = 'warning'

               icon = 'refresh'

               title = '122:Reset'

               order = 'c'


               class = 'info'

               icon = 'info'

               title = '85:Help'

               order = 'x'

Cell format

In the majority of the display handlers, the data for the handler is called after the layout or structure has been resolved by the template. When the data is being sourced from the database by the appropriate Class Method in Db.php, The content of the cell is formatted according to rules that are included in the Column array. As a general rule, this format is controlled by the key entitled type. However some transforms are controlled by field name and these are listed first iin the list below. If no cell format type is included, the format defaults to text.

Below is a master list of transforms. As these transforms are ubiquitous throughout the system, they are handled by the Cliq Class and static Method entitled formatCell() (or Q::formatCell($fieldname, $completerow, $properties, $tablename, $rowid));

    • Currency = formats a number into a currency string according to the system locale
    • Number = formats a number into a number string according to the system locale
    • Document = Uses a 3rd Party library called "Summarizer" to make a shortened version of a large block of text
    • Username = Converts a username such as "fredb" into Fred Burton (2) or Fred John Burton (3)
    • Fulladdress = Configuration will specify one of the document address fields such as d_addr1 but setting the type to fulladdress will populate the column d_addr1 with the complete address
    • Fullname = Configuration will specify one of the document name fields such as d_firstname but setting the type to fullname will populate the column d_firstname with the complete name
    • Yesno = used for boolean fields.  Displays a checked or unchecked Fontawesome checkbox.
    • List = Looks up a value in a list to get the language appropriate label. Needs the list name as an additional value in the configuration as list = ''
    • Date = formats a date into a date string according to the system locale
    • Avatar = This is a special Cell format which looks up a Gravatar at Gravatar.Com where the value stored in the cell is the significant portion of a valid gravatar
    • Image = Replaces a string with a directory and image file name stored in the database with a formatted image. The image accepts the additional options of the d_title for alt="" and title="", Class to add to Bootstrap relevant img-thumbnail and img-fluid. The image source can be displayed as an absolute URL (including http://sitename/subdirectory/image.extn) if the option entitled "subdir" is set. Other relevant options such as height, width and style are all honoured.
    • Logo = Similar to Image above but assumes the Subdirectory to be "public/images/", which is correct for Company logos.
    • Cstr = Converts a valid string reference into a language string
    • Nodata = returns nothing
    • Modifiedby = Similar to username, but assumes the field is "c_whomodified"
    • Tags = Turns a comma delimited set of values into a formatted set of tags
    • Idiomflag = Converts a 2 character language code into a Flag. Any flags that are likely to be used, must be located in "public/flags/"
    • Idiomtext = Attempts to convert a 2 character language code into a language name.
    • Slider = Displays a Div with a progress bar. In the configuration, options must include: style to control height (eg: height:20px), valuemax, valuemin and a class, such as primary to control the colour.
    • JSON = This formats a JSON string into a formatted and readable string. Cannot be used for large strings, otherwise the height of the cell would enormous
    • Email, File and Url = Converts a string into a clickable link
    • Maplocn = Creates a static map. Method assumes that the row contains the following values: d_maplocnx and d_maplocny, or it can cope with a single fieldname such as "map", so that values become "d_mapx" and "d_mapy".
    • Multitext and Combined = Defined in a Plugin
    • Titlesummary = Converts a d_title and a d_description into one cell.
    • Imageurl = Converts a d_image and a d_url into a clickable image. The creation of the image conforms to Image as above
    • TOML =  This formats a TOML string into a formatted and readable string. Cannot be used for large strings, otherwise the height of the cell would enormous
    • Text = No conversion is undertaken on the value, with the exception of wrapping a hyphen with two spaces so that slugified references will break onto multiple lines if necessary and in an elegant and practical manner.

Additional transforms can be requested from us, or added via GitHub or added as Plugins.

Multi-lingual labels and text

There are four ways that multi-lingual text can be code to appear in Cliqon - back and front end:

Firstly, there is the direct callable method. This relies on embedding a directly callable method into the component template. This is the easiest of all the four methods. The reason that we do not like it and wish to move away from it, is that it means that text is rendered as HTML and sent to the browser as HTML directly.

<!-- List -->

<a href="#" role="button" class="btn btn-link btn-sm pad5 m0 hint--top" aria-label="@(Q::cStr('111:Display records'))" v-on:click="listButton($event, card, key)">@(Q::cStr('101:List'))</a>

The second method involves the use of a $thisvars array key. The way we have coded the publishing of any template in Cliqon, is that it is sent $vars and $thisvars. $vars consists of the components of the originating URL including: action, table, tabletype, language and the REQUEST. $thisvars is an array of variables created by the Display method, such as Datatable or Dashboard, probably to be found in one of the Framework App Classes such as Admin, CMS or Website. In our example Datacard template snippet, we choose to create a "listlabel" key  -> ($thisvars['listlabel']). The value for this key can be transformed  to become "List" or "Lista" (Español) _> $thisvars['listlabel'] = Q::cStr('101:List'). $thisvars is published by the template, which contains now contains a reference $listlabel so the Template would now look like:

<a href="#" role="button" class="btn btn-link btn-sm pad5 m0 hint--top" aria-label="@(Q::cStr('111:Display records'))" v-on:click="listButton($event, card, key)">@($listlabel)</a>

The third method involves having the label text made available to Vue. This is the preferred and recommended way of providing label text to Vue functions and methods. A $jsvars array  key can be configured by the display Method (probably in Admin.Php), say "listlabel" -> ($jsvars['listlabel']). The value for this key can be transformed  to become "List" or "Lista" (Español) _> $jsvars['listlabel'] = Q::cStr('101:List'). $jsvars are not published by the template, they must be added to the JSON data that will be sent to the page as JSON by the pagescripts.

Thus just before the Return in a display model we include a block of PHP code that generates a string that would be suitable as Javascript, including the creation of global and local variables, commands and occasionally complete functions. Collectively we call this string or block, the "pagescripts". We have organised that via the overall Page rendering procedure, this string is "set" as belonging to global template variable "js".

$js = `

console.log('Dashboard JS Loaded');

Cliq.set('gmapsapi', '".$clq->get('gmapsapi')."');

Cliq.set('bingkey', '".$clq->get('bingkey')."');

// Insert Vue routines here

var options = {

idioms: ".object_encode($clq->get('idioms')).",

icons: ".object_encode($icncfg).",

panels: ".object_encode($panelcfg).",

labels: {

       'listlabel': '`.Q::cStr('101:List').`'





global $clq; $clq->set('js', $js);

Therefore with this knowledge and facility to hand, we can include static labels and text in the options that are included with the Javascript function call. The template snippet would then read:

<a href="#" role="button" class="btn btn-link btn-sm pad5 m0 hint--top" aria-label="@(Q::cStr('111:Display records'))" v-on:click="listButton($event, card, key)">{{labels.listlabel}}</a>

Finally, the old and established method of using the Javascript lstr array. The detailed explanation for the current use of the array is provided in the section on  Javascript Strings under Administration.

In a Vue repeater or form context, the labels object would move from the Display Method to the Javascript Class and Method as part of the Vue function. For completeness, here is an example of how that coding would appear;

cfg.dc = new Vue({

       el: '#datacard',

data: {



       labels: {

               'listlabel': lstr[14],

               'editlabel': lstr[27]





methods: {},

mounted: {}


Common and Fields

There are two sub-arrays in all Collection and Model records that need further explanation.


Most records have a Common section that provides general information that will be used in various places in the system. Shown below is one sample from a Model record.


lcd = 'en'

title = '38:Side Menu'

description = '39:Administration Side Menu'

displayusing = 'datatree'

formusing = 'columnform'

fieldsused = 'c_reference,c_type,c_category,c_level,c_order,c_parent,c_common,c_document,c_options,c_lastmodified,c_whomodified,c_revision,c_notes,d_title,d_text,d_page,d_type,d_table,d_tabletype,d_icon,d_css,d_submenu,d_description'

level = '60:80:90'

tabletype = 'admleftsidemenu'

As a TOML record is being parsed by the transform method (say C::cfgReadFile()), there is a facility which converts placeholders in curly brackets into real values. To do this, the value that is going to be replaced has to exist. As an example, we tend to create data URLs as an example, as follows: /admindesktop/{lcd}/getdata/dbcollection/string/. Providing the key / value has been created previously, the conversion will take place. This is not an essential activity but is included for sake of completeness.

Most of the entries are self explanatory by this time, apart from "fieldsused" which is an essential value for singleton Collection (eg dbuser) and Model records. The system could find out what columns exist in a table of the database and presume certain criteria about which fields to expect to parse on a POST request or a Getdata activity. Unfortunately this would not help with data that is held dynamically as JSON in the document field (c_document). It might be able to open the document field and discern the keys therein but it could not know that it is acceptable that keys that are not populated, do not need to be present. Therefore, there has to be a master record somewhere that details which structured fields (c_) and which unstructured fields (d_) will be need for a given singleton Collection or Model. This information is provided in fieldsused.


Every collection will include the definition of the standard structured fields in its Table. Most Models and singleton Collections will expand and overwrite the fields definitions. Shown below is an example a fields definitions sub-array from a Model:


       dbtype = 'string'

       required = 'true'

       title = '7:Content'

       defval.en = 'Text' = 'Texto'

       unique = 'false'


       dbtype = 'string'

       title = '6:Common'

       defval = 'common'

       required = 'true'

       unique = 'false'


       dbtype = 'toml'

       title = '43:Configuration'

       defval = 'value'

       required = 'true'

       unique = 'false'

The exact name of the field is the key. The definition array for the field will be used in several places in the system and may be expanded to meet other needs in the future.

    • dbtype = when the record is saved to the database at any time, this value is a database helper to dictate whether the value should be formatted according to certain rules. Virtually all Cliqon database content is held as a string, but the existence of this value makes other types possible.
    • required = when the record is saved to the database at any time, a valid value must be provided
    • title = a label string which will regularly by replaced by the placeholder and curly brackets activity described above.
    • unique = when the record is saved to the database at any time, a check to ensure that no other record contains the same value
    • defval.lcd = this is currently a rather clumsy but essential arrangement to provide a default value (including a default value for an individual language) for a record if no value has been provided when the record is initially created

Created with the Personal Edition of HelpNDoc: Free Kindle producer