Javascript Modularisation
Work in progress. Will be implemented in Rogo 7.1 (October/November 2019)
In order to modernise Rogo we are modularising our javascript and implementing requirejs.
What follows is a draft outline of javascript in rogo going forward (from version 7.1 onwards).
Directory Structure
<base_dir>/js/src/ | core source files |
<base_dir>/js/modules/ | contains core js modules |
<base_dir>/js/ | contains core initialisation scripts |
<functionality_dir>/js/src/ | functional area source files |
<functionality_dir>/js/ | contains modules and initialisation scripts for functional area |
<plugin_dir>/js/src/ | plugin source files |
<plugin_dir>/js/modules/ | contains modules for plugin |
<plugin_dir>/js/ | contains initialisation scripts for plugin |
Important Files
<base_dir>/js/modules/requireconfig.min.js | module used to access configurartion items |
<base_dir>/js/main.min.js | configures module loading and default js modules |
<base_dir>/js/rogo.min.js | initialisation script - sets configuration items etc |
<base_dir>/js/require.js | the requirejs library |
HTML File Structure
Each page in rogo will have the following js header where the rogo configuration is set, requirejs initiated and default modules loaded. Pages may have an additional js load to initiate page specifc modules.
... <script id="rogoconfig" src='../js/rogo.min.js' data-root="{{path}}" data-mathjax="{{data.mathjax}}" data-three="{{data.three}}"> </script> <script src='{{path}}/js/require.js'></script> <script src='{{path}}/js/main.min.js'></script> <script src='{{path}}/js/pagespecific.min.js'></script> ...
Loading config into js
Config is loaded into the js via the rogoconfig element on the page. rogo.js reads the attributes in as follows:
var mathjax = 0; var three = 0; var editor = 'plain'; // This is before jquery is loaded. if(document.getElementById("rogoconfig").getAttribute("data-mathjax")) { mathjax = 1; } if(document.getElementById("rogoconfig").getAttribute("data-three")) { three = 1; } if (document.getElementById("rogoconfig").getAttribute("data-editor")) { editor = document.getElementById("rogoconfig").getAttribute("data-editor"); } var root = document.getElementById("rogoconfig").getAttribute("data-root"); var require = { config: { 'requireconfig.min': { cfgrootpath: root, mathjax: mathjax, three: three, editor: editor } } };
JQuery
Jquery is modularised as following in main.js
requirejs.config({ // By default load any module IDs from js. baseUrl: '/js/modules', // paths to modules. paths: { jquery: "/js/jquery-1.11.1.min", jqueryvalidate: "/js/jquery.validate.min", jqueryui: "/js/jquery-ui-1.10.4.min", jquerytablesorter: "/js/jquery.tablesorter.min", ... ... }, shim: { ... ... // Non AMD libraries that need jquery. jqueryvalidate: ["jquery"], jqueryui: ["jquery"], jquerytablesorter: ["jquery"], }, });
The module is used via the SHIM method as such all extenstions are accessible via the $ variable. Note that if you require access to non jquery modules you should define these before 'jquery' i.e.
requirejs(['ui', 'jquery', 'jqueryvalidate', 'jqueryui'], function (Ui, $) { var ui = new Ui(); // Validate ldap options, and toggle extra settings. $("#installForm").validate(); $('#useLdap').change(function () { $('#ldapOptions').toggle(); }); $('#uselookupLdap').change(function () { $('#ldaplookupOptions').toggle(); }); $('#config').click(function() { ui.go_config(); }); });
Loading Translations into JS
PHP translation strings are json encoded on each php page as follows:
// JS utils dataset. $jsdataset['name'] = 'jsutils'; $jsdataset['attributes']['xls'] = json_encode($string); $render->render($jsdataset, array(), 'dataset.html');
The jsxls module can then access the strings using the lang_string method. i.e.
requirejs(['jsxls', 'jquery', 'jqueryvalidate'], function (Jsxls, $) { $('#forgotten_pw').validate({ messages: { email: Jsxls.lang_string['emailaddressinvalid'], } }); });
Coding Standards
- The first letter of variables included via RequireJS should be capitalised, and local variables should be lowercaseexample.js
requirejs(['ui', 'jquery'], function (Ui, $) { var ui = new Ui(); $('#config').click(function() { ui.go_config(); }); });