loading...
Cover image for Drupal 8.x - What I've Learned

Drupal 8.x - What I've Learned

michaeldscherr profile image Michael Scherr ・5 min read

If anyone has solutions to any of the issues I describe below, please feel free to leave a comment.

I've now developed two production sites with Drupal 8.6. This post will cover what went wrong, how my team fixed them, and then some best practices from what we've learned through trial and error.

The first site, in hindsight, was a complete disaster. There's nothing worse than learning Drupal (or anything for that matter) through trial and error while developing a production website. I knew nothing about rendered entities, view modes, etc. I constantly battled with the templating. We abused the [theme].module hooks, instead of using custom modules to handle functionality.

The second site was much better, although I imagine there is so much more to learn. Our biggest issue was how to effectively use views when using the ajax functionality. Our decision to not make certain taxonomies have actual pages (aka have an accessible alias), led to many problems when trying to filter them in certain views.

Localization continues to be a huge issue. If you've ever developed with Drupal, you know it's insanely frustrating configuring and outputting localized content correctly.

Best Practices (from my experience)

Language Configuration

Trust me when I say this:

Figure out your localizations ahead of time.

You should know before development:

  • all the languages + language codes you'll be using
  • what the original language will be for all content

Scenario:

Say you are told the site will be in Canadian English (en-CA) and Canadian French (fr-CA). Then a couple weeks before deployment, once all content pop is mostly complete, they want to change the language code from en-CA => en.

Here is the problem:

There doesn't seem to be a way to change the language code once it has been added. Additionally, all content that has the previous language code as the original language can't be changed either. Even if you delete the orignal language node translation, you still cannot assign another translation as the original language.

Ok fine, so you add the new language code, content pop all of the nodes again with the new language… and run into another problem. All content in a translation that is not the original language that has a repeatable number of values, cannot exceed the original language's number of entries.

How did we fix this? We haven't. We've thought about updating the database through SQL statements, but please share your thoughts if you have a better way.

Install Drupal Core w/ Composer

Do yourself a favor and use Composer to install Drupal Core. Upgrading core is now as simple as:

composer outdated drupal/*

composer update drupal/core --with-dependencies
drush updatedb
drush cr

More information is available on their website.

Install Modules w/ Composer

Same deal as with core, instead run:

# example
# composer require drupal/[module_name]

composer require drupal/better_exposed_filters

Bonus: Awesome Modules

Use the Drupal Console & Drush Executables

Installation Instructions (Use Composer)

To install via composer, run:

# drupal console
composer require drupal/console:~1.0 \
    --prefer-dist \
    --optimize-autoloader

# drush
composer require drush/drush

Common usage:

# usage
./vendor/bin/drupal [command]
./vendor/bin/drush [command]

# cache rebuild
./vendor/bin/drush cr

# show watchdog log
./vendor/bin/drupal watchdog:show

# install module
./vendor/bin/drupal module:install [module_name]

# generate module
./vendor/bin/drupal generate:module

Setup Drupal for Local Development

Follow this tutorial to make your local development so much easier.

Use View Modes

View Modes allow you to define multiple ways (aka templates) to show the same type of content. The two native view modes are full and teaser. You can accomplish 95% of what you need with those two view modes alone.

Imagine this scenario: You have a content type of Case Study. A case study can appear as a single page (full), inside a view grid (teaser), and also as a featured case study on another page (featured).

You can customize the display of each view mode individually. For example, let's say the teaser outputs the title and description, but hides the image you've set up. However, the image should be shown on the featured and full view modes.

This allows us to leverage 3 different templates and customize the output:

node--case-study.html.twig
node--case-study--teaser.html.twig
node--case-study--featured.html.twig

Use Rendered Entities

Let me save you hours of frustration. Use rendered entities whenever possible. As I understand it, a rendered entity is the output of an entity through its selected view mode.

Imagine the case study featured example from above. You add a new field to the Basic Page content type for a reference to a case study. In the manage display of the Basic Page, you can change the format of the case study reference to Rendered Entity, and select the featured view mode.

This allows for far less code duplication. You are keeping the rendering of entities separate from the nodes that reference them.

Pro tip: you can also use the rendered entity and a specific view mode as the format for a view. Additionally, in scenarios when you have cannot use the content format, you can add a field called Content: Rendered Entity that you can reference this way:

{{ fields.rendered_entity.content }}

Use the Media Module

Yes, it's still experimental, but we haven't had any issues with it. It makes uploading, selecting, and deleting media much easier.

Conclusion

Drupal is very powerful. It allows you to add complex relationships and fields to structure any kind of content. However, there is some higher level functionality that is paramount to understand and implement. Leveraging view modes, rendered entities, and other best practices will help you become a better Drupal developer.

This post ending up being way longer than I intended. There are more best practices and tips that didn't make it into this post. Any comments with new insight or solutions are always welcome.

Discussion

pic
Editor guide
Collapse
teknorah profile image
Norah Shannon

It appears you should be able to change the default interface language by:

  1. Enabling Multilingual modules
  2. Add the language under config > regional and language > languages
  3. Select as default

Also, you can change the language code for entities by either:

  • programatically looping through your entities, and setting the langcode value. Ex:

$node = Node::load($nid);
$node->get('langcode')->value = 'da';
$node->save();

  • running SQL commands through all the tables where langcode is defined and changing the value

Sources:

That being said, you would still need to change the actual content to the new language, as well (manually).

Collapse
guy profile image
Guy

Thanks for the great post. I work on a legacy Drupal 7 site and my team is in the process of moving to 8 by next year. It's an arduous undertaking, and I'm still not quite up to speed with 8, but will take your notes on getting localization right out of the gate.

I do really like the standard serialization module in 8 for composing views in JSON.

Collapse
michaeldscherr profile image
Michael Scherr Author

I’m glad you found the post useful. Definitely a good call on figuring out localization first, we are still uncovering more hidden issues once we used SQL Statements to change the default language.

Interesting you mentioned the core serialization module; I started on D8 so I don’t know any of the downfalls of D7. I’m glad you’re finally making the switch.

Good luck with everything.