Our products are printing out a bit weird right now because they’re floating, but not breaking correctly. To fix this, we need to wrap every three products in their very own row. In this tutorial, you will use a "divisibleby" test to see if the item number we’re on is divisible by three, and then loop through them. We'll also clean up our if
statement for our background color, by implementing an inline if
syntax.
In this tutorial we're going to purposely make some common Twig mistakes, debug them, and figure out how to fix them. We'll also look at a way to make parts of your Twig code easily reusable, using macros.
Twig: The Basics
FreeTwig is a templating language for PHP, which is a boring way of saying that it’s a tool used to output variables inside HTML. In this series we'll show you how to use Twig from the ground up, clearly pointing out its syntax, and then graduating to some really neat and advanced tricks. We'll start with a look at Twig syntaxes, functions and filters. Then we'll get into the world of debugging with the dump()
function. With the basics under control, we'll move to handling arrays and objects. template inheritance, tests, looping tricks, and macros (Twig functions).
To make this interesting, we're going to build something useful with Twig, like a penguin clothing store! We're starting out with a small website set up under your web server’s document root and a test page called test.php, which you can find in the series demo site download. In this lesson, you will create your first Twig template, render a variable, and learn the basic Twig syntax you'll need to know.
Additional resources
Twig Templating
CourseSet up a local development environment to practice Drupal theme development. In order to practice theme development, either on your own or following our Hands-On: Theming guide, you'll need a Drupal site up and running on your computer.
By the end of this tutorial, you should be able to:
- Install Drupal on your computer so you can modify files with a code editor of your choice.
- Generate dummy content so that you have different kinds of pages to theme.
It's time to create the bare-bones structure for a new theme on your site. You should try to complete this exercise based on the information you've learned in this chapter. The video included will walk you through the implementation of this exercise if you need some help. In this exercise you will need to:
- Create an info file that describes a custom theme to Drupal with the regions listed below (we're going to name ours "reboot").
- Enable, and view, a bare-bones custom theme.
Regions:
'Header' (header)
'Primary menu' (primary_menu)
'Secondary menu' (secondary_menu)
'Page top' (page_top)
'Page bottom' (page_bottom)
'Highlighted' (highlighted)
'Featured top' (featured_top)
'Breadcrumb' (breadcrumb)
'Content' (content)
'Sidebar first' (sidebar_first)
'Sidebar second' (sidebar_second)
'Footer first' (footer_first)
'Footer second' (footer_second)
Note: At the end of this exercise, you'll find a video walk-through of the solution.
You can accomplish a lot without needing to change any markup by adding CSS and JavaScript files to your theme. In this exercise you'll create 2 asset libraries and add them to your theme. Specifically, we want to pull in the CSS and JavaScript from the popular Bootstrap framework so that we can make use of its layout utility classes later on. We'll also add a custom CSS file that contains global styles for our site, like setting the page background color.
If you want to try and complete this on your own first you'll need to:
- Add the Bootstrap CSS and JavaScript files to your theme.
- Define an asset library using a THEMENAME.libraries.yml file in your theme.
- Tell Drupal to attach your asset library so that the CSS and JavaScript files it represents are included in the page.
Once that's done your site won't look all that different. But if you view the page source, or look closely, you should see that the Bootstrap files are included along with any CSS rules you placed into your custom style sheet.
Note: Since this course if focused on teaching the Drupal aspects of theme development, and not on writing CSS, we use the Bootstrap CSS. If you don't need it for your project though you can skip it, or add the CSS framework that you want to use instead.
You should try to complete the exercise steps on your own and use the video to help guide you if you get stuck.
Note: At the end of this exercise, you'll find a video walk-through of the solution.
Drupal has a few handy settings you can tweak to make developing themes a little more intuitive and a lot more awesome. This includes disabling some of the caching that Drupal does so you don't need to clear the cache as frequently. We'll also turn off CSS and JS aggregation in a settings file (overriding anything set on the Performance configuration form) so you can see your changes to .js and .css files with just a page refresh. Finally, turning on the Twig debug service will give us some additional contextual information about the templates being used when we view the source code of any page on our site. Walk through the exercise steps, and if you get stuck you can watch the video to see how we implemented this.
If you want to try and complete this on your own you'll need to:
- Make changes to your site's settings.php file. Hint: check out the example.settings.local.php file included with core.
- Modify configuration via a services.yml file. Hint: check out the default.services.yml file included with core.
Once this is done, if you view the source of any page on your Drupal site you should see extra HTML comments with helpful information about which template file was used to generate a section of markup.
Example:
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'node' -->
<!-- FILE NAME SUGGESTIONS:
* node--view--frontpage--page-1.html.twig
* node--view--frontpage.html.twig
* node--2--teaser.html.twig
* node--2.html.twig
* node--page--teaser.html.twig
* node--page.html.twig
* node--teaser.html.twig
x node.html.twig
-->
<!-- BEGIN OUTPUT from 'themes/icecream/templates/node.html.twig' -->
Note: At the end of this exercise, you'll find a video walk-through of the solution.
In order to change Drupal's default markup you need to override template files. The page template controls the overall layout of your theme, including the placement of regions. You should complete the exercise just following the written instructions and you can use the video to help if you get stuck.
If you want to try and do this on your own first you'll need to:
- Override the currently used page.html.twig template file.
- Modify the content of the file to include the regions defined in the theme's .info.yml file.
- Wrap the regions in the page template file with HTML markup using CSS classes from Bootstrap to achieve the example layout below.
Note: At the end of this exercise, you'll find a video walk-through of the solution.
The available dynamic tokens or variables vary from template to template. Each "page" is built from and uses many different templates. In this exercise, we'll continue our template overriding practice by overriding the node template. We'll override it and rename it in such a way that it will only affect article nodes on our Drupal site. We'll practice the process of overriding the template, inspecting the available variables, and customizing the markup. Along the way, we'll practice using the Twig filter without
. You should work on the exercise steps below first, and you can refer to the video if you need some help.
If you want to try and accomplish this on your own first you'll need to:
- Override the node.html.twig template file and target only Article nodes.
- Modify the template so that the content of the image field of a node is output wrapped in a
<div>
independent of the rest of the node's content.
Example:
Note: At the end of this exercise, you'll find a video walk-through of the solution.
In this exercise, we'll continue our template overriding practice by overriding the main menu template. We'll override it and rename it with a file name suggestion so that it will only affect the main menu component of our Drupal site. We'll consult the Bootstrap documentation and add the classes from the base nav component into our overridden main menu template file. Along the way, we'll utilize a variety of methods for adding CSS classes to HTML selectors including using attributes.addClass()
and set
. You should work on the exercise steps below first, and you can refer to the video if you need some help.
If you want to try and accomplish this on your own first you'll need to:
- Override the menu.html.twig template file, using a file name suggestion to target only the main menu.
- Add CSS classes from the base nav component in Bootstrap.
Note: At the end of this exercise, you'll find a video walk-through of the solution.
In this exercise, we'll continue our template overriding practice by overriding the image field template. We'll consult the Bootstrap documentation and add a responsive image class that will apply to any images uploaded by a user to the field_image
field. Once again, we'll add this class to the classes
array in the set
Twig tag. You should work on the exercise steps below first, and you can refer to the video if you need some help.
If you want to try and accomplish this on your own first you'll need to:
- Override the image field template file.
- Add values to the
classes
array withset
.
Note: At the end of this exercise, you'll find a video walk-through of the solution.
In this exercise, we'll practice using the t
fiter in a Twig template. As a best practice, all hard-coded text in a template should be translatable. Simple text (containing no dynamic tokens) can be be passed through the t
filter to achieve this objective. Along the way, we'll also use a basic conditional if
statement with Twig. You should work on the exercise steps below first, and you can refer to the video if you need some help.
If you want to try and accomplish this on your own first you'll need to:
- Add a
<div class="label label-warning">
element to the article node template file that contains the string"This node is not published"
. - Use the
t
filter to make the hard-coded text translatable. - Use basic logic statements with Twig to check if the node is published or not.
Note: At the end of this exercise, you'll find a video walk-through of the solution.
Preprocess functions allow you change existing variables, or add new variables, for a template file using PHP code. In this final exercise for the course, you'll define a PHP function that implements a preprocess hook and define a new variable using PHP and make it available for use within a specific template file. Specifically we want to create a new variable named {{ today }}
that contains the current date and gets passed to the page.html.twig template file. You should work on the exercise steps below first, and you can refer to the video if you need some help.
If you want to try and accomplish this on your own first you'll need to:
Learning objectives:
- Create a THEMENAME.theme file.
- Write a proprocess PHP function that adds variables to a page template file.
Note: At the end of this exercise, you'll find a video walk-through of the solution.
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.
The Layout Builder Styles module extends the Drupal core Layout Builder UI to add the ability for editors to apply custom CSS classes to the blocks and sections that make up a layout. This gives layout editors more control over the look and feel of elements within a layout. It's especially useful when using Drupal's Layout Builder in conjunction with a design system like Bootstrap, Material UI, or your own predefined utility classes.
The module allows site builders to define new styles. Then, when placing a block into a layout, if there are any styles available for the block type, the user is presented with a select list where they can choose one or more to apply. When a style is applied, any CSS classes associated with the style are added to the markup. Also, a new style-specific theme hook suggestion is added to the block to allow for further customization.
In this tutorial we'll:
- Install and configure the Drupal Layout Builder Styles module
- Learn how to define new styles
- Learn how anyone editing a layout can apply the styles we defined to a block or section in the layout to change the UX
By the end of this tutorial, you should be able to use the Layout Builder Styles module to allow editors to add predefined styles to existing layouts and blocks without writing any code.
Access control for the Media entities in Drupal works in much the same way as any other content entity. The module provides fine-grained control over create, update, and delete operations, while providing only basic control over who can view Media assets. The thinking is that there are too many possible permutations of how an application may want to restrict read access to content. Therefore, rather than try and pick one setting and add it to core, it's left entirely up to the site administrator and contributed modules.
In this tutorial we'll:
- Look at the different permissions provided by the Media module for controlling access to Media entity operations
- Discuss some common misconceptions about file permissions that can lead to potentially exposing private data
By the end of this tutorial you should know how to configure access control for Media entities, and explain how access control relates to files attached to a Media entity attached to a Node.
Drupal media entities are fieldable entities, which means that you can add any custom fields you want to your Media types. These fields can be used for collecting additional metadata about a resource, categorizing and organizing resources so they're easier to find in a large media library, or for displaying information like a photo credit or transcript for a video. The possibilities are endless once you know how to add, and optionally display, fields in Drupal.
Some example use cases for adding fields to Media types:
- Collect, and display, a credit to go along with a photo. This could also be a date, a location, or any other metadata.
- Store resource width and height dimensions as custom fields so they can be referenced by display logic in the theme layer.
- Use Taxonomy reference fields to add tags or categories to help keep a large library organized.
In this tutorial we'll:
- Learn how to add fields to a Media type
- Verify our new custom field is working
By the end of this tutorial you'll know how to add custom fields to any Media type.
The most common way to use Drupal's Media items is to add fields to content types, allowing the Media entities to be associated with one or more pieces of content. For example, adding a cover image to an article, or embedding a set of YouTube videos into a tutorial. This is accomplished by adding a Media field to the content type in question.
In this tutorial we'll:
- Explain what the different Media field-specific configuration options do
- Add a Media field to the existing Article content type
- Explain what the different field-specific configuration options do
- Confirm that it worked by verifying that the form for adding an article has the new field
By the end of this tutorial you'll know how to add a Media field to any content type, or any other fieldable entity, in order to allow Media items to be associated with the content.
Media entities in Drupal are content entities, and can be administered like most other Drupal content entities. In most cases you'll likely add new Media entities via the Media Library widget when creating a new content entity like an Article. However, it's possible to add them to the library without having to attach them to a piece of content. You may also want to update an existing Media entity, or just search the library to see whether something already exists.
In this tutorial we'll:
- Learn what a Media entity is in Drupal
- Get an overview of the main Media management page
- Learn how to add, edit, and delete, Media entities
- Learn how to bulk edit Media entities in Drupal
By the end of this tutorial you'll know how to perform basic find, add, edit, and delete operations to manage the Media entities in your library.