In my Drupal development and consultancy work, I often advise development teams on how best to implement something in Drupal. I was asked recently how I—perhaps as the sole Drupal specialist in the room—validate the advice I give. I hadn’t really articulated that before, so I wrote down some thoughts.
With Drupal, there are often many ways to acheive the same end. If you’re only familiar with part of it, it’s natural to look there for a solution. But you might miss out on something easier.
So first of all I’ll strive to put possible options on the table that I think might work. That’s good for getting the nitty gritty of what a client really needs; when you propose options, some will make sense, others won’t. Ideally we’ll get to a point where one option just naturally stands out from the rest.
Let’s take an example: Drupal has templates for different content types. If you want a piece of content to appear differently depending on it’s context, you might be tempted to put some branching logic into the template. That’s ok, but Drupal content types also have view modes precisely for this scenario: a full page event, or the teaser of an article. Each content type/view mode combination has it’s own template, so you can skip the extra logic (plus the requisite twig syntax knowledge).
This kind of thing makes sense when you’re aware of it, but isn’t always obvious at first. By revealing it, the team is empowered to make that choice themselves.
Beyond that, I consider these principles:
1. Is this as simple as it can be?
2. Is this familiar?
Any code we produce needs to be maintained. Depending on one’s experience and knowledge of a platform, it can be advantageous to stick to what is already known, and what’s used in the rest of the project. Perhaps that means using a GUI-based layout manager over custom templates. Or an atomic CSS methodology like Tailwind over a global one like BEM. Or PHP over complex SQL queries. Sometimes it’s better to eschew the most technically superior methods (or the ones we think are superior!) for familiarity and consistency.
3. Is this replaceable?
This might sound like a strange one, after all we’re trying to produce code that brings long term value. Shouldn’t we be striving to build reusable code instead? Yes, but in my experience a piece of code becomes more reliable when its broken down into small discrete pieces, boundaries and dependencies clearly defined, and the implementation ring-fenced. It’s also more testable that way. If what we’ve built does need to change, that’s a lot easier and less costly to do, or swap out for something better without the burden of much technical debt.
That’s by no means an exhaustive list, but in general they can be summarised as trying to keep things as simple as possible.