The Render API is capable of detecting poorly-cacheable (highly dynamic) parts of a page and rendering them later using a process called auto-placeholdering. This works by using #lazy_builder
callbacks to lazy load certain very dynamic subtrees of a render array. The place in the array where that very dynamic content would appear is first assigned a placeholder. At the very last moment it is replaced with the actual content.
This allows Drupal to do things like cache the overall page in the Dynamic Page Cache despite parts of the page being too dynamic to be worth caching. It also allows the Render API to assemble a page using cache fragments combined with non-cacheable elements.
In this tutorial we'll:
- Discuss what lazy builders are and how they work in conjunction with placeholders to speed up the rendering pipeline
- Cover some common gotchas for lazy builders
- Look at some example code that implements a lazy builder callback
By the end of this tutorial, you should know how and when to use the #lazy_builder
property of a render array and how Drupal uses placeholders to increase the cacheability of content and speed up the rendering process.
Linking to things is probably one of the first things you learned how to do as a web developer. Anchor tags are the framework of how the world wide web works. So it's important to know how to create them in Drupal. Chances are you'll be doing a lot of it.
Creating links to things in Drupal, however, is a bit more complicated than just typing out an HTML anchor tag. It requires understanding how URLs are generated from routes, and how to define links as renderable arrays. It can also be tricky because of the multitude of deprecated, but still functioning, ways of creating links.
In this tutorial we'll:
- Use the
\Drupal\Core\Url
class to generate URL objects from routes and external URIs. - Use the
\Drupal\Core\Link
class to create HTML links within a Drupal module. - Examine best practices for working with URLs and links in a Drupal module in order to ensure that your code continues to work into the future.
By the end of this tutorial you should be able to link to anything, either internal to your application or external, using Drupal best practices.
Modules can provide new render element types -- a powerful way to encapsulate complex logic into a reusable component. This can help to cut down on code repetition, and allow other module developers to build on your work. In this tutorial we'll:
- Define a recipe for creating a new render element type
- Look at the code for the marquee element type from the render_example module in the Examples for Developers project.
By the end of this tutorial you should be able to implement a new render element type in your own module and make use of it when defining content as part of a render array.
Strings of simple HTML and plain text can be defined in a render array using the #markup
and #plain_text
element types. In this tutorial we'll look at:
- Adding simple strings to a render array so they appear as HTML on the page
- When to use
#markup
and#plain_text
in your code
By the end of this tutorial, you should be able to add simple strings of HTML and plain text to a render array.
#prefix
and #suffix
are two commonly used examples of standard properties. That is, they are available for use on any element in a render array regardless of the element #type
or #theme
property's value. They are a great way to add additional layout markup to an element in a theme-agnostic way.
In this tutorial we'll:
- Use the
#prefix
and#suffix
Render API properties to wrap an element - Look at some possible use cases for using
#prefix
and#suffix
in your own code
By the end of this tutorial you should know how, and when, to use the #prefix
and #suffix
properties in a render array.
Renderers are the services that take a render array and convert it to HTML (or JSON, or any other format). As a module developer, understanding how they work will help you gain a better understanding of what happens behind the scenes when Drupal links an incoming request to your custom controller and then handles the data you return.
In this tutorial we'll:
- Define renderers
- List the renderers available in Drupal core
- Demonstrate how you can create a link that forces the use of a different renderer
By the end of this tutorial, you should understand the role that renderers play in the Drupal render pipeline and when you might want to use one other than the default.
Render API Overview
FreeThe Render API consists of two parts: structured arrays that provide data and hints about how that data should be rendered, and a rendering pipeline that can be used to render these arrays into various output formats. Understanding at least the basics of how the Render API works, the difference between elements and properties, and the concept of callback functions is an integral part of learning Drupal.
In this tutorial we'll:
- Look at the fundamentals of the Drupal Render API
- Point to additional material to provide more detail about the inner workings of the Render API and how content is output in Drupal
The core structure of Drupal's Render API is the render array, which is a hierarchical associative array containing data to be rendered and properties describing how the data should be rendered. As a module developer you'll use render arrays to describe the content your module controls in order to output it on a page as HTML, or as part of a response in another format like JSON. As a theme developer, you'll manipulate render arrays in order to affect the way content is output on the page.
In this tutorial we'll learn:
- What render arrays are and why they exist
- The basic format of a render array
- What "properties" and "elements" signify in the context of a render array
- Where to find more information about how to create a render array to describe your own content
By the end of this tutorial you should be able to understand when you need to use a render array, recognize one when you see it, and know where to get more detailed information about render array formatting specifics.
The individual items that make up the content of a page impact the cacheability of that page. In order for Drupal's cache and external caches to better understand how the content varies on a page, module developers use the #cache
render element property. The #cache
property defines cacheability metadata for individual elements in a render array.
Additionally, these Render API elements can become fairly complex. The calculation of what the final HTML output should look like often involves looking up content in the database, checking multiple conditions, maybe querying an external API, and various other tasks. This can cause turning a render array into HTML to become quite expensive. In order to speed up this process, the Render API will cache the generated HTML for each element and reuse it on future requests whenever possible -- but only if you tell it to do so.
In this tutorial, we'll look at:
- How render caching impacts the performance of a page
- Defining the cacheability of an item with cache tags, cache contexts, and cache max-age
- Examples of using the
#cache
property in a render array
By the end of this tutorial you should know how, and when, to use the #cache
property when defining render arrays.
One of the central components of Drupal's Render API is render elements. You can think of them as prepackaged render arrays or shortcuts you can use to describe common things, like tables, links, and form elements, in a consistent way. In this tutorial we'll take a more in-depth look at the use of the #type
property in render arrays in order to answer questions like:
- What are render elements, and what is their use case?
- Where can I find more information about available element types?
By the end of this tutorial you should be able to identify individual render element types within a larger render array, find the relevant documentation for specific types of render elements, and explain the use case for render elements.
This tutorial looks at the steps that Drupal goes through to obtain a render array for an incoming HTTP request, transform the render array into HTML, and then return it to your browser. We provide an outline of the process and links to resources for more in-depth information. We also take a more thorough look at the HtmlRenderer
which converts a render array into HTML. Knowing how the render arrays you write in your code are ultimately used can help you optimize Drupal's Render API to describe your module's content.
The #table
render element type is a powerful way to output an array of rows and columns as an HTML table. It supports all the features of a standard HTML <table>
element like headers, captions, and column groups. Data to be displayed in the table can be an array of simple string values, or an array of render arrays where each sub element is a row with columns as child elements. In addition, when used in the context of a form, tables can be made into a multiple select widget, or have drag-and-drop reordering of rows enabled. Whether you just want to display a set of tabular data, or you provide your users with a complex form element for reordering and nesting items inside a menu tree, it can all be done with the #table
element.
In this tutorial we'll:
- Look at outputting simple strings as a table
- Provide definitions for all the various properties that can be used to define a table element
- Demonstrate how to use the
#tableselect
and#tabledrag
options to create complex form widgets
By the end of this tutorial you should be able to create HTML tables in all their various permutations as part of a render array.
In this tutorial we'll look at how you can use the #theme
property of a render array to define custom HTML. With this information, module developers can use render arrays to define content, and theme developers can understand how elements in a render array are converted to HTML and which templates they can override to change the output for a specific element.
Learn how to:
- Use
hook_theme()
to define a new theme hook and define default values for variables - Create a corresponding Twig template file that outputs the variables and any custom HTML markup
- Use a preprocess function to add additional variables for the Twig template file you created
- Use the new theme hook in conjunction with a
#theme
property in a render array to link your Twig template file to actual content
By the end of this tutorial you should know how to define new templates to output content as HTML. You should also have a better understanding of how Twig template files are linked to elements in a render array.
There are a bunch of existing render elements, most commonly Form API elements. You need to know how to discover and make use of existing elements. In this tutorial, we'll learn how to:
- Locate a list of elements provided by Drupal core
- Figure out what properties apply to each element
- Use any render element type when defining content or forms in our code
By the end of this tutorial you should know what render element types are available for you to use, and how to find the details you'll need in order to implement them in your own render arrays.
It's best practice to access any of the services provided by Drupal via the service container to ensure the decoupled nature of these systems is respected. In order to do so, you need to know what services exists, and then, where possible, use dependency injection to use them in your code.
This tutorial walks through the process of:
- Discovering existing services and learn their machine name
- Using the machine name of service to request a copy from the service container
When you are implementing an HTTP API for a decoupled project, one of the critical, but often overlooked, aspects is the API documentation. Documenting your API will allow front-end developers (and you six months from now) to learn how to use that particular API.
In Drupal, there are several modules that can read your site configuration and generate documentation for you automatically.
In this tutorial we're going to:
- Learn about the importance of good documentation.
- Decide whether or not to use an existing specification for our API such as JSON:API or GraphQL.
- Review options for automatically generating documentation.
By the end of this tutorial you'll be able to decide whether or not using an existing documentation specification is a good fit for your project, and choose an option based on those available for use with Drupal.
JSON:API includes a way to request a list of entities of a given resource from the server. Collections are the best way to find content based on filters, and to build listings into the consumers. Moreover, collections can be combined with all the options you can apply to a single resource, like sparse fieldsets and includes.
In this tutorial we'll:
- Learn about what collections are in JSON:API
- Learn how to request, sort, and paginate lists of content
By the end of this tutorial you should know how to retrieve a list of resources from the JSON:API server, and how to optionally sort and paginate the items in the list.
Often, web services require the user to create content. Votes on content, ratings, comments, and user-submitted stories are good examples of this. The JSON:API module supports the creation of entities by sending data in POST requests.
In this tutorial we will:
- Add an appropriate set of HTTP headers to a request that generates a new entity
- Construct a JSON object for the entity we want to create
- Issue a POST request that creates a new article node in Drupal
By the end of this tutorial you should be able to create a POST request that creates a new entity of any type via the JSON:API.
Sometimes unexpected things happen and Drupal needs to generate an error. The JSON:API specification describes how the server should return those errors. Understanding what to expect allows consumers to plan for errors and react gracefully.
In this tutorial we will:
- Discuss how HTTP errors are used in conjunction with JSON:API
- Learn about how JSON:API embeds information about the error encountered into the response object
By the end of this tutorial, you should have a basic understanding of the types of errors you can expect to receive when making JSON:API requests and what you can do to handle them.
Collections are a very powerful feature because they allow us to access multiple items at the same time. However, in many situations we do not want to access all the entities of a given type, but only the ones that meet some specific criteria. In order to reduce the set of entities in the collection to the ones we care about, we use filters.
In this tutorial we will:
- Look at the
filter
query string parameter and how it can be used with JSON:API collections - Learn how to use filters in combination with the JSON:API module for Drupal to reduce the list of entities in a collection
By the end of this tutorial you should be able to request a list of entities in the form of a JSON:API collection and filter that list to include only the entities that match a specific set of requirements.