requireAsset and providesAsset for novice

This is a community-contributed tutorial. This tutorial is over a year old and may not apply to your version of Concrete CMS.
May 13, 2016

When you convert an html theme to Concrete CMS theme and/or add your own stuff to exist Concrete5 theme :) page_theme.php class methods: requireAsset and providesAsset could be your best freinds :) I think this issue its little confusing so i add "non developer" / "simple words" guide.

For deep/full understand of this issues you most read C5 official docs.

Preface:

CSS - How the site looks (colors, spaces, size etc.)

JS - Behavior (open modal or dropdown etc.)

Very simple and obvious idea before we start:

Like other popular CMSs, concrete is web content management ("lives in your broswer"). Concrete will use JS and CSS (For the admin panels, drop downs and so on) Your theme will also use JS and CSS. Some of these assets could cause conlict and problems so you must have some way to manage this in simple and elegant way.

In simple words

"Hey Theme I am the interface, please remember we live together and I need the right CSS and JS Assets to look and work fine :)".

"Stupid abstract example" - Lets learn the trick

Imagine you are buying new home and this home comes with build-in red Kitchen and the option to add Extra money for premium blue Kitchen :) Now you have 2 scenarios:

  • scenario1: I really love the red Kitchen.

  • scenario2: I dont like red, i want the Blue Kitchen.

If this scenario was in some computer program you should have option to "keep red + abort the blue option" or "replace to blue, abort red option" (otherwise you find in your home red and blue kitchen together)

So i create some function tell my home - i require this red kitchen :)

//scenario1:
$this->requireFurniture('kitchen', 'red');

Or I want to provide my own kitchen so dont use the red one.

//scenario2
$this->providesFurniture('kitchen', 'blue');

Now depending on the scenario I will choose to "require" red or "provide" blue :)

From this really stupid example to Concrete CMS

Assets in concrete refer to JavaScript or CSS files required to make something work.

Concrete comes with build-in Assets :) If you inspect the element when you are logged in you will find a call to external assets files like: query, boostrap, font-awesome. Of course Concrete needs those asset to work and look fine.

You find some of those assets here: /SiteName/concrete/js/* /SiteName/concrete/css/*

Also look at the full asset list: Asset-list

For the simplicity lets imagine the red kitchen is the core "build-in" jquery.js located her: /SiteName/concrete/js/jquery-ui.jsand the blue kitchen is your custom-jquery.js

When you are developing a theme again you have two scenarios:

  • scenario1: I really love the "build-in" jquery.js - i want do use this asset in my theme (Always - Not only when I am logged in and the system add this asset for the Admin Interface)
// scenario1: Require - "to demand" something.
 $this->requireAsset('javascript', 'jquery');

Now logout: In your html you will find a "magic" point to an external JavaScript file: <script type="text/javascript" src="/SiteName/concrete/js/jquery.js"></script>

  • scenario2: Oh no I don't want to use the "build-in" jquery.js - I really like my own custom-jquery.js file ("I want to ovveride the core file").
//scenario2 : provides - "to supply (something that is wanted or needed)" 
$this->providesAsset('javascript', 'jquery'); 

This step only tell the system "hey I don't want the "build-in" jquery.js. In other words now "you don't have any jquery.js file in your site".

Now the admin interface will not work well and the code will throw errors like this: Uncaught ReferenceError: jQuery is not defined(anonymous function) @ tooltip.js:1

How to FIX this error? Like we promise lets provide/supply this asset.

In this example I put custom-jquery.js in this location: siteName\application\themes\my_theme_name\assets\js

Now lets point to this external JavaScript file: Go to your theme and put this line of code: <script src="<?php echo $view->getThemePath()?>/assets/js/custom-jquery.js"></script>

Thats it :)

Font-awesome example

Concrete admin uses the icon font - font-awesome.css, when you are login this asset will load automatically.

Do this simpele test:

  • Step 1: Login

  • Step 2: Put this font-aswome markup in your theme template: <i class="fa fa-camera-retro fa-lg"></i>

  • Step 3: Refresh your page and "WOW" you will get nice camera icon.

How this is happening without any link in your theme to font-awesome? Remember in the Preface section we tell you the admin and theme live toghever. And also we learned that Concrete5 admin loads Font Awesome automatically.

Inspect your site and "ctr+f" (find) "font-awesome". You will find this line: <link href="/SiteName/concrete/css/font-awesome.css" rel="stylesheet" type="text/css" media="all">

  • Step 4: Thats nice. Go to this /SiteName/concrete/css/ folder. Here you will find "font-awesome.css" and other useful CSS assets (Look for JS assets here /SiteName/concrete/js/)

Lets Load Font Awesome Twice

In your theme you want to add (supply/provide) font-awesome so you add this line of code in your <head>

<link href="<?php echo $view->getThemePath()?>/assets/css/font-awesome.css" type="text/css" rel="stylesheet">

Whats happens? When you login you will see this asset loaded twice!! (inspect element and test this).

Look close at the different "href" addresses.

"Hey i am point to an external JavaScript file you put in the - theme level"

<link href="/mySiteName/application/themes/my_theme_name/assets/css/font-awesome.css"
type="text/css" rel="stylesheet">

"Hey i am point to an external JavaScript file from the - Concrete5 Admin interface level

<link href="/mySiteName/concrete/css/font-awesome.css" rel="stylesheet" type="text/css" media="all">

Summary: In this example we load font-awesome twice. Besides performance issue, loading Font-awesome twice is not "big-issue", but loading twice Jquery, bootstrap.js and other files could cause a lot of bugs

After you learn about: requireAsset and providesAsset its really easy to solve this problem. In this example we only need to tell the system we provide/supply this asset: $this->providesAsset('css', 'font-awesome');

Small boostrap issue:

Also remember to provide the corret code. In Bootstrap for example the framework is modular.

Boostrap docs: Plugins can be included individually (using Bootstrap's individual *.js files), or all at once (using bootstrap.js or the minified bootstrap.min.js).

So its really important to provide the correct CSS and JS that the C5 admin intereface needs (Asset list will be helpful here).

Also when you Require the core Bootstrap - remember to check if you have all the CSS and JS plugins thats you need in your theme level.

Appendix : page_theme.php example code:

<?php
namespace Application\Theme\ThemeName;

use Concrete\Core\Area\Layout\Preset\Provider\ThemeProviderInterface;

class PageTheme extends \Concrete\Core\Page\Theme\Theme
{   
    public function registerAssets()
    {   
        $this->providesAsset('css', 'font-awesome');
        $this->requireAsset('css', 'bootstrap/*');
    }
}

Summary:

Concrete page_theme class gives you a lot of control over asset loading. When you want to use the core assets - Require/Demand them, or when you want to override the core assets (provide/supply your own files).

Full developers guide docs:

Recent Tutorials
Customize locale icons
Oct 29, 2024
By myq.

How to customize locale (language region) flags

Concrete CMS Caching Guide
Oct 16, 2024

An overview of types of caching in Concrete and considerations when using them.

Redirect all requests to HTTPS
Oct 9, 2024
By myq.

How to follow best practices for a secure web

Upgrade Concrete versions 9.3.1 and 9.3.2
Sep 10, 2024
By myq.

How to get past a bug in versions 9.3.1 and 9.3.2 that prevents upgrading the Concrete core through the Dashboard

How to use Composer with Marketplace extensions
Aug 22, 2024

Composer can be used to manage third-party extensions from the marketplace

Controlling Google Tag Manager Tags Based on Concrete CMS Edit Toolbar Visibility
Aug 13, 2024

This document provides a step-by-step guide on how to control the firing of Google Tag Manager (GTM) tags based on the visibility of the Concrete CMS edit toolbar. It explains how to create a custom JavaScript variable in GTM to detect whether the edit toolbar is present on a page and how to set up a trigger that ensures GTM tags only fire when the toolbar is not visible. This setup is particularly useful for developers and marketers who want to ensure that tracking and analytics tags are not activated during content editing sessions, thereby preserving the accuracy of data collected.

Improvements?

Let us know by posting here.