We need a place to put the custom PHP code for our /weather page. In Drupal, controllers encapsulate the custom PHP logic that generates the content of a page. A basic controller might output a hard-coded response, or perform a simple calculation in PHP. Complex controllers make database requests, query third-party APIs, and format complex data using injected services and custom PHP logic.
In this tutorial, we'll:
- Create a new controller class following the PSR-4 standard.
- Define the
Drupal\anytown\Controller\WeatherPage
class with abuild()
method that returns the page's content. - Verify that our route and controller are working.
By the end of this tutorial, you should be able to navigate to /weather in your browser and see the output from our custom controller.
Drupal allows site administrators to configure view modes, defining an entity's display. As module developers, we use view builders to transform an entity object into a renderable array, respecting site-specific configurations without hard-coding display details.
In this tutorial, we'll:
- Introduce view builders and explain their significance in entity rendering.
- Develop a route and controller for a new /attending page
- Use an entity query to retrieve vendor nodes and render them with view builders
By the end of this tutorial, you'll know how to display entities using a site-specific teaser view mode.
In Drupal, content entities can have fields. Field data is entered using widgets and displayed with formatters. The Field API provides developers with means to customize fields, widgets, and formatters. Which gives site builders tools to build flexible, extensible sites using customized data models.
In this tutorial, we'll:
- Learn what it means for an entity to be fieldable.
- Define what field types, widgets, and formatters are and give examples of each.
- Explore the differences between base fields and user-defined fields.
- Define the concept of field instances.
By the end of this tutorial you should be able to define the main components of the Field API and understand how developers leverage the Field API to alter and enhance Drupal.
Entities objects are loaded using the entity type manager service (technically, the entity storage manager). Field values are read from the entity object. Doing this, instead of directly accessing data in the database, ensures that our custom code can remain agnostic about any underlying data storage logic. Reading field values is a common task, and we'll practice it by loading a vendor entity and using existing field values to pre-populate the new vendor attendance form.
In this tutorial, we'll:
- Load an entity using the entity type manager service.
- Access raw values of entity fields.
- Use
#default_value
in Form API to pre-populate form fields.
By the end of this tutorial, you'll be able to get raw field values from entities.
Implementing plugins is a common task for Drupal developers. Often you'll need to add custom functionality using an existing plugin type--most likely an annotation-based plugin. This tutorial offers a structured approach to understanding and creating Drupal plugins, with a focus on annotation-based plugins.
In this tutorial, we'll:
- Examine the custom block code we previously wrote, this time from the perspective of the Plugin API.
- Introduce a recipe for creating annotation-based Drupal plugins.
- Demonstrate how to find the necessary information for new plugin creation from existing plugins.
By the end of this tutorial, you will know how to examine the structure of existing plugin classes, so that you know how to implement a plugin of that type.
Let's combine our knowledge of implementing hooks and hook_form_alter()
to customize a form built by another module, the user registration form. For the Anytown Farmer's Market site's user registration form, we want to introduce 2 new features: a mandatory "Accept terms of use" checkbox and custom validation to prevent registration with the username "anytown".
In this tutorial, we'll:
- Identify the form ID of the user registration form.
- Incorporate new elements into the user registration form.
- Implement additional validation logic.
By the end of this tutorial, you should be able to use hook_form_alter()
to customize any existing Drupal form.
Drupal uses 4 primary information types for canonical data storage: content, configuration, session, and state. Content encompasses the site's visible data, such as articles, images, and files. Content data are called content entities in Drupal. Configuration data stores site settings including site name, content types, and views. Session data tracks user interactions, including login status. State data holds temporary information like the last cron execution time.
In this tutorial, we'll:
- Define the 4 main information types and their use cases.
- Get a high-level overview of when module developers should expect to encounter each data type.
By the end of this tutorial you should be able to recognize each of the 4 main information types used in Drupal.
Plugins enable developers to extend and customize functionality through a modular and reusable system. Plugins allow for the creation of interchangeable components that can be managed dynamically at runtime. This tutorial introduces the core concepts of Drupal's Plugin API, including how plugins, such as blocks, are defined, discovered, and used within the system.
In this tutorial, we'll:
- Define plugins in Drupal's context.
- Explain the Plugin system's operation, including types, managers, discovery, and factories.
- Discuss the role of plugins in extending Drupal.
By the end of this tutorial, you should have a high-level understanding of plugins and the Plugin API in Drupal.
Drupal's Entity API enables us to define custom content entity types. It provides a structured approach to store custom data. Creating a custom entity makes sense when built-in entity types like nodes or taxonomy terms don't meet the specific requirements of a project. Custom entities allow for custom data structures, and use Drupal's core features such as access control, Views integration, and JSON:API support. Using the Entity API to create custom content entities ensures your custom data will be compatible with other Drupal modules.
In this tutorial, we'll:
- Discuss use cases for custom content entities.
- Get a high-level overview of defining a custom entity type.
- Provide additional resources where you can learn more about defining custom entity types.
By the end of this tutorial, you'll understand the use case for custom content entities and how to begin defining one.
Customizing the available regions in your theme is one of the first things you'll do when creating your own themes. Doing so gives you complete control over where content is displayed on the page, and the markup involved. Adding regions to a theme is a two-step process that involves editing your theme's THEMENAME.info.yml file and updating your page.html.twig file.
In this tutorial we'll:
- Declare one or more new regions in our themes THEMENAME.info.yml file.
- Output the content of those regions in our theme via the page.html.twig file.
By the end of this tutorial you should be able to add or edit the regions a theme provides. Also, you'll ensure that blocks placed into regions are displayed by outputting the regions in the page template.
Contributed and custom themes can ship with a thumbnail screenshot that will be used to represent the theme when listing themes in the administration UI.
In this tutorial you'll learn how to:
- Prepare your site for the screenshot
- Create a screenshot of your theme
- Define a screenshot file for your theme in the THEMENAME.info.yml file
Preprocess functions are specially-named functions that can be used to add new variables to a Twig template file. They are commonly used by themes to add new variables based on custom PHP logic and simplify accessing the data contained in complex entity structures. For example: adding a variable to all node.html.twig template files that contains the combined content a couple of specific fields under a meaningful name like {{ call_to_action }}
. Modules use preprocess functions to expose the dynamic data they manage to Twig template files, or to alter data provided by another module based on custom logic.
In this tutorial we'll learn how to:
- Use PHP to perform some complex logic in our theme.
- Store the resulting calculation in a variable.
- Make that variable available to a Twig template file.
Example use cases for adding variables with preprocess functions include:
- Anytime calculating the value to output in a template requires logic more complex than an if/else statement.
- Anytime the desired value requires additional string manipulation beyond what can be easily accomplished using an existing Twig filter or function.
By the end of this tutorial you should be able to expose new variables to a Twig template file by defining a preprocess function in either a module or a theme.
Twig has a special syntax for accessing array keys and objects, also known in Twig as variable attributes. In this tutorial, we'll cover the period or dot (.
) operator to access a variable attribute, as well as subscript or square-bracket syntax, useful for when the key of the array contains special characters, like a dash (-
) or pound sign (#
). We'll also look at the logic Twig uses to find the matching attribute in an array or object.
Once you've defined an asset library you'll need to tell Drupal when you want to add the CSS and JavaScript that it includes to the page. Ideally you'll do so in a way that allows Drupal to only add the corresponding assets on pages where they are needed.
You can attach a library to all pages, a subset of pages, or to elements in a render array. This allows you to have some assets that are global, and others that get loaded on an as-needed basis. To attach a library you'll need to know both its name and prefix, and then use one of the techniques outlined below to let Drupal know when to include it.
In this tutorial, we'll look at attaching asset libraries:
- Globally, via your THEMENAME.info.yml file
- Conditionally, via a preprocess function using the
#attached
render array property - Inside of a Twig template file
By the end of this tutorial you should be able to attach asset libraries in various different ways depending on your use case.
It's probably not too surprising that a library called Backbone aims to provide structure to your front-end JavaScript code and applications. In this tutorial we'll take a look at how Backbone.js goes about achieving that goal, and how you can make use of it on your Drupal site. We'll first take a high-level look at the main components that make up the Backbone.js library. With that basic understanding in place we'll look at an example of how you might integrate Backbone.js into a Drupal site.
Drupal's Breakpoint module defines a "breakpoint" plugin type that modules or themes can implement via a breakpoints configuration file. So, in order to make their breakpoints discoverable, themes and modules define their breakpoints in a THEME-OR-MODULE.breakpoints.yml file located in the root of their directory.
In this tutorial, you'll learn about the structure of a breakpoints configuration file and why you would want to use one. We’ll cover the kinds of metadata you can include in a breakpoint file, including key, label, mediaQuery, weight, multipliers, and breakpoint group. Throughout, we'll look at some examples of breakpoint configuration files available in Drupal themes and modules.
You've got a slick responsive theme for your Drupal site that's been implemented in CSS using media queries. But the content and images on your site will regularly be updated and you want to use the Responsive Images module to create responsive image style field formatters that you can apply to image field display settings.
In this lesson, we'll review the concepts of breakpoints and media queries so that you can better understand what's going on when you encounter them in non-CSS file contexts like configuration forms for responsive image styles or breakpoint YAML files.
By the end of this tutorial, you should have an understanding of what breakpoints are, how they are expressed in media queries, and how they are relevant in the context of Drupal.
Some, but not all, themes come with administrator-configurable settings that you can change through the UI. These might allow you to upload your own logo, choose between a couple of different pre-defined layouts, or turn features of a theme on or off. In this tutorial we’ll look at where you can find these theme settings if they exist, and how to go about changing them.
Preprocess functions are specially-named PHP functions that allow themes and modules to modify the variables passed to a Twig template file. They are commonly used by themes to alter existing variables before they are passed to the relevant template files. For example; Changing the makeup of render array so that it renders an <ol>
list instead of a <ul>
list. Or appending data to the label of a node depending on custom logic.
In this tutorial we'll:
- Define a new preprocess function in our theme's .theme file
- Use the preprocess functions to modify the content of an existing variable before it's used in Twig
By the end of this tutorial you should be able to define new preprocess functions in a theme (or module) that manipulate the variables for a specific Twig template file.
Theme developers often need to add or remove classes and other attributes from an HTML tag. Template files handle this with a special Attributes object that contains the attributes and their values, as well as a handful of powerful methods to help manage these attributes.
In this tutorial we’ll cover:
- Adding/removing classes from elements in a Twig template
- The attributes object
- Examples of common tasks using various helper methods on the attributes object