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

Many concrete5 addon and theme packages use php libraries, JavaScript, CSS and fonts provided by third parties. It could be a CSS framework, a jQuery plugin, the Facebook API, a non-standard font or whatever. Code or other assets that weren't written by the package developer or are extended from the concrete5 core are third party assets.


The most important thing about any third party asset is that it will have a license. As a developer of a package, you need to adhere to the conditions of that license. A condition of nearly all licenses is that the license text or accreditation must accompany the asset, so ensuring users of your package are also aware of any license conditions.

  • Some licenses such as MIT allow you to do what you want with the asset, so you can sell products that use it.
  • Some licenses such as GPL allow you to distribute an asset, but not to charge for it or anything distributed with it. GPL also requires anything using it to also be GPL licensed.

Some commercially supported assets will be free to non-commercial use, but require a paid license for commercial use and an OEM license if you want to distribute it onwards with your product (addon or theme). Just because you are giving away an addon or theme for free does not absolve you of any OEM license requirements.

Before upgrading an asset in your package, beware that licenses may change between versions of an asset. For example, fancybox 1.x is MIT licensed. But fancybox 2.x has a commercial license.

Before submitting an addon or theme to the concrete5 marketplace, please check all asset licenses and make sure the conditions of the license are met by your package. But don't leave it that late. Check the licenses before committing to writing code.

Extending existing addons or themes

If you are providing an alternate block view template for an existing marketplace item and use any code from the existing view template, then you must also get permission from the original marketplace developer. It doesn't matter if their addon was free or paid for. You will need their permission.

Where to put the code

For php libraries, the best place to put them is in a /3rdparty/ directory under the package /libraries/ directory. That makes it nice and obvious that there is third party code in the package, so making the reviewer's job easier and making it easy for end user to update the library should they want to.

The library can then be loaded with Loader::library().

For example,


Loader::library('3rdparty/libraryname/libraryfile', 'my_package');

For jQuery or other JavaScript plugins, place them in a /js/ directory under the package. Depending on the script, you may leave any CSS and images it bundles with it, or you may decide to move CSS and images to their own /CSS/ and/or /images/ directories beneath the package. Many such scripts will have their own naming and organisational conventions, so its best not to mess and do what makes sense for easy update rather than redesigning the way they reference their own assets.

The assets can then be loaded with the html helper and addHeaderItem() or addFooterItem(), typically in a package controller on_befor_render() or in a block controller on_page_view() event handler.

For example:


$this->addHeaderItem($html->css('pluginname/pluginfile.css', 'my_package', array ('handle' => 'pluginname', 'version' => 'x.y.x') ));
$this->addFooterItem($html->javascript('pluginname/pluginfile.js', 'my_package', array ('handle' => 'pluginname', 'version' => 'x.y.x') ));

The array parameter at the end is used by concrete5 to help prevent collisions. Particularly with jQuery JavaScript plugins, if two packages on the same page load the same plugin from different places (ie different packages), you will end up with a JavaScript error and likely a blank edit bar. By providing plugin name and version information, concrete5 can prevent some (but by no means all) such collisions.

Where a common plugin is a frequent source of collisions, it may also be useful to wrap its code to prevent double declarations.

Read more How-Tos by JohntheFish.

Loading Conversation