
In their simplest form layout plugins in Drupal Layout Builder define the part of the content output that can't be changed. For example a three column layout will consist of three equal columns every time an editor decides to use it as the layout section. The editor can place whatever they want into the three columns. But they can not change the overall layout. This restricts editorial capabilities of using layout plugins since in real life a three column layout may need to consist of a wider middle column and narrower side columns, allow for column headings, or other customizations.
This flexibility is accomplished by creating, and exposing, configuration options for layout plugins in Drupal's Layout Builder. In more advanced cases, we can take this flexibility further by exposing an interface editors to dynamically define layout plugins.
In this tutorial we'll:
- Learn how to use custom PHP classes in the layout plugin annotation
- Learn what annotations properties can be used for custom layout declaration
- Define the concept of derivatives and outline scenarios for using them
- How to declare static single layouts using YAML format
By the end of this tutorial you'll learn advanced ways of declaring configurable custom layout plugins.
Layout plugins can be dynamically generated based on configuration using plugin derivatives. This allows developers to provide Drupal site administrators with a UI for creating new layout plugins, or to automatically register layout plugins based on the environment.
This is useful in situations where it's not enough to define a set of pre-configured layouts to use in the Layout Builder. Instead, you need to empower editors to declare their own new layout plugins without writing any code. Derivatives could also be used in scenarios where the layouts that should be made available depend on configuration set elsewhere in the module. Or, you might have a scenario where you want to have multiple different 2-column layouts, and for those layouts to have different names, so that they can be themed differently depending on which one is used.
In this tutorial we'll:
- Create a user interface that allows editors to dynamically define layouts via configuration.
- Learn how to set up a plugin deriver that creates layout plugins based on configuration.
- Create custom dynamic layout plugins with variable numbers of columns.
By the end of this tutorial you'll know how to declare dynamic custom layout plugins using derivatives.
When defining new layout plugins for Drupal you can add custom CSS and JavaScript via asset libraries. This allows for the creation of layouts with complex structures and interactive elements. Those elements might include grids, tabs, and accordions. Drupal allows you to attach custom CSS and JavaScript directly to a layout plugin, or via the layout's Twig template file.
In this tutorial we'll:
- Define a custom asset library with JavaScript and CSS functionality
- Attach the asset library to the custom layout plugin
- Transform a multicolumn layout into tabs
By the end of this tutorial you should know how to attach custom CSS and JavaScript to a layout plugin to add interactivity and styling.
When building a site using Drupal's Layout Builder, it's a good idea to keep the number of layout plugins manageable. In many cases it's better to create a single layout plugin that can be re-used rather than duplicate a layout multiple times to accommodate minor variations. One way to do this is to provide editors with configuration options that will change the output when a layout is used.
For example, imagine you need to provide variations of a 3-column layout where the columns are different widths. You could define a new layout for each variation. Or you could define a single layout with a configuration option that allows a user to choose the column widths. The latter approach reduces code duplication, and makes the codebase easier to maintain.
In this tutorial we'll:
- Learn how to declare advance layout plugins with configurable settings in the Drupal Layout Builder
- Extend the
LayoutDefault
class and create a custom settings form that editors will see when using a layout - Use the provided configuration values in the layout's Twig template file to modify the layout when it is rendered
By the end of this tutorial you should be able to expose layout-related settings to editors, allowing for more flexibility in custom layout plugins.
Drupal site administrators can create new media entity types, with their own unique configurations and sets of associated fields. Different media types can be configured with different field names, permissions, moderation workflows, and display settings, making it possible to create truly custom content administration experiences. The process is similar to creating a node content type like articles or events with one major distinction: every media type inherits from a specific media source plugin. The source plugin provides domain-specific knowledge about the kind of resource being represented. For example, the Remote video source plugin used with the default Remote video media type knows how to consume and display videos from YouTube and Vimeo given only their URL.
Drupal core comes with a couple of common media source plugins, and contributed modules and custom code can add to this list, increasing the different media providers with which Drupal can integrate.
In this tutorial we'll learn how to:
- Install a contributed module that provides a new media source plugin.
- Create a new media type.
By the end of this tutorial you should be able to explain how source plugins relate to media types, and create a new media type.
The Drupal Media Library and Media ecosystem can be integrated with any third-party media provider by defining new media source plugins. Media types (Media entity bundles) have an important distinction compared to other content entity types like nodes. Every media type inherits from a specific media source plugin. The source plugin provides domain-specific knowledge about the kind of resource being represented. For example, media types dealing with images know how to validate file extensions and render <img>
tags. Media types dealing with remotely hosted videos might know how to retrieve thumbnails from a remote API, and display an HTML video player and transcript.
In this tutorial we'll learn how to:
- Define a new source plugin
- Integrate a third-party API via its existing PHP library
By the end of this tutorial you should be able to create a new source plugin that exposes any third-party media resources you want to integrate with Drupal.
If the Media assets you want to use in your library support oEmbed, then you might be able to use them with a minimal custom code. Before you go down the path of creating a custom media source plugin try this approach first.
oEmbed is a standard way of allowing third party sites to embed an asset represented by a URL. The Remote Video source in core uses the oEmbed features of YouTube and Vimeo. When you paste a link into a Slack channel, and it displays a pretty card preview, or an embedded video or Spotify playlist, that's oEmbed in action. Does the Media you want to embed have a canonical URL? If so, paste it into the tool here and see if it displays oEmbed info in the results.
In this tutorial we'll:
- Learn how to enable additional oEmbed providers as Media sources
- Use the contributed oEmbed Providers module for compatible providers
- Demonstrate how to create a custom oEmbed media source plugin to further customize the results
By the end of this tutorial you should be able to embed any oEmbed-compatible content as Media assets in Drupal.
Want to know if the person that's viewing your custom block is authenticated? Need to change the elements visible on the page based on a user's permissions or roles? Want to display a welcome message for users returning to your site?
All of these things require knowing who the user is that's currently accessing a page. This can be accomplished by using the current_user
service to load an object that contains information about the current user as well as methods for checking permissions, and retrieving additional information.
In this tutorial we'll:
- Define what "current user" means
- Use the
current_user
service to retrieve an implementation of\Drupal\Core\Session\AccountInterface
- Retrieve information about, and check the permissions of, the current user
By the end of this tutorial you should be able to retrieve and make use of information about the applications current user in order to perform logic in your code that customizes the response for different users.
React is a JavaScript library that makes it easy to create interactive user interfaces. Drupal is a content management system with a powerful web services API. React and Drupal can work together in a couple of different ways. This series of tutorials explores some of those options, and the related concepts and terminology.
Our goal is to provide you with some baseline information you can use to get started integrating React and Drupal together. After you've completed these tutorials you should be able to better envision how to use these two technologies to solve some of your own issues. We hope you'll come away from this with enough knowledge to start exploring further on your own. We link to external resources liberally, and encourage you to explore beyond the examples we provide, read the linked resource, and dig in. There's no substitute for exploration and experimenting with real code when it comes to learning these things.
In this series we'll:
- Introduce the technical side of React, terminology, and information about where to find more resources
- Learn about using Drupal, and the JSON:API module, to turn Drupal into a powerful web services API provider
- Learn about the use cases for adding React to a Drupal site
- Walk through increasingly complex code examples that start with a "Hello World!" application, and end with a fully decoupled application that can list, create, update, and delete content in Drupal
- Learn about how to authenticate a Drupal user via an API using React
- Contrast, through example code and use cases, the differences between integrating React into an existing Drupal theme or module and creating a stand-alone React application
- And more!
Before we start writing any React code, let's go over some basic concepts and terminology. Throughout this series we'll assume you're familiar with these things. They'll come up again and again as you work on projects that involve React, so it's worth taking the time to learn them.
In this tutorial we'll cover the following at a high level, and provide links to resources:
- Why choose React?
- What are React components?
- What are hooks, state, and JSX?
- The role of build tools when developing React applications
By the end of this tutorial you should have a firm grasp of the fundamental concepts and terminology necessary to start creating React applications.
React and Drupal can be used together in two different ways: fully decoupled, also known as headless; or progressively decoupled.
In this tutorial we'll talk about the differences between these two approaches, including:
- Defining what each method refers to
- Considerations regarding hosting, performance, and access
Then we'll link to lots of additional reading materials so you can gain a deeper understanding of the subject.
By the end of this tutorial you should be able to define what decoupled and progressively decoupled mean, and how they differ from one another.
Writing a React application requires including the React JavaScript library in the page, writing some React-specific JavaScript, and then binding it to a specific DOM element on the page. You may also want to include existing packages from the npm ecosystem, and use modern JavaScript (ES6+) features, which necessitates setting up a build toolchain for your JavaScript using a tool like Webpack or Parcel.
There are a lot of different ways you could go about setting this all up. Do you add React via a theme or a module? Do you need a build tool? Should you use Webpack, or Babel, or Parcel, or something else? While we can't possibly cover all the different approaches, we can help you figure out what is required, and you can adapt our suggestions to meet your needs.
In this tutorial we'll:
- Create a new custom theme with the required build tools to develop React applications
- Add a DOM element for our React application to bind to
- Create a "Hello, World" React component to verify everything is working
By the end of this tutorial you'll know how to configure everything necessary to start writing React within a Drupal theme.
Components are the fundamental building blocks of any React application. React uses components to represent different elements in the UI. To show this, we'll build a React widget that can query the Drupal.org REST API to retrieve usage statistics for a project and then display them. We'll create buttons that allow us to toggle between two different projects. In doing so we'll learn about creating components and using props and state in React.
In this tutorial we'll:
- Define two new React components
- Learn about using props to pass data to a component
- Learn about using state, and the
useState()
hook, to create interactivity
By the end of this tutorial you should have a basic understanding of how to write a React component that uses props and state to display data from a third party API.
React excels at displaying lists of data. But that data needs to come from somewhere. In most cases this happens by making a network request to retrieve data from one or more APIs, processing the response, and then displaying the data. In the context of working with a Drupal site there are two possible options: Drupal core's JSON API module, or the drupalSettings
JavaScript API.
In this tutorial we'll focus on the high-level overview and:
- Explain the difference between content and configuration data
- Introduce the JavaScript Fetch API, and where to find information about using it
- Get an overview of the ES6 array functions we'll use to parse the complex data structures returned from an API
In the remaining tutorials in this series we'll provide examples of real world use cases.
By the end of this tutorial you should have a firm understanding of how to get started making API requests using React.
In order for our React code to list content from Drupal we'll need to enable the Drupal core JSON:API module, and then use fetch()
in our React component to retrieve the desired data. This technique works for both React code embedded in a Drupal theme or module, and React code that is part of a fully decoupled application. We'll discuss the differences between those styles as well.
In this tutorial we'll:
- Use
fetch()
to bring data from Drupal into React - Parse the data using ES6 array functions to find just the bits of data we need
- Combine multiple React components together to render a list of articles retrieved from Drupal
By the end of this tutorial, you should have a better understanding of how data from a Drupal API gets incorporated into a React application.
To perform create, update, and delete (CRUD) operations with Drupal core's JSON:API via React there are a few things you'll need to understand. First, how to format the POST
, PATCH
, and DELETE
requests necessary to add, edit, and delete Drupal entities. Next, how to handle authentication, and cross-site request forgery (CSRF) tokens. Over the next few tutorials we will create a simple but powerful React application that can add, edit, and delete Drupal node content.
This tutorial contains:
- An overview of the application we're building
- Information about making secure authenticated requests to Drupal's JSON:API
- An overview of the API requests we'll use to create, update, and delete nodes
By the end of this tutorial, you should have a picture of the application we're going to build, and know how to make the API requests we'll use in our application.
Using React we can do more than just list content. By using the POST, PATCH, and PUT methods of Drupal core's JSON:API web service we can also add, update, and delete, content entities. To demonstrate how this works we'll create a small React application with a form that lets you add, edit, and delete article nodes.
In this tutorial we'll:
- Learn how to handle user authentication and CSRF tokens in a React application
- Create a single React component that outputs a form to add or edit content
- Create a wrapper around the JavaScript
fetch
API to assist in dealing with requests to Drupal's JSON:API
By the end of this tutorial you should know how to create, edit, and delete content in a Drupal site using a React application.
Now that we know how to build a working application in React and embed the application in Drupal, let's make a stand-alone version of our application which can be used outside of the context of a Drupal module or theme. In the next few tutorials we'll look at how to create a fully decoupled React application whose only interactions with Drupal happen via API requests.
In this tutorial we'll:
- Introduce differences we need to account for in a fully decoupled application
- Provide an example of what the final project will look like
By the end of this tutorial you should have a better understanding of what we're trying to create in the rest of this series.
Using create-react-app we can scaffold a stand-alone React application with boilerplate configuration and organization already in place. It's a great way to get started using React, as well as the ecosystem of associated tools like Webpack, Jest, and Babel. After creating the scaffolding, we'll port the code we wrote in previous tutorials to the new structure.
In this tutorial we'll:
- Use
create-react-app
to scaffold a new React project - Refactor existing code into the organizational structure used by
create-react-app
- Confirm that our code runs
By the end of this tutorial, you should know what create-react-app
is and how to get started using it.
When you create a fully decoupled application, the code in your application can't rely on things like the fetch()
function's same-origin
policy and the browser's use of cookies to authenticate requests. Instead, you need to use alternative methods like OAuth or JSON Web Tokens (JWTs).
We'll focus on setting up and using Drupal as an OAuth provider, and allowing a decoupled application to authenticate users via OAuth. This same technique applies just as well if you want to use JWTs.
In this tutorial we'll:
- Install the Simple OAuth Drupal module, and configure it to work with a password grant flow to allow our code to exchange a username and password for an access token
- Demonstrate how to retrieve and use an OAuth access token to make authenticated requests
By the end of this tutorial you should know how to install and configure the Simple OAuth module and make authenticated API requests using an OAuth password grant flow.