This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

Some jQuery plugins are packaged with and used by multiple Concrete5 add-on packages, sometimes minimised, sometimes not, sometimes under a different filename or aggregated with other jQuery plugins into a single communal file.

When jQuery plugins are loaded from the Concrete5 core, addHeaderItem and addFooterItem will filter out duplicate requests. Similarly, when the same file is requested multiple times from the same add-on or theme package, addHeaderItem and addFooterItem will filter out duplicate requests.

However, when the same jQuery plugin is loaded from different files at 2 or more different paths, it can end up being loaded multiple times, causing a JavaScript error from the duplicate declaration in the jQuery namespace and JavaScript halting execution so all scripts on the page or even site cease to work. A good example is the fancybox plugin which is used by many add-on packages to pop up dialogs and image galleries.

A github pull request provides an extension to the Concrete5 addHeaderItem and addFooterItem to help solve this and has now been included in the core. However this can only be depended on if all add-ons loading their own copy of a jQuery plugin conform to the extended interface.

A complementary method that add-on developers can incorporate unilaterally into their own add-on packages is to wrap a jQuery extension declaration within the jQuery plugin file. The following code tests to see if the jQuery plugin 'the_plugin_name' is declared, and only continues to declare 'the_plugin_name' if it does not already exist. if it does already exist, a message is reported to the developer console, but by not declaring it again, at least this script will not break anything.

(function($){
  // make sure jq plugin 'the_plugin_name' is not already defined
  if(typeof $.fn.the_plugin_name === 'undefined'){
    // The plugin is not already defined.
    /*
    The original plugin code to extend jQuery with 'the_plugin_name' is 
    inserted in place of this comment. eg.
    */
    $.fn.the_plugin_name = function (){
      // plugin details
    };
  }else{
    window.console && window.console.log && 
    window.console.log('Plugin the_plugin_name conflict avoided in package this_packags_name/this_file_name');
  }
})(jQuery);

This 'guarded declaration' technique does not need to test every declaration within the plugin, any single addition to the jQuery namespace is enough for the test. It doesn't prevent duplicate downloads, but it can be done unilaterally, can be done anywhere a jQuery plugin is defined, and it can in many cases stop a duplicated script file from breaking a site.

The disadvantage is that it requires modification of the jQuery plugin’s source file, so this solution is best only used by developers where a particular jQuery plugin is known to give problems because of its widespread incorporation in many add-on packages.

Also, this will not work if the guarded declaration is made before an unguarded declaration of the same jQuery plugin. To work reliably, it must either be applied to all various declarations of the same jQuery plugin, or be applied only after other possible declarations of the same jQuery plugin have been made.

Overall, it adds some protection, but will not guarantee to always prevent jQuery plugin collisions unless applied universally.

Read more How-tos by JohntheFish

Loading Conversation