If you want to create a link to an internal page in a Twig template--and there's not already a variable in the template that contains the URL you want to link to--you'll need to determine the route of the thing you want to link to and then use the Twig url()
or path()
functions to generate appropriate URLs. In most cases when you want to create a link to an entity that is being output by the current template there's an existing helper variable to use. For example, in a node.html.twig template file there's a url
variable that points to the current node. For other scenarios, like hard-coding a link to the /about page, you'll need to do a little more work.
In this tutorial, we'll:
- Get the absolute URL value
- Get the relative path value
- Generate HTML for a link
- Get the URI to a file, like an image in the Media library
- Get the active theme path
By the end of this tutorial you should be able to create links to any internal page via Twig.
Do you cringe at the sight of untidy whitespace or (gasp) no whitespace at all when you View Source? Learn how to tame whitespace in Twig template files in this tutorial. By the end of this lesson, you will be able to recognize how Twig controls whitespace and how you can do the same in your Drupal template files.
Media source plugins provide the link between media entities in Drupal and the actual media asset itself. They are the code that understand the difference between an image, a video, and a Tweet, and perform the translation that allows the media ecosystem to treat all media entities equally. For example, local image files, and remote YouTube videos, can both be catalogued in a similar way as media entities, but they need very different handling when it comes to displaying them.
Media sources are represented as plugins, there are a handful in Drupal core, and a developer can add new plugins to represent any type of media your application needs to catalogue.
In this tutorial we'll learn:
- How media source plugins relate to Media Types
- The responsibilities of a media source plugin
By the end of this tutorial you should be able to define the role of a media source plugin and understand what's required to define your own.
The Drupal core Media Library module provides an enhanced user interface for locating Media entities and attaching them to an article. It's a drop-in replacement for the default entity reference widget which uses a not very intuitive autocomplete field. Using the Drupal core Media Library module requires minimal configuration.
If you want to provide content creators with a gallery-like library of Media entities that they can browse through in order to find the ones they want to add to their content, the Media Library is the easiest way to do it. It can be configured to work with both Media fields and the CKEditor powered WYSIWYG editor commonly used for editing the body field of Drupal nodes. There's really no reason not to use it.
In addition to providing a better UI for locating existing Media entities, the Media Library provides a way to create new Media entities right from the content creation form. This prevents an otherwise confusing requirement where Media entities need to be created, via a different set of forms, before they can be used.
In this tutorial we'll:
- Install and configure the Media Library module to work with Media fields
- Use the user interface provided by the Media Library to improve the experience of finding and selecting Media entities to associate with a piece of content
By the end of this tutorial you'll know how to replace the default entity reference widget used for selecting Media entities with the much improved Media Library UI.
Media entities, like any content entity, work great with all the different features Drupal provides for changing the way things are displayed: view modes, Layout Builder, theme templates, and more. We're big fans of using view modes to create a component-like design system where entity types have view modes representing the different context in which they're displayed. Then we theme the view modes. This works great for displaying Media entities associated with a page and for changing the way that Media assets are displayed within the Media Library browser.
In this tutorial we'll:
- Create Hero and Sidebar view modes for Media entities
- Configure the Image Media type to use the new view modes and style each one differently
- Use the new view modes to render Image Media assets within a Layout
- Update the Media library view mode that's used by the Media Library browser to display additional information alongside the thumbnails used when selecting Media to attach to a page
By the end of this tutorial you should be able to change the way that Media assets are displayed by using view modes and display formatters in a Drupal site.
Drupal core provides support for migrating data from Drupal 6 or 7. The templates provided in core migrate your data in a very specific way. They attempt to copy things verbatim whenever possible. However, you may wish to alter this for your migrations. In this tutorial we are going to explore the various ways that you can alter the existing Drupal-to-Drupal migrations to meet your needs.
One method of creating a custom Drupal-to-Drupal migration involves using the Migrate Upgrade module to generate a set of migration configuration entities that you can use as a starting point. Even if you're not going to use the generated output in the end, this is still an informative exercise as it allows you to see examples of various migration paths.
In this tutorial we'll:
- Use the Migrate Upgrade module's Drush commands to import Drupal core's migration templates
- Examine the generated configuration entities
- Use the Migrate Tools module's Drush commands to view a list of the individual migrations that make up our Drupal-to-Drupal migration
By the end of this tutorial, you should be able to use the Migrate Upgrade module to generate the migrations that Drupal core would use to migrate content, list those migrations, and inspect them individually.
If you want to modify the Drupal-to-Drupal migrations created by Migrate Upgrade you'll need to export the Migrate Plus configuration entities, convert the ones you want to customize to standard migration .yml files, and put them into a custom module. Then, you can make edits the YAML definition of the migration, and keep your customizations in Git.
We recommend creating a new module to house the code that makes up your custom Drupal-to-Drupal migration.
In this tutorial we'll:
- Create a new module
- Export the migration configuration entities generated by
drush migrate-upgrade
as YAML files - Copy the files that represent the migrations we're interested in into our new module
- Customize the copied files
By the end of this tutorial you should have a new module that contains the starting migration YAML files for your custom migration.
As part of creating a custom Drupal-to-Drupal migration we want to limit the set of users that are migrated from our source site into our destination Drupal site. In this tutorial we'll:
- Extend the existing source plugin
- Alter the query that's used to select users from our source site
- Update our user migration to use the new source plugin
By the end of this tutorial you should be able to override the core source plugins used when migrating from prior versions of Drupal in order to gain more control over exactly what is migrated.
Every row returned, from every source, during the execution of a migration is passed through hook_migrate_prepare_row()
and hook_migrate_MIGRATION_ID_prepare_row()
. Using these two hooks we can augment our migration in a variety of different ways.
In this tutorial we'll:
- Discuss the use case for
hook_migrate_prepare_row()
- Implement
hook_migrate_prepare_row()
and use it to skip all but a select list of fields during the field migration - Implement
hook_migrate_MIGRATION_ID_prepare_row()
and use it to skip all but a select list of node types
By the end of this tutorial you should have a better understanding of when hook_migrate_prepare_row()
might be useful when writing your own migration, as well as how to skip rows in a migration based on conditional logic.
Why use Migrate Upgrade and Migrate Plus? The short answer is: because it'll save you from having to type out a bunch of YAML by scaffolding a migration for you.
The contributed Migrate Plus and Migrate Upgrade modules are commonly used to aid in the process of performing a Drupal-to-Drupal migration. The combination of the two makes it easier to customize the configuration of individual migrations on a per-project basis by allowing you to edit each individual migrations configuration using the same mechanics that you would to write a custom migration.
It's not the only approach to making these changes, but for many people (including us), it's the most efficient way.
In this tutorial we'll:
- Get a more in-depth look at the role of the Migrate Plus and Migrate Upgrade modules
- Discuss the use cases for using them as part of a Drupal-to-Drupal migration
By the end of this tutorial you should be able to explain what both the Migrate Plus and Migrate Upgrade modules are used for.
As new major versions of Drupal are released, contributed modules need to be updated for compatibility. As of right now (October 2021) there are a lot of contributed modules with a Drupal 8 release and a patch in the queue to make them work with Drupal 9. However, there's no official Drupal 9 compatible release for the module, so the module can't be installed with Composer. This creates a circular problem where you can't composer require
the module if you don't patch it, but you can't patch it until after it's been downloaded by Composer.
To help solve this common issue, Drupal.org provides a lenient Composer endpoint that publishes all modules as compatible with Drupal 9 regardless of whether that's true or not. By using it, you can composer require
the module and then use cweagans/composer-patches
to apply any necessary patches.
In this tutorial we'll:
- Add the lenient Composer endpoint to our project's composer.json file
-
composer require
a non-Drupal 9 compatible module - Use Composer to download and apply a patch that makes the module Drupal 9 compatible
By the end of this tutorial you should be able to use contributed modules that require a patch to be compatible with Drupal 9.
Drupal 8.8.0 introduced a bunch of new features intended to make it easier over the long-term to maintain a Drupal project using Composer. In doing so it establishes some new best practices, and moves into Drupal core solutions that were previously maintained by the community. This is all good news. But, it means if you're using Composer to update from Drupal 8.7.x or lower to 8.8.0 or higher you'll need to do a bit of additional work to untangle everything.
This tutorial is especially useful if you started your Drupal project using the drupal-composer/drupal-project
template and would like to convert to use the new templates (i.e. drupal/recommended-project
or drupal/legacy-project
) included with Drupal 8.8.x core.
In this tutorial we'll:
- Convert our project to use the new
drupal/core-recommended
, anddrupal/core-dev
Composer packages - Explain which commonly used Composer packages are deprecated, and which new ones replace them
- Learn how to use the
drupal/core-composer-scaffold
Composer plugin - Cover tips for troubleshooting updates
Furthermore, in order to Upgrade to Drupal 9 from Drupal 8, you will first need to update your Drupal 8 site to at least version 8.8, as the upgrade paths for Drupal 8 site from before Drupal 8.8.0 have been removed from Drupal 9.
By the end of this tutorial you should be able to update your Drupal projects using Drupal core 8.7.x or lower to Drupal core 8.8.0 or higher using Composer. And be ready for an upgrade to Drupal 9.
Drupal's development has a regular release cycle consisting of major, minor, and patch releases. Drupal releases use semantic versioning for its version numbers. Since we're committed to making sure our tutorials are kept up-to-date with the latest and greatest version of Drupal we figured it would be a good idea if you knew how to keep your Drupal site up-to-date with the latest "point" releases as well.
This tutorial will cover:
- How to determine the type of update
- The standard update procedure
- Update Drupal using Drush
- Update Drupal using Composer
This tutorial won't cover:
- How to perform a major version Drupal upgrade, for example, from Drupal 6 or 7 to the latest version of Drupal. For that, see our guide, Learn to Migrate to Drupal.
Upgrade to Drupal 10
FreeThere’s no one-size-fits-all path to upgrade from Drupal 9 to Drupal 10, but there is a set of common tasks that everyone will need to complete.
In this tutorial we’ll:
- Explain the differences between Drupal 9 and Drupal 10 that affect the upgrade path.
- Walk through the high-level steps required to upgrade from Drupal 9 to Drupal 10.
- Provide resources to help you create an upgrade checklist and start checking items off the list.
By the end of this tutorial you should be able to explain the major differences between Drupal 9 and 10, audit your existing Drupal 9 projects for Drupal 10 readiness, estimate the level of effort involved, and start the process of upgrading.
Upgrade to Drupal 9
FreeThere’s no one-size-fits-all path to upgrade from Drupal 8 to Drupal 9, but there is a set of common tasks that everyone will need to complete.
In this tutorial we’ll:
- Explain the differences between Drupal 8 and Drupal 9 that affect the upgrade path.
- Walk through the high-level steps required to upgrade from Drupal 8 to Drupal 9.
- Provide resources to help you create an upgrade checklist and start checking items off the list.
By the end of this tutorial you should be able to explain the major differences between Drupal 8 and 9, audit your existing Drupal 8 projects for Drupal 9 readiness, estimate the level of effort involved, and start the process of upgrading.
Deprecated code is any code flagged for future removal, but which has not yet been removed to ensure that existing code which relies on the to-be-removed code will continue to work. When an API, or feature, becomes deprecated it's a warning to all developers that at some point in the future this thing they are relying on will not exist, and they'll need to update their custom code to a new approach. Preferably before the existing one gets removed.
In this tutorial well:
- Learn about why, and when, code is deprecated in Drupal
- How to identify custom code that is using deprecated features
- How to determine an appropriate upgrade path to the new API
By the end of this tutorial you should be able to explain what code deprecation is, and why it's important for Drupal's continue innovation, as well as how to update your own code when an API you rely on becomes deprecated.
Annotations are specially-formatted PHP docblock comments that are used for class discovery and metadata description. While it is technically possible to use annotations for other purposes, at the moment Drupal only uses them for the plugin system.
In this tutorial we'll look at:
- What annotations are
- The use case for annotations
- How to figure out what you can put into an annotation
By the end of this tutorial you should understand how annotations are used in Drupal and how to write them in your own code.
Many of the processes that Drupal performs when responding to a request are cached in order to increase performance. Creating the HTML for the page that a user sees or the JSON response to a REST request can require thousands of operations. Some operations are time consuming, memory heavy, CPU intense, or all 3. By performing the operation once, and then caching the result for next time, subsequent requests can be fulfilled faster. In order to make it easier to store, retrieve, and invalidate cached data, Drupal provides cache-related services you can use in your code. Drupal also enables you to provide information about the cacheability of data to the Render API to improve the performance of page rendering.
In this tutorial we'll:
- Cover the terms and concepts you should be familiar with when working with the Cache API
- Point to additional resources for more information about how to perform specific tasks with the Cache API
By the end of this tutorial, you should be able to define the concepts of bubbling and cache invalidation, and know how cache keys, tags, context, and max-age are used to provide cacheability metadata for items.
Some events are dispatched by Drupal core, some by underlying Symfony components, and some by contributed modules. The list of events that you can subscribe to depends on the modules you've got installed. This can make it tricky to get a complete list.
In this tutorial, we'll look at different ways you can get a complete list of the available events for your Drupal application, and where to find documentation for those events.