Howto: Drupal 8 and memcached on Lando

Update: Only a small part of this is related to Lando, it’s mostly about configuring Drupal with Memcached, but I would just note that since I wrote it in 2018, I no longer use Lando or (or anything involving Docker / containers). Instead, if you’re a macOS user, I’d recommend Laravel Valet – which is about as fast, simple and lightweight as you can get. It handles many frameworks / content management systems, takes care of your https:// support and domain names, and makes it easy to switch between PHP versions. You need to install MySQL or MariaDB (I use the latter) yourself, which is easy using Homebrew.


    1. Make sure phpinfo(); (available at /admin/reports/status/php in Drupal for administrators) contains a memcached section – by default Lando will install the memcached PECL package.
    2. Install and enable memcache Drupal module.
    3. configure settings.php:
      $settings['memcache']['servers'] = ['cache:11211' => 'default'];
      $settings['memcache']['bins'] = ['default' => 'default'];
      $settings['memcache']['key_prefix'] = 'mysitename_';
      
      $settings['cache']['default'] = 'cache.backend.memcache';

      Note the hostname for external connections (port 11222) is localhost, but internal connections have a different hostnamecache – to verify, run lando info

      (give it the correct sitename – this is especially important if you ever use memcached for two or more sites on the same server, to avoid conflicts.

      Also, note memcached has no security so if an application knows or can guess another applications’ prefix it can read all the data.

    4. Truncate all MySQL tables beginning with cache (Drupal bootstraps from the database by default and otherwise may continue to use them)
    5. Run drush cr
    6. You can should now work.

Verify connection and performance (e.g. hits/misses and memory used) at /admin/reports/memcache

Way to test an internal connection from PHP in a container, if you can’t install what you need:

php -a
> $socket = fsockopen('cache', "11211", $errno, $errstr);

If you don’t see any errors, it has connected.

Drupal – troubleshooting config synchronisation broken CSS when updating theme colours/appearance

Symptom: After deploying configuration changes to production, including a change to the theme (e.g. editing colours, colour scheme or logo on /admin/appearance/settings/bartik), you get a mostly white page because the colours are all missing. Yet when you visit that admin URL everything looks correct, and as soon as you click ‘Save Configuration’ the site is normal again.

What’s going on?

This happens if you’re using a standard Drupal .gitignore file, which typically has the following:

# Ignore paths that contain user-generated content.
sites/*/files
sites/*/private

If you export your configuration and look at color.theme.bartik.yml – you’ll find this at the bottom:

stylesheets:
  - 'public://color/bartik-7a1420bf/colors.css'
files:
  - 'public://color/bartik-7a1420bf/logo.svg'
  - 'public://color/bartik-7a1420bf/colors.css'

Every time the colours are updated a new stylesheet is created in /sites/default/files/color/bartik-[hash], but .gitignore is ignoring these files, so even if you perform a configuration sync correctly, production won’t have the CSS file it needs.

The solution is to add this to .gitignore:

sites/*/files/
!sites/*/files/color/
!sites/*/files/color/*

.gitignore syntax for inverting subdirectories is pretty confusing.  You might need to use git add –force If you see references to “double-globs”, that means **, and note it doesn’t work on all platforms (e.g. Mac).

Drupal – troubleshooting missing blocks

It’s possible to hide a block from the entire site by accident, because of some counter-intuitive behaviour in the block Visibility settings.

By default, when placing a block there are settings for Content Types, Pages and Roles.  Usually if you leave these blank (i.e. don’t select any checkboxes), the relevant tab has a summary label saying ‘No restrictions’ and they are ignored.

The Pages tab behaves a bit differently.  It has Show and Hide radio buttons and a textarea to input URLs.   If you leave the button set to show (the default) and the textarea is blank, the block is visible on all pages (barring any other restrictions such as the content type).

The danger is if you change it to Hide, and specify one or more pages to exclude.  If in future you decide to remove those so the list is empty again, you must set the radio button back to ‘Show’, otherwise it’ll be hidden from all pages, even though the tab will still say ‘No restrictions’.

Specifically the combination in this screenshot hides the block everywhere, as if it were disabled completed:

This block will be hidden, even though it says ‘Not restricted’

So if you can’t figure out why a block isn’t showing, manually click the Pages tab and check the full settings.  (This can be particularly confusing if you’re testing View blocks with complex contextual filters and they’re working in the Views UI preview, but not on the page.)

 

 

Drush Symfony error on Drupal 8.4.x

If you’re working on Drupal core or a development site and get this error when running Drush commands, e.g. drush cr or drush pm-list

PHP Fatal error:  Declaration of Drush\Command\DrushInputAdapter::hasParameterOption() must be compatible with Symfony\Component\Console\Input\InputInterface::hasParameterOption($values, $onlyParams = false) in /Applications/DevDesktop/tools/vendor/drush/drush/lib/Drush/Command/DrushInputAdapter.php on line 27

It’s because in the next Drupal minor release (8.4.x)  Symfony components have been updated to ~3.2 (in 8.3.x they remain at 2.8.x)

This causes a conflict with Drush – you should upgrade to Drush 9, which you can do via:

composer require drush/drush:9.*

One of several GitHub issues on drush-ops/drush

Drupal troubleshooting – upgrade warning when you already have latest version

Scenario: you’ve upgraded Drupal core to the latest version (via composer) but Drupal thinks an earlier/previous version is the most recent, despite running drush updb, clearing the cache, running cron etc.

e.g. you’ve upgraded Drupal core to 8.3.1, but still see a “version 8.3.0 available” warning on /admin/reports/status

Simple fix: go to /admin/reports/updates and click “Check Manually” and you’ll see a progress bar and it will pull in the latest list of packages and the warning will go away.

Git apply no output / no effect – troubleshooting Drupal patches

Be aware that for Drupal, when testing patches from the core issues queue, you can only use the git apply command on the main repository:

https://git.drupal.org/project/drupal.git (browse code)

(i.e. choose 8.2.x or 8.3.x according to issue )

and not on drupal-composer/drupal-project (e.g. a DrupalVM install)

This is logical, the commit IDs in the .patch file simply can’t be found in that repo, so git skips them.  Instead you should use:

patch -p1 < example.patch

…as described here. (You still use -R to reverse it.)

What’s less helpful is git apply will give you no warning there’s a problem – you’ll run the command, see [ok] but no other output, as though it had worked.

Likewise using any of these switches won’t print anything to the screen:

--verbose
--summary
--check

Annoying, the instructions for  --check imply it might tell you:

Instead of applying the patch, see if the patch is applicable to the current working tree and/or the index file and detects errors. Turns off “apply”.

(See also)

Suggested Checklist

  • create a new branch for the patch you’re testing
  • run git diff to check the files have actually been altered
  • run drush cr too to reset cache/UI etc. before testing

Troubleshooting Drupal\Core\Template\Loader\ThemeRegistryLoader – Unable to find template

(NB: this post refers to Drupal 8)

You may see an error like this if you’re developing a theme with caching disabled and twig.config.auto_reload on, and you’ve just removed a template from a subtheme:

Twig_Error_Loader: Template “themes/custom/test/templates/field–node–title.html.twig” is not defined (Drupal\Core\Template\Loader\ThemeRegistryLoader: Unable to find template “themes/custom/test/templates/field–node–title.html.twig” in the Drupal theme registry.)

To get rid of this you need to clear the theme-registry , until you do that it won’t correctly fall back to the equivalent file in your base theme.

Similarly, if you add if you add an extra template to a subtheme, Drupal will ignore it and continue to use the base theme until the theme-registry is cleared. (You won’t get an error, but you’ll wonder why your changes haven’t been reflected.)

To reset it:

drush cc theme-registry

or:

drush cr

The latter is less precise and takes longer to run, but is quicker to type the first time. Or you can use drush cc and pick the number the menu.

Note this happens (for me) regardless of whether twig.config.cache is true/false or whether the dynamic page cache is disabled.