Drupal

How to install a Drupal.org sandbox module using Composer

What do you do if you want to use a Drupal.org sandbox project with Composer? You can’t just add it in your "require" section, as it won’t be available as a package name. Turns out you just have to define the repository in your composer.json like so:

Code language: JavaScript

"repositories": {
  "drupal/image_field_caption": {
    "type": "package",
    "package": {
      "name": "drupal/image_field_caption",
      "type": "drupal-module",
      "version": "1.x-dev",
      "source": {
        "url": "https://git.drupalcode.org/sandbox/spoit-2806183.git",
        "type": "git",
        "reference": "8.x-1.x"
      }
    }
  }
},
"require": {
  // ...
  "drupal/image_field_caption": "1.x-dev",
  // ...
},
// ...

Drupal 8, behaviors, and jQuery Once

When porting some front-end code from Drupal 7 to Drupal 8, I ran into an unexpected change in the use of jQuery.once(). In Drupal 7, you’d do this in a behavior:

Code language: JavaScript

Drupal.behaviors.exampleBehavior = {
  attach: function(context, settings) {
    $('.example', context).once('example-behavior', function() {
      // Do stuff.
    });
  },
  detach: function(context, settings, trigger) {
    $('.example', context).removeOnce('example-behavior', function() {
      // Undo stuff.
    });
  }
};

In Drupal 8, however, you can’t pass in a function to jQuery.once(), as the API for that jQuery plugin has changed. It now acts like jQuery.filter(), in that it filters out any elements that have already been processed so they aren’t processed more than once, and returns a jQuery collection. So, in Drupal 8, the example would be:

Code language: JavaScript

Drupal.behaviors.exampleBehavior = {
  attach: function(context, settings) {
    $('.example', context).once('example-behavior').each(function() {
      // Do stuff.
    });
  },
  detach: function(context, settings, trigger) {
    $('.example', context).removeOnce('example-behavior').each(function() {
      // Undo stuff.
    });
  }
};

Drupal 8 contextual links are locally cached in sessionStorage

I ran into a seriously confusing issue with a project that I’m learning the internals of Drupal 8 for: custom contextual links were not reliably appearing or even disappearing after removing them from code, and the only thing that seemed to work was to fully uninstall and reinstall the custom module, which was far from ideal. Turns out that Drupal caches contextual link markup in sessionStorage, which is why clearing Drupal’s own cache had no effect like you would expect. The easiest way of handling this is running window.sessionStorage.clear(); in your browser’s developer console. Alternate solutions include opening the page in a new tab will cause a re-download of the contextual links (due to how sessionStorage works), or opening up your browser’s developer tools and deleting the sessionStorage entries for the entities or other identifiers - for a block it would be Drupal.contextual.block.*, while for a node it would be Drupal.contextual.node.*.