Example Lesson Videos - Drupal 8 Theme Development: Overriding and Customizing Templates in Your Drupal 8 Theme (Part 2 of 2)

  • Lesson Notes
  • Playlist
  • Transcript
Lesson Notes
These are two example lesson videos pulled from our Drupal 8 Theme Development course.

See Full Course Syllabus and Schedule

Example Code For This Course

All the example code you see me using in this course is available as a git repository. This allows you "checkout" different versions of the code to move to any point in the course. Your primary assignment each week is to follow along with creating the modules you see me create in the lesson videos. You have two ways you can do this. Personally, I prefer to copy and type out the programs I see on screen, because I find it helps me remember things better. However, this can be fairly time-consuming, so there is a second option. Since I have provided many different versions of the code in the example git repository, you can watch the videos, and when you get to a checkout point (there will be an on-screen prompt), checkout that version of the code, read through it, and run it to confirm you understand what you've just watched. That will take less time, but I will leave it to you to decide how you learn best. Be sure you perform the clone operation in the correct folder, depending on whether or not you want to copy the code yourself or just use the example code to follow along. I discuss the appropriate locations in the code repository video.

Frequently Asked Questions

Do the lesson videos play on iPads and iPhones?

Yes, they work on both desktop/laptop computers and iOS devices.

How can I ask questions or get help?

You can ask questions about the lesson or get help with your assignment by posting to the class discussion forums and attending the weekly live Q&A sessions with the instructor. (online via webinar software)

Do I need to have my own website or hosting account to work on?

No, we will provide you with a development environment you can install on your computer. Installation and configuration of the local development is covered step-by-step in course lesson videos.

In this video, I will show you how you can customize the HTML that Drupal uses to display various elements on every page. We'll use the theme that we started with in previous videos. In Drupal 8, all HTML output is rendered from templates and those templates are written in the language called Twig. In this video, I'm going to show you how to override the built-in templates so that you can provide your own HTML markup for any of the elements you see on a Drupal page. We will also see a little bit of the Twig language in the process, but I will cover the language features of Twig in much more detail in another series of videos. Okay. Before we begin, we need to make sure that your development site has Twig debug enabled. There was an earlier video where I showed how to do that. So if you're watching videos in order, you should have already done that but a quick review of it is that you need to copy the example in your sites default folder. You need to copy the example.settings.local.php file into the default folder as settings.local.php and then you need to enable it from settings.php by including these lines at the bottom of the file. And then in order to turn on Twig debug, you need to go into development_services.php and make sure you have this configuration set, these parameters set in the file. After you do that, you clear all your caches and the Twig debug should be turned on. You can figure... you can check for that by viewing the page source. In your page source if you see these comments that say theme debug, theme hook, et cetera, then you have Twig debug enabled. All right. Once you have Twig debug turned on, then we can begin the process of customizing the HTML for our theme. As I said at the beginning of the video, all HTML that will be rendered in Drupal should be placed in a template file or multiple template files. There are many different template files that get rendered together to make up one Drupal page. It's sort of like an onion. You've got layers of templates inside of other templates and those are inside of other templates and they all build together to make a single page. So when you want to customize the HTML for some element on a page, the first task you have is to figure out which template has the HTML for the element that you want to customize. That's where the Twig debug helps you. When the site has Twig enabled, those comments I showed you a moment ago tell you which templates are responsible for each part of the page. Viewing these comments works best if you're in the Chrome browser, but Firefox will work as well. The comments aren't formatted as nicely in Firefox, but they do work. So let's take an example. Let's say that we want to change the HTML markup for a block. So first, let's create a simple custom block to put on our sidebar. I want to do that because the built-in search block and the tools block they have some existing customization that I want to skip right now so let's just make a simple block. So I'll open up in another tab here, structure block layouts custom block library. And let's create a custom block that says something like, "Welcome to our site." And then for the body we'll say, "We're glad you're here." So I'll save that custom block and I'll go back to block layout and we'll need to place the block on the sidebar. So here it is the "Welcome to our site" block so I'll place that. And we'll leave everything like it is default. I'll drag it up to the top of the sidebar and save. And now if I go back and refresh the site we can see that the block is here. So now let's look at the markup for this block. So if I right click in this area, so I'll right click on the title and I choose inspect then Chrome will pop open the inspector down here and I can look at the HTML that makes up the site and you could see if you've never used the inspector before, as you hover over different elements down here in the code, Chrome will highlight those elements on the page. So that makes it really easy to know which thing you're looking at in the code and match it up. Okay, so if we look at how a block... how the markup for a block is structured, here we have a div that wraps the entire block and then inside of that we have that H2 tag that is for the title. Next, we have these... this is the contextual links. You see these little things that pop up, this is only for administrators, but these little management links, there's a div for those. Those wouldn't be shown to non-administrators but that's what's there. And then down here we have another div for the body and then inside of that div we have the actual paragraph tag which is the content of the body. And then I think that wraps it up. Yeah. That's the end. That's how the blocks HTML is rendered. So what if we wanted to change something? What if we decided that instead of H2 tags, we wanted to use the H3 tag for block title instead? How could we make that change? Well, to do that, we first need to figure out which template controls the block title markup. That's where we see. That's where these debug comments will help us. If we go back to the beginning of the block. then we can see this line right here. It says begin output from core/themes/classy/templates/block/block.html.twig. That is the template that is being used for this block. This is the template that we should override but before I do that I do want to point out one another thing that this block is actually made up of a couple templates. There's the block template. But then if we go in here, inside of it, right before the body tag or the body div tag, we can see another template is being used. So this is the field text with summary. So this is actually a template for the body field. So just like I told you before, templates can nest together to build larger structures and that's what we're seeing here. There's an inner template that controls the body markup, so basically this div tag here. And then there's an outer one that controls the larger structure of the block. So make sure that you understand all the sub templates and when you're trying to find where your markup is, make sure you notice all the sub templates and choose the most specific one that includes inside of it the HTML that you want to change. And so you can see actually. There's a start and end tags for each template so you see it says begin output of this template. And then it says end output of the template. So we can see our H2 tag doesn't appear between these two, but it does appear between the block, the end of the block HTML and its beginning which is up here. So that's how we know that block.html.twig is the file that we need to override. So let's go take a look at that file. Now, that file is inside of a classy theme which is under core themes classy. And that makes sense if you think about that it's going to be in our base theme because in general, when we use that base theme then we are inheriting all of the design from the base theme. However, be aware that modules can also provide templates to the Drupal system. So if you're overriding something that's been produced by a contributed module, you may find that the template is in a module instead of a theme. Everything works the same way in either case. Just follow whatever path is listed here in this comment, and that will get you to the file for the template. All right. Templates should always be inside of a templates sub folder. That's true either in themes or modules. And then for classy, you can see that there are sub folders inside of here. There's this block sub folder and here is our block.html.twig. So if we open this up and we scroll down, we can see here is the HTML that controls that title. So we see the H2 tags right there. This is what we need to change. Now, we can't edit the file here in the classy theme. Or actually, we could edit the theme here. We could edit this template file right here. But that would be a terrible idea because this file gets overridden every time we do a Drupal update. So every time we do the Drupal update we would have to come back here and fix it again. And surely as we customize several things we would not be able to remember all the changes. So instead, what we need to do is make a copy of this template and put it in our theme. Then we can edit our copy and it will stay in place as we do Drupal updates. In order to do this, we will need to create a templates folder inside of our theme because all templates must be in a templates folder or they won't be found by Drupal. So underneath our theme here, bitwisdom, let's create a templates folder and then let's copy block.html.twig into the templates folder. Now, we had some folders here under templates and classy. We are not required to follow the sub folder structure. For classy, they have a lot of templates because they have templates, they're specifying templates for almost everything. For us, we're only going to be overriding a few of them. So I'm not going to make the sub folders and it's not necessary that the sub folders match up. What is necessary is that it'd be inside of the templates folder. So I'm going to paste my file, the block.html.twig inside of the templates folder and then let's close this up so I make sure I'm editing the right now. Be careful about that. It's easy to accidentally be editing the wrong one when you open it up. So then I make sure I open up the block.html.twig from my copy in bitwisdom theme. And then I can just make my changes. So let's change the H2 to an H3 tag. All right and then we'll save. And now we come back over to the site and if we refresh, we'll see that nothing happens. That's expected. Because we've added a new template to our theme, we need to rebuild the caches. So I'm going to go to my virtual machine and log in to it. And then inside of my Drupal folder I'm going to run 'drush cr' for cache rebuild. And in that process Drupal will pick up that we've added a new template to our theme. So I'll refresh now, and you can see it looks a bit smaller. If I inspect, we can see that we've got H3 tags now for the block title. And if we look here at the output, you'll see that it says that this template is themes/custom/bitwisdom/templates/block.html.twig. So our template has now overridden the built-in template for blocks. Now, if we look at the other blocks on the sidebar here, you'll see that they still have large texts. And if we inspect them, you'll see that they're still H2 tags for the titles. And we could see why if we look here at the Twig debug statement. The template that's being used for the search block here is a special one, blocks search form block.html. And the same thing's true here if I look at tools. You'll see that this is a special blocks system menu block because this happens to be a menu links block. So if we wanted these... so these two aren't using the standard block template. And that's why when we made that change, it didn't change the size of the titles. It didn't make these into H3 tags. So if we wanted to make these H3 tags as well, we can just follow the exact same process that we did before. So we'll go up here to the classy theme, and those two blocks are here. Here's the menu block and the search form block. So I will copy both of those templates and then I'll come down to bitwisdom. And in our templates folder, I will paste both those. And then let's edit them. You'll see there's a little bit more markup in here for these. That's okay. We don't need to change any of the other things. We just want to change the title right now. So I'll just change these title tags to H3 on both of these. And then I'll save everything. And now again, we're going to have to clear caches because we added some new templates to our theme. So once we do that, once I clear the caches I should be able to refresh and hopefully these will be updated. Okay. They look smaller. Let's just confirm. The search has an H3 and the tools menu now has H3 for the title. So it works. Now, let's look at some more options that we have when override templates. In the block example the first template we overrode, did the override on would have updated every block on the site that was using the standard block template. That's most of them except for the menus in the search that we saw and it's definitely all of the custom blocks that you might make. However, what if we only wanted to change our specific blocks HTML? Let's take another example since we've already done the blocks. How about nodes? Here we are looking at the homepage of our site and we have a bunch of teasers for several different nodes here. There's a mix of page nodes and article nodes and we're seeing the teaser view for all of them. Because we generated these automatically, the teaser views are quite long, but these are still the teaser views. So what if we wanted to override the template or the design, the HTML for these? Well, let's do the inspection and look at the Twig debug comments. So I'll inspect here to the title because it's close the top of the node. And now there are many more templates involved in... there are many sort of sub templates nested templates like we saw before in the node titles, sorry, in a node. So we need to make sure that we get the outermost one. So the one that sort of wraps around the entire node is right here. We can see this is the node.html.twig template. So if we wanted to override the design or the HTML that was being rendered here, we could override this node template just like we did for the blocks, but that could be too broad of an approach. The node.html.twig template applies for all types of nodes in all view modes. So that means it applies to both teasers and the full page views for nodes and for all different types. What if we only wanted to override this template for articles? Or more specifically, what if we just wanted to override this template for the teasers of articles? We can do that by choosing a specific name for our template file. The way it works is we copy the current template into our theme just like we did before, but we give that file a different file name. We can see if we look just above the current template we can see a list of file name suggestions. These are ordered from most specific to most broad, usually. And you can see that node.html.twig is at the bottom. It is the most broad. You can also see that instead of a little asterisk or star, it has an xx to it. That's because it's the one that's currently in use. So next up the line if we go from like most broad to most specific, if we go up the line you'll see that there's an alternative file name node - - teaser.html.twig. That would be the name of the file that would be for all nodes of all types but only in the teaser view mode. Or we have node - - article.html.twig. That would be for all nodes of the article type but in all of its view modes. So both the full page and teaser. Then the next up the list is node - - article - - teaser. So that would be only the article nodes and only that teaser view mode. Getting even more specific, we have node - - 40.html.twig. That is literally just this one node. So it's the node with ID 40. And then again, we can go node 40 teaser. That is only the teaser view mode for this specific node number 40. And then the last two are some alternatives if you want to work with just the nodes that are on the front page view. We will see some more detail about customizing views, templates for views in another video. So those are our options and what I want to do is I want to override the template for all article nodes but only in their teaser view mode. So we're going to choose node article teaser.html.twig as our file name. So the way we go about doing this is first we have to copy the current template. So the current template is just called node.html.twig. So we copy that in first. So we'll go back up here to classy. The node template is under the content sub folder. So here it is, node.html.twig. I will copy that and then I'll scroll down and paste it into my templates folder. And then I need to rename it. So I'll right click it again and you'll see it says node.html. NetBeans will automatically add the '.twig' for you so just don't add that part here. But we need to add... we need to change this to node - - (so two hyphens there) article - - teaser. So now we have node article teaser.html.twig. And let's change something in here. So I'll open it up and let's add some sort of wrapper div on the contents of this. So let's say for our design, we need an extra div tag in here. So let's say div class equals article teaser wrapper and then we'll need a closing div just before the closing article tag. All right so we'll do that. Now, I'll save and then in order that we can see this, let's add some style. So I'll go here under CSS and go to style and then at the bottom I will add article teaser wrapper, and let's just put up a thick border around it so that we can see it. So this will add a thick green border around it. So we'll save that. And now we'll need to clear caches because we copied a new template file into our theme. And then after we clear caches, if I refresh, we can see that there is a green border now around this node. If I scroll up a little bit you'll see there isn't a green border around this one because it's a page. If we keep going up we should eventually get another... yeah here's another article. It's got the green border around it. And if we look down in our inspector are, we can see that the output for our template is now our customized node article teaser. And you'll also see in the file name suggestions that the little x has moved up to node article teaser. So we've done it. We have overridden the node template but only for articles and only in their teaser view mode. So there's a lot of different templates in Drupal 8 and each of them will have its own internal structure and markup that might be different. However, the process for how you make changes to that markup is exactly the same as what we've just seen. So to review the process, first, you need to find the template file that is currently being used and you can do that with the Twig debug comments like we've seen. Next, you copy that template into your theme inside of the templates sub folder of your theme. Then you optionally rename that template file to one of the suggested file names if you want to make it more narrowly defined. If you don't, if you just want to override everything then you can keep the same file name, but you may rename it to make it more targeted. Then you can make... once you've done that you can make any changes that you want to make to the HTML, the markup, anything that's in that template file, you make your changes. Save those, clear your caches and then your changes will be available. So for every template it works the same. The exact override file suggestion names and the scopes that those cover will be different for each type of template, but in general, they are pretty self-explanatory. So we saw that nodes have their type and view mode. Blocks will have the module that produced them and the ID of that block. Fields will have their... the type of field it is and the specific field name. And then also usually a more specific one for the type of entity they're in like the node or something like that. So the process is the same for all of them. And so I think that is all you need to know about how all to override templates and customize the HTML output for Drupal 8.