Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
May 12 2023
May 12

Access from where

As mentioned, it matters from where you are trying to access a field value because this will determine how you can query and load the entity it is attached to. When accessing from object oriented code, you should always try to inject a service when you can. In procedural code (a hook for instance) this is not possible and loading will have to be called statically if the entity you need was not passed in.

What type of data

Before Drupal 8 was released there was no consistent way of telling if a field value is for instance a string, an integer or a timestamp. This created a lot of problems when building machine readable APIs on Drupal that expose its data to other systems, one of the major promises of Drupal 8 and later. A solution was needed for a consistent way of typing this data, or describing the data. This is where the Typed Data API comes in. The Typed Data API for a large part determines how you can access data of a specific type, let’s see what that means.

One way to access a field value then looks like:

use Drupal\node\Entity\Node

$node = Node::load($nid);
$title_field = $node->get('title');
$title = $title_field->value;

The first 2 lines provide us with a loaded node object to work with in the example. To keep focus, let’s assume from her on that we already have a node loaded or passed in. As mentioned in the beginning of this article there are several ways to query and load nodes (or other entities), we will get into that in another article. After loading the needed node(s) it no longer matters from where you are trying to access the field value, the code is the same.

So what happens on line 3 and 4 of the example above? On line 3 we first use the get() method to load an instance of FieldItemList into a variable. The get() method is present on all content entities, we use the field name of the data we want to access to call this method. On line 4 we then call the value property on the loaded field object in order to load the actual title string into a variable. It is important to realise that value is a so-called magic property pointing to the first primitive value in the list that the instance of FieldItemList gave us. 

Magic properties are very handy but it is important to be careful when using them because they somewhat obscure what is going on beneath the surface. On top of that, although most fields use the value property, some fields use a different property name. An example of this are entity reference fields using target_id as their property name. Line 4 of our example would then look like:

$id = $field_reference->target_id;

Instead of a string like the node title, this would load the target_id integer into a variable. Because it is quite likely that you would like to access data on the corresponding item, there is the magic entity property that directly gets you the fully loaded entity object for this item. It’s as easy as this:

$entity = $field_reference->entity;

While these magic properties are very useful, be aware that the appropriate property depends on the field to be accessed and using the wrong one will result in an error. Also when working with more complex data types (date for instance) or fields holding multiple values (cardinality larger than 1), using magic properties can lead to unexpected results.

So besides accessing data using magic properties, what other options do we have?

The getValue() method

The getValue() method is present on all TypedData objects and returns the raw values stored. Calling this method on the field in our example returns an array holding one item (since we only have one item in the list) that contains the individual item raw values. It would look like this:

$title_field = $node->get('title');
$value = $title_field->getValue();

While the list could be useful in some cases, we want to access the data of the title field like we did earlier using the value property. So to make this example get to the same value above, we need to dig deeper into the array:

$title_field = $node->get('title');
$value = $title_field->get(0)->get('value')->getValue();

What this does is get the first item in the list (use get(0) or offsetGet(0)) returning a FieldType plugin. Because we know that the title field uses the name value for its property we can use the get() method to get its property by name. Finally we use the getValue() method to get the string value from the Stringdata Datatype plugin. 
You can now see how accessing the string value can lead to quite lengthy code and why using the magic value property explained earlier is so appealing.

Helper methods

Many content entity types have helper methods on their class to make accessing certain fields easier and more verbose. Staying with the title example, we could get the title string from the node as follows:

$value = $node->getTitle();

Helper functions can be found in the class that is responsible for instantiating the object you are working with. The notation is usually short and verbose. Besides that, it is generally advisable to use helper methods when available because in future releases these might be changed or overridden featuring additional logic that is very specific to what the helper method does.

Conclusion

Looking at the options laid out above, you might ask what option should I use to access a field value?
The main driver for this decision is the cardinality of the field you are dealing with. If you know that the field has only one value, you can use the following:

$title = $node->get('title')->value;
$id = $node->get('field_reference')->target_id;
$entity = $node->get('field_reference)->entity;

If the field has more than one value or you expect to refactor code to accommodate this in the (near) future, you can use the following:

$names = $node->get('field_names')->getValue();
$tags = $node->get('field_tags')->referencedEntities();

Hopefully this sheds some light on accessing values on fields in Drupal. While it might seem somewhat complex or even overwhelming, it leaves us with a robust way of accessing data that provides a strong foundation for working with Drupal in the future.

Extra: chaining

While this notation is verbose and very clear, you don’t have to split the get() and value calls. You can put both on one line like:

$title = $node->get('title')->value;

Extra: test if the field exists

This code shown in the examples will throw an error if the entity doesn't have a field named "title". Make sure this code only gets run on entities where you know that field exists. If you are unsure if the is the case, you can use $entity->hasField('field_name') or if (!empty($entity->field_name)) to test.

Extra: no need to explicitly call get()

You don’t need to call get(), because this is a magic method. So in our example, this line:

$title = $node->get('title')->value;

Could be written as:

$title = $node->title->value;

Calling a magic method like this provides slightly cleaner code that is even easier to read. Please be aware that magic methods can not be always used while standard methods can be.

Mar 10 2023
Mar 10

By default, a standard Drupal installation already comes with a predefined block type that is used when you add a custom block to a region: the Basic block. It only has a title and body field. Drupal block types work quite similar to content types. It allows you to create a particular type of block by adding and managing fields, form display and display modes.

Out of the box, Drupal offers several ways to use a Twig template to theme your custom block. However, when you want to create a Twig template that applies to all blocks of a specific block type, you need a few lines of code.

To enable templates for custom block types, we use theme suggestions. Assuming you have a custom Drupal theme called "mycustomtheme", place the following snippet in your mycustomtheme.theme file:

function mycustomtheme_theme_suggestions_block_alter(array &$suggestions, array $variables) 
{ 
  // Block suggestions for custom block types. 
  if (isset($variables['elements']['content']['#block_content'])) { 
    array_splice($suggestions, 1, 0, 'block__type__' . $variables['elements']['content']['#block_content']->bundle()); 
  } 
}

Now you can use block–type–my-block-type.html.twig to theme every custom block of the block type you have created.

Happy theming!

Oct 07 2020
Oct 07

There are several stable contrib modules available that offer redirecting users - often as one of many functionalities. In some cases however, you might want to write your own module in order to precisely control what it does. Or perhaps you would like to combine this code with other specific requirements into a custom module.

Whatever your particular reason, here’s how redirect users the proper way in Drupal 8:

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MYCUSTOMMODULE_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#submit'][] = 'MYCUSTOMMODULE_user_login_form_submit';
}

/**
 * Custom submit handler for the login form.
 */
function MYCUSTOMMODULE_user_login_form_submit($form, FormStateInterface $form_state) {
  $url = Url::fromRoute('/your/destination/path');
  $form_state->setRedirectUrl($url);
}

For Drupal 8 in particular, it is important to note that we no longer use hook_user_login(), because it would stop other implementations of that hook to be invoked. Instead, we’re adding a custom submit handler to the user login form.

Of course this is just a starting point. You could add certain conditions or redirect users to different paths depending on their user role. 

___

Hope this helps! Please don't be afraid to reach out if you need any help with your Drupal project. Our experts are always happy to help!

Sep 23 2020
Sep 23

The main reason for the global arg() function to be deprecated in Drupal 8 and onwards is that it no longer served any specific need. Besides that, using the arg() function needed some extra care to avoid getting unexpected results. Say that you wanted to load a node on the path 'article/123', executing arg(1) would return '123' with which you could load the node. Using the '123' returned by arg(1) did not in any way guarantee that the path was valid or even that a node with ID 123 existed.

In Drupal 8 and onwards things are done differently. Consider the following:

$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface) {
  $nid = $node->id();
  // Do whatever you need to do with the node ID here...
}

Getting the node ID this way is far more robust than doing so the old way using the arg() function. We know for sure the node exists and the path is valid because routeMatch() would not return a node object otherwise. As a bonus you can easily do some extra validation because you already have the node object loaded. You could, for instance, check that the node is of type 'article' by adding:

if ($node->bundle() == 'article') {

Getting the node ID this way may seem like a lot more work than using the deprecated arg() function, but it certainly guarantees a way more robust way of working which in turn will make your code better and more stable.

___

Need help developing your Drupal website? Our team of expert Drupal developers would be more than happy to help you out!

Aug 25 2020
Aug 25

When migrating our Drupal website from 7 to 8, after much debate, we decided to convert all image fields on our old website to media fields in our Drupal 8 website. Little that we realise that we would eventually run into a little theming difficulty along the way. What seemed like a very basic requirement at first glance, turned out to be a little harder than we thought.

The hero images used in this website are in fact images from a media field on content type ‘article’. In Drupal 7, we would have used an image field and programmatically get the image url in a node template, like so:

field_image['und'][0]['fid']);
  $hero_uri = $hero_img->uri;
  $hero_url = image_style_url("my_image_style", $hero_uri);
?>

And set it as a background image like this:


Yes, there probably is a module for that, but where’s the fun in that, right?

Retrieving the image url from an image field in Drupal 8 and 9 seemed pretty straightforward too. Even the solution for getting the image style url from a simple image field can be found quite easily. Getting the image url from a media field can also be looked up easily. 

For some reason however, it seemed nobody had attempted to retrieve the image style url from a media field image in Twig before. Or at least nobody had documented how to do it. There’s a twig module called Twig Tweak, but it doesn’t appear to support image styles. 

Finally, after lots of Googling, documentation skimming and trial and error, we found the solution. This is what we ended up using in our twig node template:

This will respect the image style set in your Drupal admin. The image style is set in on the Manage Display tab of your content type. 

That's it folks! Hope this helps anyone out there.

___

Need help developing your Drupal website? Our team of expert Drupal developers would be more than happy to help you out!

 

Aug 13 2020
Aug 13

This error message is caused by a security feature that was added to Drupal 8. Previously, it was possible to spoof the HTTP Host header and trick Drupal into using a different domain name. In other words, your Drupal site could be duped into thinking it to be someone else. 

In order to prevent this from happening, Drupal looked at the Symfony framework which already provided a trusted host mechanism, where site administrators could whitelist hostnames. Trusted hosts can now be configured in Drupal through a new setting in settings.php:

$settings['trusted_host_patterns']

According to the documentation, this setting needs to be an array of regular expression patterns, without delimiters, representing the hostnames you would like to allow to run from.

For example, if you want to run your Drupal website only to run from www.yourdomain.com, you write the following in your settings.php:

$settings['trusted_host_patterns'] = array(
  '^www\.yourdomain\.com$',
);

Or if, for example, you would like to run your Drupal website off of *.yourdomain.com and *.yourdomain.org, your settings.php would have to include this:

$settings['trusted_host_patterns'] = array(
  '^yourdomain\.com$',
  '^.+\.yourdomain\.com$',
  '^yourdomain\.org',
  '^.+\.yourdomain\.org',
);

Using regular expression patterns, you can build all sorts of rules.

For local development environments, you could include the following in your local.settings.php:

$settings['trusted_host_patterns'] = array(
  '^127\.0.\0.\1$',
  '^localhost$',
);

Have fun and be safe out there!

___

Jun 17 2020
Jun 17

This is not a migration

Previously, a major version update for Drupal implied a time-consuming migration process. It usually involved content migrations, configuration changes and porting modules to enable them to work properly. In some cases, migrating took nearly as much effort as rebuilding a site from scratch. 

This time however, upgrading will most probably have none of that. In fact, according to the founder of the Drupal project, a key target when developing Drupal 9 was ease of upgrade (https://dri.es/making-drupal-upgrades-easy-forever). Version 8 was all about dealing with technical debt so that future releases would be like they are in WordPress: painless, fast, and fun. With Drupal 9, this has finally been accomplished.

There’s plenty more shiny new stuff under the hood that propels Drupal into this new era of digital experience frameworks.

What’s great about Drupal 9

Ease of upgrade is not the only new feature in Drupal 9. There’s plenty more shiny new stuff under the hood that propels Drupal into this new era of digital experience frameworks. What we are most excited about is its API-first development. Drupal now includes JSONAPI in core. This means Drupal is no longer the traditional monolithic cms we’ve come to know. Instead, it is now built to support headless applications, third-party data integrations and pretty much any modern innovative use cases for the open web. Furthermore, editorial flexibility and content management experience both took huge leaps forward.

Upgrading from Drupal 8

Drupal site owners who have been keeping their Drupal install up-to-date are in for the smoothest ride. The only differences between Drupal 8.9.0 and Drupal 9 is the removal of some deprecated APIs and the inclusion of updated third-party dependencies, such as Symfony and Twig. As long as the modules you have in use do not rely on deprecated code or libraries, you should be good to go.

This how our Drupal experts prepare for a smooth operation when upgrading a Drupal 8 site to Drupal 9: 

  • Ensure that a site is running the latest stable version of Drupal 8 and any contributed modules installed
  • Install and run the Upgrade Status module. This tool integrates into the site’s status update to check system requirements and contrib module compatibility for Drupal 9.
  • If we run into contrib modules with compatibility issues, scan the respective module’s Drupal.org page and issue queue to find out about their Drupal 9 readiness and possible solutions or workarounds.
  • Check custom modules for use of deprecated libraries or APIs. The Rector module is often very helpful. It automates PHP code upgrades by renaming classes, methods, properties, namespaces and constants.
  • Check the hosting environment and make necessary changes if needed. The Upgrade Status module should point out the system requirements for Drupal 9.

After completing these steps, we are ready to update the Drupal core to version 9.

Upgrading from Drupal 7

For Drupal 7 site owners, there is no clear upgrade path. Upgrading from Drupal 7 usually involves rebuilding the site in the new version and migrating all content and configuration to the new site. This may require more resources, but it is a great opportunity to rethink the site structure and implement some major improvements.

We’re here to help

Whatever your current situation, we are here to help. We combine strategy, design and development on a daily basis to help our clients solve complex business challenges. And our Drupal migration experts are more than comfortable upgrading or migrating any complex website to Drupal 9. 

Send us an email or give us a call to discuss your project with us! We’re happy to help.
 

Feb 20 2020
Feb 20

As a creative digital agency based in Amsterdam, we’ve gotten used to having two languages of conduct: Dutch and English. We switch back and forth without even noticing and have learned to read, write and conduct business in both languages effortlessly. Our clients are mostly Dutch, but many cater to an international audience or operate beyond borders, so by now there quite a few multilingual websites in our portfolio.

Despite the potential complexities multilingual websites may pose, Drupal has always been notoriously adamant about supporting all languages - including those with non-latin scripts and those read from right to left. Whereas multilingual sites in Drupal 7 often required a plethora of internationalization and translation modules, combined with some custom code, Drupal 8 was going to solve all our multilingual headaches once and for all. Or did it?

Everything is perfect. Almost.

Admittedly, Drupal 8 has made it easier than ever to support multiple languages. Its architectural overhaul simplified the structure, thereby making internationalization of content much more logical and efficient. A lot of internationalization functionality was moved to core in order to improve maintenance and support. And of course, to enable Drupal site builders to create multilingual sites out of the box.

So Drupal 8 solves every pet-peeve you could’ve had with multiple languages in a single site perfectly and for good. Right? Not quite. Things are never exactly how we (or our clients) want them and that’s fine. That’s why there are Drupal Developers.

Sleek and minimal will do.

Let’s talk about the language switcher in Drupal 8. It can be enabled, placed as a block in the region of your choice and it pretty much works. It shows all added languages written out fully, like so:

  • English
  • Nederlands

However, as we like our site sleek and minimal and consider our visitors tech-savvy, we would like to customize the links and determine exactly where and how the language switcher links get rendered.

Customize the language block

In order to control the output of the language switcher block, we want to be able to render the necessary links only. We don’t need a block title or any of those pesky elements, we just want an HTML list with links, for example:

Luckily, Drupal 8’s Twig templating system makes it pretty easy to render exactly what we want. Just place this in the page.html.twig of your custom theme where you want your language switcher links:

{ # Language switcher # }
{{ drupal_block('language_block:language_interface', wrapper=false) }}

Changing the link labels

Although it’s probably best practise to fully write out the available languages - English, Nederlands, Francais - we could do with some more sleek minimalism. Besides, we consider our visitors as tech-savvy, so we can probably suffice with showing only the language codes as our links: EN and NL.

Let’s tackle this one with a preprocess function. Just paste this code in your CUSTOMTHEMENAME.theme and the links in your switcher should magically transform into language codes:

/**
 * Use language code for the language switcher
 */
function CUSTOMTHEMENAME_preprocess_links__language_block(&$variables) {
  foreach ($variables['links'] as $i => $link) {
    // @var \Drupal\language\Entity\ConfigurableLanguage $linkLanguage
    $linkLanguage = $link['link']['#options']['language'];
    $variables['links'][$i]['link']['#title'] = $linkLanguage->get('id');
  }
}

Don’t forget to change CUSTOMTHEMENAME to the name of your custom theme.

Hide links for untranslated content

Once the language switcher is enabled and placed, it’s always there. Even when there is no translated version of the page you are viewing, there is a link to the translation of that page. Which doesn’t exist and will just lead you back to the same node, possibly on an unaliased path. That’s bad for SEO and worse for usability.

Let’s fix this by only rendering translation links when translations really do exist. We’re going to create a custom module. Let’s call it “untranslated”.

Our untranslated.info.yml file looks like this:

name: Untranslated
type: module
description: "Disables language switcher links for untranslated content."
package: Custom
core: 8.x

dependencies:
  - language

And untranslated.module looks like this:

 $link) {
      try {
        if ($entity->getTranslation($lang_code)->access('view')) {
          $new_links[$lang_code] = $link;
        }
      }
      catch (\InvalidArgumentException $e) {
        // This language is untranslated so do not add it to the links.
      }
    }
    $links = $new_links;

    // If we're left with less than 2 links, then there's nothing to switch.
    // Hide the language switcher.
    if (count($links) < 2) {
      $links = array();
    }
  }
}

/**
 * Retrieve the current page entity.
 *
 * @return Drupal\Core\Entity\ContentEntityInterface
 *   The retrieved entity, or FALSE if none found.
 */
function untranslated_get_page_entity() {
  $params = \Drupal::routeMatch()->getParameters()->all();
  $entity = reset($params);
  if ($entity instanceof ContentEntityInterface) {
    return $entity;
  }
  return FALSE;
}

Now enable this module and your untranslated links should magically vanish until you publish a translation of your page.

There’s been some debate about whether you should remove the links to untranslated content as we demonstrate here or go for a less radical approach and add css classes in order to display links as grayed out or apply strikethrough. This decision will depend on your particular case or client.

The rest of the customizations we applied were just styling, so we’ll leave those up to you and your designers.

If you need any help with your Drupal website, feel free to reach out to our expert Drupal developers. We would be more than happy to help you out.

Have fun out there!

___

A big thank you to these very helpful resources:

Jan 03 2020
Jan 03

That’s nice, now why are you telling me this?

In you role as a project- or site owner you might not be aware of the implications the “End of Life” announcement has if your site is running on Drupal 7 right now. There are two things you should be aware of:

1. Active development of Drupal 7 stops on the EOL date.

This does certainly not mean that your site will come to a grinding halt on that day, but it does mean that Drupal’s strong points will start to fade going forward. The Drupal Association will no longer provide security releases for Drupal 7, no further development on the core framework will be done and development on the Drupal 7 version of most contributed modules will stop.

Security, flexibility and scalability are often reasons why Drupal was chosen for a project and this clearly has an impact. I knowingly say ”impact” because the robustness of the Drupal project prevents a full stop of support even after the EOL date. A number of partners will be selected to provide paid security support for several years and there will always be members of the community who are prepared to do some work on unsupported contributed modules.

2. Upgrading means migrating.

Upgrading your site from Drupal 7 to Drupal 8 means that you have to also migrate all content that is present in your site. The theme that is used to display the content on the site will also have to be re-developed. This only holds true for this specific upgrade and not for later upgrades from Drupal 8 to Drupal 9 for instance, more on that later... The massive structural changes of the inner workings of Drupal are the cause of this, highly inconvenient but certainly necessary to keep Drupal the modern framework we all need it to be.

Performing a migration and re-developing the theme mean that this needs to be discussed and planned well in advance. Depending on the size of your site the time needed may vary, but to wait until the EOL date arrives is obviously not a good idea.

I see, so what should I do?

The sensible thing to do is to start thinking about what steps are necessary to perform an upgrade to Drupal 8. Drupal 8 was released in November 2015, so it has been in production use for over 4 years now. It is a very stable and mature piece of software with a wide adoption worldwide.

As mentioned earlier, “under-the-hood” Drupal 8 changed significantly compared to Drupal 7. Upgrading therefore provides a chance to perform structural and visual changes to your site that you have in mind anyway. It doesn’t make sense to make big changes to your Drupal 7 site when you know that it’s official life will come to an end in 2021. If you now start to plan for incorporating these changes into the Drupal 8 version of the site, you still have plenty of time to thoroughly discuss these changes and efficiently spend your budget when the time comes to actually perform the upgrade.

The same goes for migrating your content. The upgrade provides an opportunity to think about what content you want to keep and how you can put it to it’s best use!

Drupal 9 will be released in 2020, do I have to do all this again? Should I postpone?

Drupal 9 will be released on June 3rd 2020. Since that is less than half a year away, it might seem better to wait a bit and move from Drupal 7 to Drupal 9 directly. That’s where the big “under-the-hood” structural changes in Drupal 8 come in, upgrading from Drupal 8 to later versions will be extremely easy and not require a full migration! This makes the move from Drupal 7 to 8 an exception, once you are on Drupal 8 upgrading can more or less be done with the click of a button!

So migrating to Drupal 8 first makes a lot of sense because you can start incorporating changes into your site directly, without having to wait for a move away from Drupal 7. This way you benefit from being on the new version of Drupal right away and are future proof from that moment on.

Ok let’s do this, how do we perform the migration?

There are 3 parts relevant to the migration from Drupal 7 to Drupal 8: upgrading code, rebuilding the theme and migrating content. To perform a successful migration we first need to understand where you want to go, so we first discuss what the Drupal 8 site will look like before we do anything else. We have extensive project management experience in house that will lead to a clearly defined product to deliver.

Once we know where we are going, it is time to look at the Drupal 7 site we are coming from. For projects we have not built ourselves this usually means we perform an assessment that tells us how the site is built and what we can expect from its content. The assessment’s outcome tells us how much work the migration will entail and forms the basis for an estimated budget and time needed to complete the project.

Do you want us to help you migrate your Drupal website? Contact us for an introductory meeting and get started right away!

Nov 12 2019
Nov 12

Why this is a problem

Allowing any user to user to upload files directly to your website introduces the risk of accepting virus infected files into your filesystem. The risk is much higher for anonymous (not logged in) users because they might be malicious users, but for business reasons it often makes sense to allow anonymous users to submit files. Further processing of infected files, like forwarding a submitted resumé to colleagues or external parties, allows the virus to spread. This could cause significant trouble and hurt SEO as well as your reputation as a dependable business partner.

Scan those files!

Scanning files that are uploaded by anonymous users to a site is something that is often overlooked. Fortunately this a problem that can be easily fixed! The most common way to solve this is by installing a virusscanner in your webhosting environment and let it scan each file that is uploaded. There are various options out there, but we use the open source virusscanner ClamAV to get the job done. In order to be able to scan uploads in your Drupal site there are 2 things you need to do:

1. Install the ClamAV binary file in your hosting environment

With high service managed hosting providers like Acquia or Pantheon this has often already been done for you. If you are hosting on a VPS or dedicated server you will have to install the binary yourself, see this guide for some help with that.

2. Install and configure the ClamAV Drupal module

Instructions are on the project page. Don’t forget to clear the cache of your Drupal installation after after you complet the install, most settings will not take effect until you do. After installation and configuration, you can verify the module is working correctly by trying to upload a fake virus to your website. For this purpose ClamAV is EICAR compliant, meaning you can upload the harmless EICAR anti-virus test file that will then be detected as a real virus if the installation works correctly.

Enjoy your hassle-free solution

This setup now allows for each file that is uploaded to your Drupal website to be scanned for viruses. An infected file will not be accepted into the filesystem and an entry into the site’s log is made so you can keep track of infected upload attempts.

Scanning uploaded files this way provides you with an extra layer of security in your website, protecting your organisation, SEO results and business reputation without site visitors even noticing…

Oct 01 2018
Oct 01

Since its release in November 2015, Drupal 8 has kicked up quite a fuss. If you’re running a Drupal website, by now you’ve probably heard people talk about Drupal 8. It’s a major upgrade with many improvements, but many users are still wondering if and when they should upgrade their current website to Drupal 8. Is a migration worth the resources? What advantages does it offer over older versions?

In this post we’ll share just some major improvements of Drupal 8 over its previous versions that may help you determine whether an upgrade is worth it. This list is compiled from first-hand experience, most commonly heard when talking to clients who took the plunge.

1. API first

Drupal 8 is built around a services-based, API architecture that is able to serve content across an infinite variety of apps, platforms and devices. This also makes it easier to disconnect the front from the backend and use a separate frontend framework (such as React, Vue or Angular) to create different apps and user interfaces that all draw content from one central structured content database. 

2. Improved performance

The list of improvements is endless, but you can take it from us that Drupal 8’s performance has increased substantially. Better JavaScript handling, intelligent caching and selective code execution all contribute to way better website loading times.  

3. Enhanced accessibility

Unlike its previous versions, Drupal 8 enhances web accessibility by supporting industry standard accessibility technologies — WAI-ARIA. It allows developers to use HTML5 natively, making it easier to optimize for accessibility and SEO. The Drupal 8 frontend is responsive by default, making any install ready for all devices.

4. Multilingual by default

Turning a Drupal 6 or 7 install into a fully multilingual website took quite a bit of effort. You needed several contributed modules and often even custom development to pull it off. Drupal 8 has a multilingual DNA, making it was easier and more efficient to translate your website into several languages. 

5. Future ready

The upgrade from previous versions to Drupal 8 may be considered quite an operation, but it may well be the last migration you need to undertake. Drupal’s architecture and release cycle has been revolutionized to offer effortless upgrades to future major versions. This means that your Drupal 8 install will be prepared to upgrade to Drupal 9 without much effort.

Of course this is just a small selection of improved features of Drupal 8 and there are plenty more. The impact of each will rely on your specific case. 

If you need any help to determine what is the best course of action for you, please don’t hesitate to contact us for advice. At The Savvy Few, we provide a range of strategy, design and development services aimed at helping organizations make their digital transformation a success.

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web