From RNWiki
Revision as of 04:45, 10 February 2010 by Kguske (talk | contribs) (Assumptions)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Problem

Add-ons that require CSS and / or JS to be loaded require manual changes to header.php, includes/javascript.php and / or includes/custom_head.php. As the use of CSS and JavaScript becomes more prevalent, the need for standard methods for using these tools without requiring modifications by the site administrator increases. Furthermore, manual changes make upgrades more difficult.

Although the use of externally-defined CSS and JS is common, there are also many uses for dynamically-generated CSS and JS. An example of this is a custom user attribute required for registration with validation requirements.

The increased use of JavaScript libraries like jQuery increases the possibility of multiple attempts to load the same JS. For example, a site-level add-on (i.e. something that needs to be loaded on every page) requires a tool tip function, and a module requires the same function. Preventing multiple loads of the same CSS or JS is required, as well as the ability to load CSS and JS at multiple levels (site, module). Some add-ons should not be loaded on every page as they may impact performance or conflict with other add-ons.

Opportunity

The opportunity here is three-fold: 1) to define a standard way to enable easy loading of CSS and JS with minimal (or no) manual changes by the site admin at multiple levels in both the HEAD and BODY sections, 2) to eliminate duplicate loads, and 3) to simplify the installation of add-ons with optimal performance. With externally defined CSS and JS, loaded in a standard way, we could minify and combine the files for improved performance. Some dynamically defined CSS / JS (e.g. the copyright JS) cannot be externalized, but could still be loaded in standard way (possibly for minification). However, the approach must consider the possibility that old themes, modules and other add-ons will not support the RavenNuke™ standard.

To enable RavenNuke™ to address this opportunity, the following requirements were identified:

  • Use functions that prevent duplicates to load arrays that define all CSS and JS (both externally-defined and in-line, dynamically defined), then load it from the arrays prior to the closing HEAD and BODY tags.
  • Use included PHP files, in a standard location (includes/addons), that contain the logic to determine which CSS and / or JS to load and when for site-level add-ons.
  • Modules can define a standard variable in the module’s index file to define the location of an included PHP file which serves the same purpose for module-level add-ons without requiring RavenNuke™ to check for file existence and without requiring old modules to be modified extensively to support the RN standard.

Approach

The approach used in RavenNuke™ 2.4 is:

  1. Where possible, externalize and individually minify all CSS and JS.
  2. Modify mainfile.php to include 4 new functions: addCSSToHead, addJSToHead, addJSToBody, and writeHead. The functions use an array each and check the array before adding to prevent loading duplicate externally-defined files.
  3. Modify header.php and includes/javascript.php to:
    1. Load site-level externally-defined and inline dynamic CSS and JS to respective arrays via the addXxxToHead functions.
    2. Check for existence of files in includes/addons/head-xxx.php, and including them in alphanumeric order. These site-level add-ons would load the CSS and JS arrays in the appropriate order using the addXxxToHead functions.
    3. Use the definition RN_MODULE_HEAD, defined in a module's index.php, to load module-specific CSS and JS using the addXxxToHead functions.

Solution

Prior to RavenNuke™ 2.4.0, the header.php used this process:

  1. Include theme
  2. Include javascript.php
  3. Link theme’s favicon.ico, if it exists
  4. Link themes/ravennuke.css
  5. Link themes/xxx/style/style.css
  6. Link themes/xxx/style/ . RN_MODULE_CSS, if it exists
  7. Include jquery, tabcontent, ajaxtabs, nukePIEhdr, nukeFEEDhdr (CSS and JS)
  8. Include includes/custom_files/custom_head.php, if it exists
  9. Include includes/custom_files/custom_header.php, if it exists (outside the HEAD tags and before body – this will always break compliance)

RavenNuke™ 2.4 uses this approach:

  1. Include theme - (let theme define links for favicon and its style)
  2. Link theme’s defined favicon; if not defined, check if it exists and link to accommodate old themes
  3. Add themes/ravennuke.css to CSS array
  4. Add theme’s defined CSS to array; if not defined, check if it exists and add to array to accommodate old themes
  5. Include javascript.php (to allow site administrators to follow an add-on instructions to load JS here)
  6. Include jquery, tabcontent, ajaxtabs, nukePIEhdr, nukeFEEDhdr (add CSS and JS to arrays)
  7. Include includes/addons/head-xxx.php and includes/addons/body-xxx.php, if they exist (site-level add-ons)
  8. If defined, include module’s RN_MODULE_HEAD (add module-level CSS and JS to arrays)
  9. Include includes/custom_files/custom_head.php, if it exists (to accommodate add-ons that don’t conform to the RN standard)
  10. Include includes/custom_files/custom_header.php, if it exists (outside the HEAD tags and before body – this will always break compliance)

Assumptions

  • Themes should define the favicon and style locations to avoid checking existence for them.
  • CSS and JS that must be loaded in the BODY section before being used (i.e. not just before the closing BODY tag) must be loaded by the add-on.
  • Add-ons must not attempt to load JS in the BODY section that belongs in the HEAD section (e.g. a BODY section jQuery plug-in must not load jQuery in the BODY section).
  • An add-on should load ALL required javascript (e.g. jQuery.js) and CSS using addJSToHead, addJSToBody, and addCSSToHead functions, even if the javascript or CSS may be loaded by another add-on. These functions will prevent the JS or CSS from being loaded multiple times, and using this approach ensures that JS and CSS are loaded in the proper order.

Future enhancements

  • To balance manual changes vs. performance, we could add a config option in the site preference table or in rnconfig.php for the webmaster to turn off checking for includes/head files if there aren’t any site-level add-ons. Since this could increase support requirements, it wasn’t included in RN 2.4
  • Phase 2 (post 2.4) will assess and, if possible, implement on-demand minification and /or CSS and JS consolidation, compression, and / or caching. The assessment will determine whether or not we should manually consolidate all CSS and JS into a minimal number of externally defined files to use instead of dynamic minifying and loading.