Customise scaffold files the right way
There are some key files like robots.txt
and .htaccess
which are often tweaked for Drupal websites. These can be considered part of the 'scaffolding' of a site - they control the way the site works, rather than its content or design. Any new release of Drupal core that includes changes to them specifically mentions that they need updating, as those changes may have to be merged with any customisations made on your site. For example, there was a security release that added rules to .htaccess
, which were essential for any site to incorporate and the template settings file, default.settings.php
, also gets regular updates which are easy to miss out on. The new Drupal Scaffold composer plugin can now ensure that these files are always up-to-date by default. But that can mean it's now too easy to lose customisations, as those files are taken out of our direct control. (They now behave like files from external dependencies, which are usually excluded from version control.)
It's not a good idea to 'hack' (i.e. make changes to) core files. Drupal developers even dissuade each other from doing this by joking about bad things happening to kittens! But while these scaffolding files may come from core, they all live outside of Drupal 8's /core
directory. (A full list of these files is near the bottom of this article.) This leaves them vulnerable to the forgetful developer coming along and tweaking them without thinking. To be fair, it's quite right to expect to be able to tailor them for SEO, specific business requirements, performance gains, debugging needs or whatever.
So the Scaffold composer plugin provides some ways to customise these files in a 'nice' way, all of which require some little edits to your project's root composer.json
file.
-
Simply append or prepend some lines
Create a file containing the lines that you want to add, and reference it within the 'extra' section:
"extra": { "drupal-scaffold": { "file-mapping": { "[web-root]/robots.txt": { "append": "assets/my-robots-additions.txt" } }, ... } }
Replace 'append' with 'prepend' as the key if needed. This is great for
robots.txt
, which usually just wants some additions beyond what Drupal normally provides. I've used it fordefault.settings.php
to suggest some useful project-specific config overrides for developers. -
Override a file entirely
Create the file you want to use instead of core's version, and reference it within the 'extra' section:
"extra": { "drupal-scaffold": { "file-mapping": { "[web-root]/robots.txt": "assets/robots-override.txt" }, ... } }
This loses out on any improvements that Drupal may add over time, but is handy if you want to take back control of the file entirely. For example, some SEO agencies like to determine the contents of
robots.txt
entirely (although the RobotsTxt module may be more useful for that). -
Patch a file
Create a patch of changes that you want to make, and use the
post-drupal-scaffold-cmd
script event hook:"scripts": { "post-drupal-scaffold-cmd": [ "cd docroot && git apply -v ../patches/my-htaccess-tweaks.patch" ] }
This is really useful if you have specific changes to merge into a specific place of a scaffolded file, like in
.htaccess
. This ensures you get the benefit of updates made by core to the file.Pro tip: run
composer install; git diff -R .htaccess > patches/my-htaccess-tweaks.patch
to produce the patch if.htaccess
is still under version control!
Once these are in place, you can then ensure to remove and exclude all the scaffolded files from version control, if you haven't already. Here's example commands you could run to remove them. Make sure to replace 'docroot' with your webroot subdirectory.
# Commands to remove scaffolded filesgit rm .editorconfig .gitattributes --ignore-unmatch;cd docroot;git rm .csslintrc .eslintignore .eslintrc.json .ht.router.php .htaccess index.php robots.txt update.php web.config modules/README.txt profiles/README.txt themes/README.txt example.gitignore INSTALL.txt README.txt sites/README.txt sites/development.services.yml sites/example.settings.local.php sites/example.sites.php sites/default/default.services.yml sites/default/default.settings.php --ignore-unmatch
...and a snippet you could paste into your project's .gitignore
file. (Again, replace 'docroot' if necessary.) This should then be committed for this to all work out.
# Lines to add to your project's .gitignore file.# Files from the Drupal scaffold for composer./.editorconfig/.gitattributesdocroot/.csslintrcdocroot/.eslintignoredocroot/.eslintrc.jsondocroot/.ht.router.phpdocroot/.htaccessdocroot/example.gitignoredocroot/index.phpdocroot/INSTALL.txtdocroot/README.txtdocroot/robots.txtdocroot/update.phpdocroot/web.configdocroot/sites/README.txtdocroot/sites/development.services.ymldocroot/sites/example.settings.local.phpdocroot/sites/example.sites.phpdocroot/sites/default/default.services.ymldocroot/sites/default/default.settings.phpdocroot/modules/README.txtdocroot/profiles/README.txtdocroot/themes/README.txt
A current list of the files can be found in core's composer.json file.
Good luck - you can now rest assured that the Drupal kittens will rest in peace 😅