Published Jul 29. 2023 - 9 months ago
Updated or edited Nov 22. 2023

The threat of Drupal 8… eh… 9... eh… 10!

GFF is running on Drupal 7, and Drupal 7 is terminal. It’s destined to die. And upgrading is not an easy task, not least because version 10 is already there.

Nerd alert

This is NOT about fly fishing or fly tying, but about site development and nerdy stuff.
Versions
Versions
Martin Joergensen

Content Management Systems like Drupal go through incremental improvements, and ever so often change versions. Drupal has been through a handful of major changes, and while I have been working with it, it has changed from version 4 to 9 and 10.
Most of these changes have been incremental improvements within the system, using basically the same structures, principles and programming paradigms. Version 7 brought some fundamental changes with the entity system and a new database abstraction layer and quite a bit of added complexity, but the hook system, the template system and a lot of other things were retained.
That changed in a major way with Drupal 8. Like major! And the changes were enforced even more strongly in version 9 and 10 where a ton of things that kept D8 connected to D7 – and added a certain degree of backwards compatibility – were simply removed. Deprecated as it’s called.

I’m not saying that the latest Drupal is a bad CMS (well, I might hint that below), but it’s a very different CMS compared to version 7.

End of life

Drupal 7’s end-of-life was first announced to be November 2022.
That was extended to November 2023 earlier this year, so another year for those of us planning to do an upgrade.
For good measure and as a reflection of reality (read: the sustained popularity of Drupal 7), it was recently further extended to January 2025.
That means that after January 2025 there will be no more updates, no more security patches, and support will slowly be dwindling. After that date it will be downright stupid to make a site based on Drupal 7, but well before that – essentially now – it’s a really good idea to upgrade and move on from Drupal 7 to a newer version.
You’d be better off moving on to version 9/10 right away, because that’s the current version, and Drupal 10 is what Drupal.org is pushing and recommending right now.

So GFF is due for an upgrade to the present version of its core publishing system.

Upgrade to Drupal 10 - Yeah, right!
Martin Joergensen

The problem is that upgrading is a pain. Upgrading most systems is a pain, because in spite of all promises, things are rarely as smooth as expected or wanted.
Upgrading from Drupal 7 to 8/9/10 is a real pain!
And that’s because of the huge differences between Drupal 7 and the following versions, particularly when it comes to programming and adding custom functions, but also because a lot of modules have changed drastically – or ceased existing.

Symfony and Twig

The people behind Drupal also decided to start using the Symfony framework and the Twig template system that comes with it. They also decided to embrace a more object oriented approach to coding, and a new file structure for the code was also implemented, using a lot of YAML-files for configuration, and splitting up a lot of code into many separate files, which could previously be just one.
Things like themes and modules are now divided into a wealth of folders and files where filenames are deciding for the registration of classes and functions. This again has led to the need for using namespaces and some kind of dependency manager, where “the market standard for PHP”, namely Composer, was selected.

My problem is that of all these choices: Symfony, Twig, OOP, YAML, Composer and namespaces, I basically only like OOP. And I’m not even especially crazy about the way that Symfony uses OOP. Namespaces are OK, but introduces the need for a ton of use statements, and namespaces are – as many of the other new elements – a sign of the growing complexity. It’s used to iron out all the complexity wrinkles introduced by these new choices. And you know I hate complexity!
I’m not too fond of Twig. It’s another language to learn, and it does little (nothing, actually) that PHP can’t do. And PHP can do much more. I was OK with PHPTemplate, which was the template system in version 7. It used plain PHP in the templates, meaning no need to learn a new syntax.

An example

Composer doesn’t do what what I thought it was supposed to: manage dependencies. I just installed Flexslider on my local server using Composer. Easy peasy. Just copy and paste the command from Drupal.org:
composer require 'drupal/flexslider:^2.0'
Or it should be easy. My version of Composer runs under Windows 10, and chokes on the single quotes, and emits the total useless and clueless error message:
[UnexpectedValueException]
Could not parse version constraint 2.0': Invalid version string "2.0'"

This might very well express what’s going on inside Composer, but as an error message caused by single quotes in stead of double, it’s pretty uninformative. The problem is not the version string, but the way it’s quoted. And please notice that the command is copied ad verbatim from drupal.org, so it must be right, right? Not!
Replace it with:
composer require “drupal/flexslider:^2.0”
and Composer fires up and does its thing. Or rather… doesn’t, actually, because as a dependency manager it does a damned poor job here.

I would expect it to install the module and its dependencies – d-e-p-e-n-d-e-n-c-y manager, right? But no. Once done, it has installed the module, but the JS library needed to use Flexslider is nowhere to be found. You would expect it to be located in the /vendor folder where all other libraries are found, but it isn’t there.

After some research it becomes apparent that you need to fetch it yourself and place it in /libraries/flexslider – like in the old days!
With that done, Flexslider works.

… and Composer sucks!

I downright loathe Composer, which is a symptom of things going in a wrong direction, much more than a helpful tool in my eyes. When projects need tools like Composer to keep track of dependencies, it’s typically a sign of them becoming way too complex.
And unfortunately Composer doesn’t solve that with a simple spell. Composer is a command line tool, which is complex to use and emits tonnes of useless and hard-to-understand gibberish when things go well, and even more useless gibberish when things go wrong. Needless to say that things very often go wrong … I think my Composer-commands generally fail or emit an error code more than half of the time I run Composer. And Composer can blow up a site completely and almost beyond repair with a single command gone wrong. Such is the power of command line tools.
And for good measure: Composer does NOT make manual downloads unnecessary. For some reason, this dependency manager is unable to keep track of quite a few dependencies, and basically always leaves me with some manual patching to do when I’ve run it.
I hate Composer!

I don’t mind package managing and dependency checking, but for crissake let’s do it in a modern, robust and helpful tool! Not an archaic command line tool with a ton of switches and crazy error messages! I thought we’d entered the modern era of web- and GUI-based tools.
I don’t know what tool should be used in stead, but there’s bound to be something better than Composer.
And mind you, it’s not like I can’t use the command line. I was weened on DOS-prompts and use UNIX almost every day, and can easily see the benefits of efficient command line commands. But for tasks as complex as this, we should move on.

When Symfony breaks, everything breaks

Another annoyance with Drupal 9 is the sensitivity of Symfony. It’s very finicky and has no really good ways of handling what seems to be pretty mundane errors.
In my eyes, modern frameworks should be robust and able to run on the fumes of a system, giving back meaningful and sensible messages, which can be used to correct whatever errors are found.
It should also present the user with a decent error page, and not an ugly dump of code-gibberish.
Not so with D9 and Symfony!
The combo mostly crashes and burns when something goes wrong, if a class or file is missing or some YAML-file contains references, which aren’t found – or just has a wrong indent. And the way it tells me – and the end user this – is by some really mean looking techno-babble on a blank screen, and no access to the system at all before it’s fixed.
Due to the way D9 operates and the way it basically caches everything, there will rarely be a way of returning to a working site because the errors and missing dependencies have been written to the cache, which is read on restart, and emits the same error – even though it might be fixed in the code or the files.
Sure you can clear the cache… using an other command line tool called drush... or you may be so lucky that a /core/rebuild.php is permitted, but why isn’t there a way to do this through the interface, even with the errors occurring? It might not fix the error, but at least you wouldn’t be in a deadlock with only voodoo as the way out.

Maintainers
Maintainers
Martin Joergensen

Not my decision

Now, Drupal is open source and the development and direction that its parts take is in the hands of many people. Of course there has to be a central committee to lay down the general lines, but I can essentially do what I please in the parts that I program, and can offer them back to the community to decide by popular demand whether they like it or not. If nobody likes what I do, it doesn’t get used or maybe gets transformed by other programmers to a more generally acceptable way of doing things. If people really like what I do, it will get used and may even get the honor of being integrated into the core of the system.
But the overall direction of the core and the basic principles isn’t something that I can influence. It might be the case if I really engaged myself in the development of the core, but that’s not something I have the skills or the resources to do. That also means that decisions like basing the system on Symfony and Twig, and using Composer isn’t something that I was asked if I liked. I could have meddled with the people making that decision, and participated in the discussions prior to making it, but I honestly don’t think my words would have carried any significant weight in such a discussion.
Systems like Drupal have a priesthood of high priests, whose words weigh much heavier than what we humble oompa-loompas contribute. Most of them have earned their robes through knowledge and hard work within the community, and I respect that. But it doesn’t make them presidents of the state of Drupal. I know that an open source community is essentially a very democratic society, but like all other democratic societies, it takes commitment to get influence beyond your single vote, and only a few people have this commitment, and their influence naturally becomes significant.
So Drupal has taken turns that I wouldn’t have given it if I had anything to say.

Huge differences

The result is that the difference between the versions 7 and 8/9/10 has become huge. A few structures are similar between the versions, but the way core, modules and themes are built differ significantly. Moving a site from one to the other requires some major changes.
There are tools to migrate from 7 to 9/10. That is, if you have a pretty straightforward and mundane installation with a simple content structure and few or no custom made elements. And provided that the contributed modules you use are all migrated to version 9/10, which is far from the case with a lot of D7-modules.
And guess what… GFF is not such a mundane system!
GFF is big and complex, has tonnes of custom functions, and utilizes Drupal out into every corner with many modules made for special purposes, a home made theme, and a lot of adaptations tailored for this site. It also uses quite a few modules, which are only barely ready for current Drupal versions, and a couple that will most likely never be. One really important module, which the site uses heavily, is the caching system Boost, which has no Drupal 9/10 version and none in the pipeline. The latest update is from 2019. The built-in cache in D9 and 10 is complex and convoluted, and does nothing along the lines of Boost, so there’s a task to be solved there before I move anything to a new version.

From scratch

So upgrading this site is not a question of running a couple of migration scripts and adjusting a couple of modules, but more like building a Drupal 10 site from scratch and programming a lot of routines to import users, content and structure. And even after that, there will still be a lot of manual work left, necessary to get things to connect and behave.
There’s such a huge difference between the versions, that the theme and custom modules basically have to be coded from scratch. And I have programmed a lot of modules for GFF in order to handle the many features of the site, not least some of the administrative ones, where I have made various tools to make he task of running the site easier.
And of course a thing such as LeaderCalc or the magazine images will require a lot of work.

Getting around to it

I work professionally with Drupal 9 and 10 in my day job, and I’m starting to know my way around the system. But I know Drupal 7 so much better, and developing for D7 is a second nature to me, while my D10 skills are still at the foot of a steep learning curve even after having done it for more than a year in my daily work.
I dread the day where I will have to start the GFF upgrade, which will probably be some time in late 2023. I reckon that I’ll need some months to make it work, and once I have set up a D10-site, I’ll have to make routines, which can incrementally import the ever growing content on the current site, in order to be on par with the last additions when I decide to switch over.

Content isn’t the worst

Just the task of converting is Sisyphean, even though converting content isn’t bad. The content systems behind D7 and D8/9 are fairly similar.
The huge difference is in the module programming, where I have a bunch, which are very central to GFF. The way these are made now is almost infinitely different compared to before, and the process of building them is vastly more complex. The addition of the Symfony framework has made even the simplest task extremely complex.
Let me exemplify.
Drupal used to have some really neat little helper functions to do certain common tasks. A couple were for making proper URL’s and links, done with two functions called url() and l().
These have been deprecated in the latest versions. And their replacements are crazy complex collections of class uses, object initializations and function/method calls.

Linking then:
$link_as_html = l(‘Patterns’, ‘patterns’);

Linking now (on a bad day):
use Drupal\Core\Link;
use Drupal\Core\Url;
$url = Url::fromUri(‘internal://patterns’);
$link = Link::fromTextAndUrl(t(‘Patterns’), $url);
$link = $link->toRenderable();
$link_as_html = render($link);

Linking now (on a slightly better day):
use Drupal\Core\Link;
use Drupal\Core\Url;
$link_as_html = Link::fromTextAndUrl(t(‘Patterns’), Url::fromUri(‘internal://patterns’))->toString();

I’m sure there are some higher and nobler motives for the direction chosen, but they seem pretty ulterior to me. I can’t see what gains come from introducing the colossal complexity to almost every layer of the system. What was a pragmatic and efficient system has become convoluted and opaque.
It’s simply hard to deduct how to do things compared to before. If there was a function called node_load() – and there was – you could be pretty sure that there was a user_load() and an image_load(), all taking the element id as an argument.
Loading a node now?
$node = \Drupal\node\Entity\Node::load($nid);
or the recommended way:
$node= \Drupal::entityTypeManager()->getStorage(‘node’)->load($nid);
And getting an image?
$image = \Drupal\media\Entity\Media::load($fid);
A user:
$account = \Drupal\user\Entity\User::load($uid);
A term:
$term = \Drupal\taxonomy\Entity\Term::load($tid);
OK, there’s a degree of consistency, definitely, but there’s also added complexity. Notice how it’s node/Node, media/Media, user/User and then taxonomy/Term! Why not term/Term?
Add to that the notorious camelCase and use of User/user, Node/node and so on. A pretty sure way of introducing random errors, and although there might me a motivation for the alternating letter case, it’s not obvious or logical, and you basically have to check the (confusing) documentation every time.
For some this might be the seventh heaven, but for me node_load, image_load, user_load makes so much more sense.

Off on the wrong foot

So I’m starting at a pretty lousy starting point: I simply don’t like the way things are done now, but a decade invested in code and content means that it’s the only logical way for me to go, and luckily my paid job has brought me through the worst labor pains, and I do know my way around the new system much better than I did when the manuscript for this article was first started back in March 2020.

.

Log in or register to pre-fill name on comments, add videos, user pictures and more.
Read more about why you should register.
 

Since you got this far …


The GFF money box

… I have a small favor to ask.

Long story short

Support the Global FlyFisher through several different channels, including PayPal.

Long story longer

The Global FlyFisher has been online since the mid-90's and has been free to access for everybody since day one – and will stay free for as long as I run it.
But that doesn't mean that it's free to run.
It costs money to drive a large site like this.

See more details about what you can do to help in this blog post.