 Welcome to my talk, demystifying rendered content in Drupal 8 twig files. That's an awfully long name with a lot of jargon in it. So first off, what does it mean? Well, theming in Drupal 8 is a ton different from theming in Drupal 7. And I'll talk a little bit about how that's so. Then we've also got this new tool to Drupal Core called twig. That's pretty integral, so I'll talk about that. And also, Drupal tends to give us a lot of markup out of the box. But as front-end developers, we often want the markup to be written differently to suit our needs. This is what my talk is about. In addition to sharing my process of discovering what works and what still needs work, if questions pop up, please write them down. And like I said, I hope to get to some Q&A time at the end. So quick room check. Who is new to Drupal 8? All right, a lot of you. Who's new to twig? And who's already working in Drupal 8 and has a pretty good system for working with twig? Already working in Drupal 8 as front-end developers, hoping to learn some more tricks. All right, cool. Well, welcome. It's wonderful to have you here. And I hope you find my talk helpful. Much of my talking points relies on debugging. Why is that, you might ask? Well, for me, coding without debugging tools is a little like this GIF. At first, you know exactly what you want. You've got your eye on the prize and are set out to write the perfect code. So you take aim, and you might even get the answer the right the first time. And there's much rejoicing. But more often than not, you get it wrong repeatedly before you get it right. For me, I like knowing exactly what elements and tools are available to me. So when Drupal 8 came out, I made it a personal mission to see about debugging twig files. Speaking of which, I should probably tell you a little bit about myself. My name is Amy Valencourt-Sals. I am a full-stacked software engineer. And more recently, I've gone front-end focused. I work for Think Shout. We're a small but growing agency that builds websites for nonprofit organizations, such as the Southern Poverty Law Center, Facing History, Humane Society, and many others. We are also contributors to the Drupal community and our module maintainers for MailChimp, Red Hand CRM, and the Drupal 7 Salesforce Suite. Enough about me? Let's talk about some differences between Drupal 7 and Drupal 8 that are pertinent to us front-end developers. So there's been a shift from using PHP template files, a.k.a. TPL, to twig. Essentially, they're both files that produce markup and probably have some coding logic mixed in. These are template files that tell a project what to render on the page, an element, a field, et cetera. What is twig and how is it different? Well, let me demystify this for you. Twig is a fairly simplistic PHP templating language. So instead of writing a bunch of verbose PHP, you write much cleaner looking code. Twig is a compiling language for markup. Similar to how SAS compiles our theming work into computer-readable CSS, twig is compiled into PHP-readable templates, which then are rendered on the web page. That's kind of a lot to think about, so I can break it down. When a page renders, it converts what you've written in twig and compiles it using a PHP script. That PHP script lives in your site default files PHP folder, in case you're curious. The script essentially stores the compiled code into memory and then turns it into the page we are visiting. Here's a screenshot of the home page of twig.senseolabs.org. I highly recommend getting familiar with the twig documentation. I refer to it often. The Drupal community has also created some super helpful twig functions. And those can be found in the drupal.org documentation. I've included a couple of, actually I've included several links at the end of my slide deck. So you don't have to memorize all these resources. Here we are looking at essentially the same code crossed over from Drupal 7 to Drupal 8. There are some noticeable differences in syntax. In Drupal 7, TPL files have PHP right in the code versus twig curly brackets on the bottom right. Commented out TPL files can make my brain hurt, honestly. Because the markup and PHP variables will comment out, but the PHP tags will stick around. So it's really hard to read. Twig, when you comment out a line, the full line comments out it's entirely much more reasonable to look at. Also a pro tip, TPL files have the variable title. Whereas twig files have the variable label. That's how you get your title. Just to let you know, it'll come in handy. There's also the move away from the hook system, which those in Drupal 7 are very familiar with. We moved more to a model view controller system in Drupal 8. As a Drupal front end developer, we have some choices when we need to change the markup. One is that we can override the template. And that works great for a lot of the time. But there are certain instances where that's just not possible. Or we can also use a hook, like a pre-process hook. And that's great if we know how to write PHP. And if we don't, then we have to ask one of our back end developer friends for a little bit of help. And as front end developers, we kind of like to write our own markup. And it's good coding practice to keep the markup in the front, right? Another option we have is we could convince a designer to change their design. Don't do it. As front end developers, it's a pretty good practice to just find a way to make it work. In a harmonious relationship with front end developer and a designer, we'll lead to everyone's happiness. In Drupal 8, overriding templates has never been easier. It gives you more control of the logic for displaying elements, and everybody wins, including your very happy designer. Drupal 7 had the luxury of debugging right in the template files. Drupal 8? Not so much at first, but now we've got more tools. It's pretty exciting. OK, one of these new tools is file name suggestions. It takes a little bit of configuration, namely setting your twig.config debug setting to true. Once that's done, maybe clear the cache and refresh your page. And when you inspect the element, you can have access to these lovely file name suggestions. If you look at begin output at the bottom, you'll see exactly which template file is being rendered. In this case, it's coming from the core themes, Bartik templates, and then the file node.html.twig. The x on the left side of node.html.twig in the list, that indicates that this is the template that's being used. The order of the file names is important. It's listed as more specific at the top to more generic at the bottom. Depending on the level of specificity, you can choose a file name that suits your needs in the best way, and then Drupal will be smart enough to adhere to the file name rules of specificity. That's a really hard word to say. To give you an example, let me take you through a practice project to give you an idea of how this process works, how to apply these tools, and tricks I'm about to go through with you. So a little diversion. I actually just recently went to Costa Rica, and I was that close to that sloth. And so I had to fit this video in this talk somehow. There was so much wildlife in Costa Rica, and I was so inspired by it that I thought I would create this website as an example to take you through this. So let's pretend we're creating an article listing page with posts about all the fun wildlife in Costa Rica. I think I need some water. So the back-end developer has already gone ahead and set up a listing page using right out of the box Drupal article nodes and arranged the fields for viewing them in their teaser view mode. Remember, suggestions go from more specific at the top to more generic at the bottom. Can people see these? Yeah? Okay. So our role as front-end developers is we need to style all of the articles of a teaser view mode. Which file name suggestion should we use? And somebody can just shout it out. Anyone? Raise hands, it's fine. Yes! Node article teaser. Whoever said that gets a gold star. Okay. Now that we know what file name suggestion to use as our override template, where do we put it? In the themes, custom, your theme name. In this case, I used think base. Templates directory would probably be a good path. I've created a nodes directory to place any templates associated with node types, such as this one. And the same could be done for blocks, field template types, et cetera. Okay, so now we've got our file and our file name suggestion. We know where to put it. We find that twig file that Drupal is already using and we copy and paste that code into our new file, clear the cache, and then this is what we see as we inspect the element. The path is now themes, custom, think base. It could be your own. Templates, nodes, node article teaser. We're in a roll. We got this. Drupal's already giving us the markup. We can wrap our elements in divs if we want to. We get focusing on writing some sweet sass and JavaScript. This is what we do, right? Yeah? Exactly. Okay, so now we're feeling like pros. What's next? Well, we're going to theme a call to action block. So the backend developer has created a call to action block. Is everybody familiar with a call to action block? Anybody who's not familiar? Okay, so a call to action block. And that's what we call it at our work. Is a block that when a user visits a site, they're compelled to act in some way. So a donation button would be, or a block that has a donation button would be an example of a call to action block. Okay, backend developer has created this block with a tile view mode. They've added this new CTA block. That's what we're calling this custom block. And it's placed using the block layout UI. So that's all set up for us. Okay, it's our turn. So as front end developers, our task is to set a style for all CTA blocks across the site that are using the tile view mode. And we apply an image as a background. This is why I'm not a designer. Okay. I guess it was pretty good. Maybe I'm missing my calling. Okay. Here's the block we're going to create. We're going to help raise money to generate awareness about how feeding wildlife, like these cute coatties that were on the side of the road, begging for food, we're going to generate awareness why feeding them is a problem. I mean, this is a really big problem in Costa Rica. I mean, there are signs everywhere saying come on guys, don't feed the coatties, but there are tourists giving them potato chips and all the, okay, fine, I'll stop. Wrong talk. So our task, as I said, is to set a style for all CTA blocks using the tile view mode. We got this, right? Here are our file name suggestions. Can anybody help me out here? So there's more specific at the top to more generic at the bottom, but does anybody see where the block type is, the CTA block tile? What? Oh my God. What am I supposed to do with this? I mean, I thought we had this, right? I don't know what to do. Okay, well, let me think about this. So I guess I can think of three options here that we can take. One is to use display suite. We have the ability, when using display suite, to create a view mode and display suite essentially provides a default template for that view mode. And you can override it too. Those of you who read my session blurb, might have seen that I might possibly do a demo of display suite. Well, when I tried to replicate this recently, I went to create a new view mode and all of my fields vanished and I wrestled with it for a couple of hours and I had to chuck it, so no demo. And I'm not quite sure what's going on there, but I'm sure that it'll be fixed. You can also create a custom file name suggestion with a bit of code and I'll show you that next. Lastly, there's a way to specify view modes in your template and I'll get to that later on. This code uses a hook theme suggestions hook alter. And what it does is it takes an array of suggestions and variables and allows a developer to create alternative file name suggestions for a specific element, in this case blocks. This example creates a naming convention that includes block types as a file name suggestion that is recognizable by Drupal. To try and override this file name without using that doesn't work, I tried it. But hey, after a little cache clearing after using that hook, there's our new file name suggestion. Yes. Okay, we're good to go, right? Okay. Now that we've got our override template set up, we've got to do some trickery with our markup. It's time to look at debugging tools. First, we've got twig dump. This will, it is what it says. It'll dump the information about a template variable right on the page for you. So you apply dump within the curly brackets, add your twig variable inside, and this is what you get. So unless you're really good at guessing, this can be a time suck. Dump is fantastic if you wanna double check and see if a twig variable will give you exactly what you want. Next is develop in Kent. So you download and enable the develop module and it'll come with develop Kent. So enable the develop and develop Kent modules and then the kint twig function will become available to you. And this is an example of what it looks like. This will get us the majority of the way there. We can already tell that content.body will give us the body field, content.field background image, the background image, et cetera. When I tried this, I discovered that kint is a rather expensive tool and it has a tendency to max out the memory and drag the site down. So a little extra configuration might be necessary, but it's pretty good. Likely there are other tools out there. In the comment sections of blogs that I was reading while I was prepping for this talk, there were a handful of people who had mentioned CodeLockster, so that might be worth checking out. And there are probably others too. If anybody knows of others, please feel free to let us know at the end. Xdebug is my personal favorite. My team at ThinkShout uses PHPStorm and Xdebug integrates nicely. When I'm working on backend tasks, this tool is completely invaluable. I can see the call stack, meaning the files that were executed before I stopped my program. I can set variables to be watched and step through the code to see if and when my variable value changes. It's fantastic. So here's where we get to the juicy part. But first, a little story. Back in the day, soon after Truffle 8 was first released, this amazing fellow, I'm probably gonna butcher his name. Love Amir Cullen? Did I get it? Did somebody know him? Okay. Okay. Well, do you remember my mentioning when a twig file is compiled, a PHP script is generated? Truffle has a way of caching these. So at first, they weren't available to us devs. But after some configurations, that this blog post essentially showed me how to set up, I used Xdebug to set up a listener. I was able to set a break point on one of these one-time generated PHP scripts and get what I need. And remember, site's default files, PHP, is where those script files live. I would find my template specific PHP script and set a break point and everything was fantastic. So fantastic that I wrote a blog about it back in November. And I submitted a talk to DrupalCon. And to my surprise, it got accepted. I guess this is of interest to you. And I finally carved out some time to work on this talk about three weeks ago, only to discover this method no longer works. Oh my God. So it seems the system of caching had changed somehow, such that the PHP script is only run once. So I was unable to trigger the break point by refreshing my page. Oh my God. So yeah, this is my first talk to be accepted at DrupalCon and suddenly my gift to front-end developers was just gone. After taking numerous deep breaths in a paper bag and realizing that there were probably other people in the Drupal community that feel as passionately about debugging as I do, I set out to do some research. And I found this. The twig xDbug module, along with installing Drupal console, and the links are included at the end, gave me exactly what I was looking for. Better yet, rather than debugging the PHP scripts, we can debug right in our twig files. Oh my God. This is really cool. Seriously. Having to go from debugging in PHP scripts to this is just mind-blowingly awesome. So I hope you guys are as stoked as I am. Here's what we do. Get yourself set up with twig xDbug, the necessary libraries, and Drupal console. Grab the template file you wish to debug. That's in green. And hey now, look at that. We've got a break point twig function just like dump or kint. You clear the cache, you turn on your listener, refresh, and the break point function triggers a script. And that's in red. That stops right in the template, giving you the twig variables and information available to you. This is pretty, pretty amazing. Okay, new tip, nowhere to look. Because Drupal arrays can take you deep, deep, deep, deep, deep down into an infinite rabbit hole of options. I'll save you some guesswork. So check this out. This is what your debugger will look like when it's stopped. To be more specific, I'll zoom in for you. So in green, the context variable is where all the important information will live. Now I've got access to my fields, and you can see at the bottom in blue, body, background, image, and field link. Okay, let's talk about twig translation. So these, oh, I forgot to mention in my last slide, PHPStorm allows you to click those fields and drag them into your watcher so you can see what path they come from. So now that we know the path, the bottom right is how we translate it. Whenever possible, add the field value completely using content dot, whatever the field is. This will keep the integrity of your field configurations intact, such as image dimensions, trimmed text, et cetera. I've put together a couple other twig recommendations for you that I lovingly call my twig tionary. Actually, I stole that from a colleague because I thought it was kind of clever. So shout out to Eric. First tip, ignore context and what comes next. Twig is smart enough to find what it needs from content. So content, elements, content, I'm sorry, context, elements, content will be translated to simply content, no bells, no whistles. Second tip, keep the integrity of any symbols present. See how view mode has a pound symbol in front of it? It stays nearly the same, but content gets stripped down and the rest is put right next to it. If an arrow exists, treat the method in the same manner as a raise, like so. Notice how the arrow becomes a dot. And yes, you perceptive people probably noticed that my last example had the word values following the arrow. I admit it probably wasn't a good example because that twig variable didn't actually produce any results on the page. So I'm going to try putting a dot value on the end and that does the trick. How do I know that it does the trick? Because dump is your friend. So I tried putting the full variable in the dump function on the template and I got that items ID. Oh yeah, remember the block that we wanted to create for the codeys? Here's the markup. So we've got our div with a background image and it's wrapped around the title which is also the label in this case. The body and the link field. Oh, and hey, look at that. I set a twig variable of my own getting the view mode associated with the current block that's being rendered. And I'm setting the view mode as a class to be changed dynamically. So if I want to reuse this template for other CTA blocks with different view modes, I can do that very easily by using this method. The codeys are going to be very pleased. Now the background image twig variable path would have taken me forever honestly if I didn't have the proper debugging tools. So here's how my team and I figured it out. We know. Content dot field background image will give us exact access to any specifics around this field. As front-end devs, we know that setting an image as a background requires that images file path URL. Drupal has a couple of its own twig functions and one is file URL. This helper function accepts a relative path from the root and creates a relative URI path to the file. Perfect, that's exactly what we need. So, oh, this example also shows us that we can get the entity property values like so with entity dot URI dot value. It's a matter of finding the right twig variable path such that entity can find the URI value. After some trial and error, this is the least verbose way that we could grab the background image field URI. And as you may have guessed, adding zero pound item was required. The URI value could not be found without it at the time. So I thought I'd save you some time by giving this to you because you will probably use it. To make your lives even more easy, a colleague brought this module to my attention and she's currently using it in one of our Drupal 8 projects. The twig field, nah, twig field value module allows themes to get partial data from field render arrays without all the mess of digging into the trenches of potential infinity. Here's an example of how to get the background image field URI value using the twig value module, that's right. No more guessing at the missing pieces, cleanly written twig variables all the way. So as I wrap up my talk, I thought you might appreciate some extra words of wisdom. The first one is to create the shortest render code possible. So if it's getting too long, chances are there's a better way and a shorter way to go about getting what you need. Try not to use array placements like zero, one, two, et cetera. Those items are susceptible to change. I found that out the hard way. Sometimes dot zero is the best route, yay. I found that to be the case with the background image variable, for example, and if there is a better way, please feel free to share it at the end. Also, everything gets easier with practice. Just some closing thoughts for you. With Drupal 8 still undergoing changes, debugging can change too. It's the nature of our work. Get to know twig. The more you work with it, the more you like it, I promise. Practice creating custom templates. Fortunately, Drupal 8 makes this a priority. So take advantage of custom template creation. It will free you up to do amazing work. Lastly, know where to look. Don't rely on mediocre tools that won't give you exactly what you need. Dive right in to get exactly the right information the first time around. Thanks for listening. Any questions? Yeah, that would be great. Thank you. Check. For the background image problem. Yeah. So here's one challenge, and then I'll give you one solution. Challenge is, if you need to use an image style, image style derivatives are only created once the image is loaded. Grabbing the background image like that from the URL, your image style will never be loaded. There's a image URL formatter that you can actually use. So through the field display, when you do manage display instead of image, you can choose image URL. It'll actually output the string for you that you can then use in the twig template. Sweet. Thank you for that. Hi. Hello. I've built a site in DA, and I found that one of the challenges that I had was when I had to do conditional statements that wrapped a variable that perhaps had some kind of wrapping markup around that variable. In some instances, I found that that markup was actually getting printed out when there was no value and that you had to somehow render that value before to see if content actually exists in it. OK. So did you come up with a solution for this, or are you? Well, I did a lot of thread searching to see if there was something out there, and a lot of people had different solutions to it, and I didn't know if there was one that maybe you had had experience using. I remember it had, I forgot exactly what the command was, but basically what it did was it rendered the field value to check and see if that had value, and then it would print that whatever was inside the conditional itself. And would you do that using the twig tools available to you? Yeah, it was a pipe command that you added onto the value itself, and I don't remember what it was, but I was just wondering if maybe you had any experience with that, or if you think that maybe that was just kind of an odd case, it doesn't normally happen, but I've had experience with that happening before. Yeah, I treat it the same way it sounds like you do. OK, yeah. All right, and I also wanted to mention that you mentioned a lot of different tactics for debugging twig templates in order to get what those field values were, and I wanted to share that in my experience using it, I found that without having any of that other, without having that module installed or Drupal console installed that just by debugging the preprocess function for that template actually gives you pretty much everything that gets printed into the template. So you can just kind of bypass that. If all you want to do is just check what's inside the node preprocess, so that you can get everything inside the node templates, like all those different values. Sweet, great to know. Thank you for sharing. Thank you. Do you know or have any experience with retrieving a twig value from a JavaScript file? Gosh, I don't. That's a really good question. Because I know there's Drupal settings that give you access to that, but I've just been having a hard time with that. OK, and you haven't been able to get it in your twig. Well, we have on one specific JavaScript file, but it seems like when there's a double invocation of two Drupal settings. Say that again, please. When there's two Drupal settings in different JavaScript files, then that's where, I don't know, something gets mishmashed. OK. But yeah, maybe someone else. I've asked around, and it's been really hard to find. Oh, no, I wish I could help you. It's all good. Thank you. Anyone else? Oh, so I'm going to put my slides on my session page, so they'll be available to you. So yeah, so you can have the resources. Absolutely, absolutely. Thanks for coming.