Dec 24, 2014

Beta 3 --> Beta 4: Use libraries, not individual stylesheets or javascript files

I installed Drupal 8 beta 4 with hopes that I would not have to make any code changes other than bumping up the version number. Alas, it was not to be.

As soon as I tried to go to the module's configuration page, I got the unhelpful error message, 

  The website has encountered an error. Please try again later.

Going to admin/reports/dblog showed the log message:
  
LogicException: You are not allowed to use css in #attached in drupal_process_attached() (line 1759 of /var/www/html/opti/core/includes/common.inc).

Searching for "css" through the change records for Drupal core revealed that css and javascript files are now organized and declared within libraries that are defined in the .libraries.yml file.

For example, in the D7 version there are lines of code such as the following when building a form,

  $form['#attached']['css'] = array(
    drupal_get_path('module', 'optimizely') . 

      '/css/optimizely.theme.css',
  );
  $form['#attached']['js'] = array(
    drupal_get_path('module', 'optimizely') . 
      '/js/optimizely.admin.js',
  );
 

In D8, we have instead yet another YAML file optimizely.libraries.yml whose contents are,

  optimizely.forms:
    version: VERSION
    css:
      theme:
        css/optimizely.theme.css: {}

  optimizely.enable:
    version: VERSION
    js:
      js/optimizely.admin.js: {}
    dependencies:
      - core/jquery
      - core/drupalSettings


In this example, two libraries optimizely.forms and optimizely.enable are defined. Both css and javascript can be part of the same library, but I separated them for finer granularity.

The relative paths to the files are relative to the root of the defining module.

For the css property, the theme sub-property or some other sub-property is required for a valid definition. Otherwise, the attempted inclusion of the css will silently fail. See the article CSS file organization (for Drupal 8).

The dependencies property is critical. After a couple of hours of debugging, I realized that the JavaScript was failing because jQuery is no longer automatically included in every page, so it must be explicitly specified. The other dependency is a variable that is referenced that is part of drupalSettings.

VERSION seems to be a filler value that means no particular version.

To use these libraries,  the equivalent form building code then has the lines,

  $form['#attached']['library'][] = 
    'optimizely/optimizely.forms';

  $form['#attached']['library'][] = 
    'optimizely/optimizely.enable';
 


Sources:

Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module
https://www.drupal.org/node/2274843

hook_library_info() is replaced by *.libraries.yml file
https://www.drupal.org/node/2201089

CSS file organization (for Drupal 8)
https://www.drupal.org/node/1887922

Change records for Drupal core
https://www.drupal.org/list-changes

No comments:

Post a Comment