Drupal.js: Best Practices for Managing Javascript in Drupal


Published on

Drupal has specific ways for working with Javascript, whether it's including files through drupal_add_js() or keeping your site structured with the Libraries. If you don't learn the correct techniques, you'll pay the consequences down the road.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • These things are pretty basic, but they are the things that will ruin your day, if you don’t know about themPlease, chime in, if you have any other thoughts.
  • Read this out loud.
  • Let’s start from the beginning. The right way to load javascript in a normal, static html file.This is a snippet from HTML5 BoilerplateTo some front-end developer just starting out with Drupal, they might consider loading javascript like this: (inline in a template file)
  • THAT IS WRONG.Javascript in your templates is like a timebomb. It will come back to get you.Why? Drupal doesn’t know it is there. - Bypasses aggregation - Bypassessminification - Stale versions can get stuck in caching
  • The .info file:Themes:The library loads on every page the theme loads.Modules:Once the module is enabled, the library loads on every page!drupal_add_js()It loads when the function is run.Requires you understand drupal’s hooks and preprocess methods, so you aren’t loading it at the wrong time.
  • Reasons:Unintended side effects – Like this console error I found one a project I was working on.Performance – You aren’t running any unnecessary Javascript, and you may save an HTTP request
  • The default settings for drupal_add_js are usually pretty good for performance.Type – ExternalJavascript can be served from a CDN (Default:file)Every Page – Tells Drupal that this is loading on every page. (Default: FALSE, unless in a .info file)Set this flag if you put it in hook_init, page_preprocess, etc. This allows Drupal to intelligently aggregate files (think, an “every page” bundle and a “some pages” bundle)3. Scope – serve it from the footer (Default: HEADER)4. Defer – serves it after the page is loaded (Default: FALSE)-----------------------------------------------------------------5. Cache – Caches this file. Defaults to TRUE6. Preprocess – Aggregates this file. Defaults to TRUE
  • Drupal has a sophisticated weighting system for javascript
  • First by scope, with 'header' first, 'footer' last, and any other scopes provided by a custom theme coming in between, as determined by the theme.Then by group.Then by the 'every_page' flag, with TRUE coming before FALSE.Then by weight.Then by the order in which the JavaScript was added.In D7Jquery is first because it is set in Header > JS_Library > Every Page > Weight = -20If You want something to load absolutely last: Footer > JS_THEME > FALSE > Weight = 20
  • Examples:Subscribe to our Newsletter modal on a per-page basis.
  • So, we’ve talked a lot about how to load our javascript file. But what’s actually inside it?You can put normal jQuery in there and it will, work.A lot of examples, however, use jQuery Behaviors.To be honest, I don’t fully understand it. You can sort of just copy-paste the template, put your stuff inside of it, and it just works. To describe it shortly:1. Drupal.behaviors is like the document.ready of Drupal. (tells it to load once the DOM has loaded)2. Behaviors code executes on every request… including AJAX requests.3. This structure allows scripts to apply to parts of the page that have been updated via AJAX. Like “Infinite Scroll”.4. Context will contain the newly loaded AJAX content, so you can treat AJAX content differently from normal content.5. Settings is for passing values from PHP to Javascript.
  • Step away from drupal_add_js() now, to cover a few more important things.Libraries is a moduleJquery Cookie in our codebase in several places.
  • jQuerynoConflict allows you to Namespace your javascript by the version of jquery you want to use.You don’t need to use jQuery Multi.
  • My Question for you: What lessons have you learned while working with Javascript in Drupal?
  • Drupal.js: Best Practices for Managing Javascript in Drupal

    1. 1. Drupal.js Best Practices for managing Javascript in Drupal By Bryan Braun
    2. 2. The Right Way! In the .info file scripts[] = js/example.js In PHP code: drupal_add_js('js/example.js') FYI, drupal_add_js() was removed in Drupal 8.
    3. 3. Only load it when you need it
    4. 4. Working With drupal_add_js() Performance Defer: TRUE Every Page: TRUE Scope: footer Type: external Cache: TRUE drupal_add_js('js/example.js' drupal_add_js('//cdnjs.clo drupal_add_js('js/example.js' ' drupal_add_js('js/example.js array('defer' => 'TRUE')); udflare.com/ajax/libs/d3/3 array('every_page' 'footer')); array('scope' => => 'TRUE')); .4.1/d3.min.js', <script src='example.js' Preprocess: TRUE 'external'); defer></script>
    5. 5. Working With drupal_add_js() Load Order scope group every_page weight drupal_add_js('js/example.js', array('group' => 'JS_LIBRARY’));
    6. 6. Passing data from PHP to JS In myModule.module drupal_add_js(array('myModule' => array('key' => 'value')), 'setting'); In example.js var myValue = Drupal.settings.myModule.key;
    7. 7. Drupal Behaviors Drupal 7 6 (function ($) { Drupal.behaviors.example function (context) { Drupal.behaviors.example = = { $('.example', context).click(function () { attach: function (context, settings) { //$('.example', context).click(function () { Do things here. }); // Do things here. } }); } }; })(jQuery);
    8. 8. Working With Libraries Before After
    9. 9. Working With jQuery The “newer version problem” jQuery Update jQuery Multi Drupal 6 -> jQuery 1.2.6 -> 1.3.2 Drupal 7 -> jQuery 1.4.4 -> 1.8.2 Drupal 8 -> jQuery 2.0? Uses jQuery noConflict* Updates Core -> 2.1.0+ -> 2.1.0+ Alongside Core*
    10. 10. Questions? @bryanebraun