 Thank you for being here. This is a quick recipe making Drupal aid render the markup that you want. My name is Mauricio Dinarte. I am known as Dinarcon in Drupal.org, Twitter and pretty much everywhere on the internet. I am from Nicaragua. I also one of the organisers of the local Drupal community. I work for a company called Agaric. I work for a company called Agaric. I am a Drupal team, pretty much like in Europe and America. And I am really passionate about teaching. And very soon I will start this personal project about teaching Drupal in different languages. So I got some stickers on the table if you want to grab some. And before going any further I would like to know a little bit about you. We have a Drupal team. So most people about creating a custom theme? Well, good. How about creating a theme? A lot of people? Good. Have you worked with Tweek or symphony? Excellent. And have you created a Drupal aid theme? So, the session is from the basics, building of knowledge, so at the beginning there will be a lot of basic concepts because most of you already know this, I will try to not spend a lot of time in that. And I want you to remember this, the objective of the session is not just to give you a piece of code that you can copy and paste and just magically work, my objective is that you understand how the different pieces interact together so that you can, you know, create your own solutions. And Leah Bero, author of CSS Secrets, put it in a very good way. Understanding the process of finding a solution is far more valuable than the solution itself and we are looking for that, for understanding the process to find the solution. So we're going to start talking about Tweak. Tweak, as you might know, is a PHP project, a templating engine. It comes from the symphony ecosystem and we adopted it for Drupal 8. When working with Tweak and in particular with Drupal 8 themes, we're going to interact with a lot of templates. A template is basically HTML markup with some placeholders that will be dynamically modified. And in the template, you can embed CSS, JavaScript and images as needed. So this is an example of a Tweak template and as you can see it's basically an HTML skeleton with the placeholders. And you can use Tweak outside of Drupal, again, this is not specific to Drupal. On basics, we're going to cover Tweak syntax and see some examples of how Tweak is used in Drupal Core to explain the different concepts. So for the very basics, if you want to print anything, you use that print something syntax which is two curly brackets. If you want to do something like evaluate a condition on go where a loop, you use that do something syntax which is curly bracket percent sign. If you want to add a comment in your Tweak template, you use curly bracket and a hashtag. So I will be saying print something and do something a lot while explaining the template. So I just want to set the stage about that vocabulary that I will be using. Now in Drupal 8, most of the time, we're going to use one syntax to print variables and it is that dot notation which we see here in line number one. Tweak provides other mechanisms like line two and three in which we can use a square bracket notation or the attribute function. But we're going to see just in a moment why 99% of the time, we will want to use that dot notation. But before doing that, I want to tell you when you cannot use it. So if the variable that you want to print starts with a hash sign, you cannot use that dot notation. So for example, in line number six, we have a variable conform inside that one, another variable conform operator and inside that one, hash, sign and type. Because that name starts with a hash sign, you cannot use that dot notation. Another scenario where you cannot use that dot notation is when the variable name has some dash as part of the name. Because Tweak will think that this is an emetic operation and it will actually try to perform a subtraction. So in that case, you cannot use that dot notation. These two other options are rarely used. In fact, the square bracket notation appears about five times in Drupal core at all. And attribute function, it doesn't appear at all. But because using that attribute is very common nowadays, if you have to do it, this is how you go about it. Now why is the dot notation so useful? Because it is going to give, to do a lot of evaluations for you. In the past, the theme had to know the underlying that structure. Is this an array? Is this an object? And so on. With Tweak now in Drupal 8, that is abstracted, making the life easier for the themeer. And the dot notation is going to perform all of these checks for you and return whatever, you know, returns a value. Everything upset line number 15 is Tweak by itself. In Drupal 8, we add a little bit of more magic, if you will, to Tweak. And in the case of the dot notation, we add a final check before returning nothing. And that is, if this is a rendered array, if the variable that I am trying to print is a rendered array, call automatically the render function and return whatever comes from that. Another difference between Drupal 7 and 8 when theming is that in the past, the recommended way to add classes to the template was using preprocess functions. In Drupal 8, it is recommended now to do it directly in the template because, for one, the themeer will know which classes are available right away. And also because there are the tools and mechanisms to do it. For example, here, we are using the set keyword to define a variable. That variable is going to be an array of classes that then we are going to be added to an HTML tag. One thing to note is that when you are working with Tweak, you have all the functionality available for you. So in this case, I am building an array dynamically. So sometimes, depending on the conditions, the number of elements will be different. So in line number four, for example, we are concatenating strings. We are doing, like, sanity checks before printing the variable names. We are evaluating if the node in this case is promoter or sticky, and if that is the case, add some classes. And we can do a lot of stuff, you know, anything that Tweak provides in the template. And when we have the array of classes, we just call the attribute object. It has an add class method. We pass the array, and then we will get, you know, the classes as we want them. Tweak also has the concept of filters. So filters are used to modify something before it is being printed. The way that you work with a filter is you pass either a variable or a string or some other scalar, like a number, and then the pipe symbol, and then the name of the filter. So for example, in line number two, we are transforming a text to uppercase. Filters can also be applied using a different syntax, like in line number five and seven. So if you want to apply the same filter to multiple lines, instead of doing it, like one by one, you can just use the do something syntax, use the filter keyword, and then the name of the filter. And then you can have as many lines as needed, and the filter is going to be applied. Also, filters can be concatenated or changed. That means the result of one filter is going to be sent to the next one. So in this case, we have a variable with the name of name. We strip the tags, and the result of that, we make it uppercase. And filters can also receive arguments. And this is not a security focus session, but just for you to know, Tweak Core provides a filter called join. In Drupal, we provide one called safe join. So there are some security implications related to that. And there is actually an issue to bring the changes that we're suggesting upstream. But any time that you have to do joining in a Tweak template in Drupal 8, use safe join. And in the case of safe join, it receives a parameter that is going to be, what is going to be the separator between the different elements. And talking about parameters, they can be optional. And if you don't provide them, you will get some defaults provided by Tweak. So for example, the number format, you can define the decimal places, how many decimal places you want, the decimal point separator, the thousand separator, and so on. But if you don't provide, Tweak will use some defaults for you. We also have functions. In this case, functions are used in many different ways. In line number two, we're using a function to print a value directly in the template. In line number five through seven, we're using the range function to generate an array. And then we are using the for loop syntax to do something with that array. And in line number ten, this is probably the more interesting example. In contrast to filters, where the output is right away, like in the template where you put the filter, it is going to be printed right away. In this case, with the attach library function, we are actually adding CSS to the header and JavaScript to the footer. So when you use a function, the result of what is going to be output is not necessarily right away in the template. In here, we're modifying the whole Drupal page. And there are some filters and functions specific to Drupal. And you can find them on those links. We also have tests. So tests are usually used when you want to evaluate a condition. In this case, these are examples mostly from Drupal core. If the variable Q, which in Drupal represents the query string parameters, is empty or is not empty. If the value of a label is in one of these array, if a variable is not empty, if a number is odd or even, there are many options. Technically speaking, the only test in this slide is the word odd. The word is not in or those are called operators. But they are usually used in the context of tests. So I just grouped them together here. And this is a summary of all the three things that we just saw. So a filter requires an expression preceding some text, some variable. They can receive arguments and the result of applying the filter is always a scalar that is going to be printed right away. With functions, they do not require an expression preceding them. They can receive arguments and the return value is mixed. It can be something to print right away, like a number or a string. Or in the case of the attached library, it is something that modifies the whole page. And in the case of tests, they require an expression preceding them. They can receive arguments. And the return value is always going to be a Boolean, either a yes or no. Now, another example from core about control structures. So when you save a node in Drupal, you get a message. This node has been saved successfully. So those messages, this is the way that core prints them. There is a variable called messages, which is an array. And we apply the length filter. If the value is more than one, we print them as a list. Otherwise, we print them just like the text itself. This is the length filter is another example of how we're making things easier for themers. Because in the past, if the variable was an array, you have to use a PHP function to count how many elements are in the array. If the variable was a string, you have to use a different PHP function to count how many characters are in the string. We tweak, the theme doesn't need to know about the underlying that structure. You apply the filter and it will give you sensible defaults. So in this case, we have a nif condition and inside a for loop. This is another example for printing the breadcrumb. So this is like when you go to a page, you have like home and then the section and then the title of the page. So that is called a breadcrumb. This is how Drupal prints them. You get breadcrumb as an array and you use a for loop to iterate over each element. And then for each element, it is also like a structure. Does that element has a URL? If so, print an A tag, which is a link tag. Otherwise, just print the text. Now, let's talk about Drupal templates. Drupal templates are like onions. And if you saw the movie, you will guess why. Because they come in layers. So when we want to print something on a Drupal website, we will be interacting with a lot of templates at the same time. Let's give an example. We have a blog section in our website. And we have on the sidebar a blog that shows more articles written by the same author. So to print that, Drupal will have at least to interact with five different layers of templates. One is the theme region because every blog needs to be placed in a theme region. Then you have the blog itself. Then, because this is a listing, let's assume that we build the blog using views. The view is showing different nodes, nodes created by the same author. And then for each node, we might print the title, we might print the tags, an image, and so on. So we are printing individual fields. So it is very important to understand that Drupal will be working in layers to print whatever you want. And you need to know exactly in which layer you're dealing with to modify Drupal as you need. And I just gave one example. But just to build one Drupal page, you can actually interact with 100 or 200 or even more templates. So it might be overwhelming. And we are going to see some techniques to identify which one of all of those templates are the ones that you need to modify and how to do it. So again, in Drupal, we work with templates and in different layers. So one template will call the other. The other most template in Drupal is called HTML.html.tweak. So every template is going to end with HTML.tweak. And in this case, this is the HTML template. Five lines from the bottom to the top, we see that we're printing something. It says print page. When that line is evaluated, we are actually calling the next template in the hierarchy, which is the page template. In the page template, we're going to see that we will be printing page.something. Like in this case, page.private menu, page.secondary menu, page.bredtrum, and so on. So those page.something are the theme regions available for you. So if you ever want to know what regions are available in your template, in your theme, you can see the page template and look for page. And those are the regions. Each of these is going to call a region template, which is actually really simple. You just check, is there any content to print within this region? If there is one, you call the block template. Let's assume that we're printing a note. So the block template will call the note template, and you can continue going on and on to the field level, or you can skip some of these layers. For example, if you're printing a user, or if you are printing a view, and so on. The thing is that you will be interacted with a lot of different things. Now, why so many templates, Drupal? Well, you know, Drupal is very flexible, but with flexibility, you know, we also get some complexity. Drupal Core comes with about six or seven themes, one of which is called Stable. So Stable alone has 159 templates. So, you know, it might get complicated to find wishes that are right to modify. And I started giving this presentation a little bit over a year ago, and that number has actually been increasing over time. So I don't know if it's going to be 200 or more at some point, but it has never gone down. So when you have so many templates, what do you do? So to overwrite Drupal markups, we're going to see an example of how to do it. So let's say that we are installing Bartik, you know, a fresh Drupal installation with Bartik. When we create an article, we get a tagline that says submitted by the author on and then the date. Let's say that we want to change the format of how the date is presented. This is the recipe. This is how you are going to do it. You will enable ThemeDevok. You are going to locate the proper template to modify. You are going to copy over the template to your theme. If needed, you are going to use filename suggestions. Then you make your changes, you clear the cache, and you rinse and repeat. So you do this process over and over until you get the results that you want. And it is very important at the end to disable ThemeDevok or you might get some weird stuff happening. So first step, enabling ThemeDevok. In those links, you can find documentation on how to do it, but basically it is finding the services.yml file in your installation and modifying some parameters there. Once you do that, Drupal will be, you know, working as usual, but if you inspect the source code of a page, now you will get HTML comments with very useful information. So you get three different pieces of information when you enable ThemeDevok. Going from top to bottom, from bottom to top, where it says begin output, you see exactly which template it's being used. So that is the first step. You need to locate what is the template being used, so you already know it is in the back-partic theme, in the templates folder, and it is the node template. Another thing that you get, remember that there are different layers, views, page users and so on. Where it says ThemeHook node, that means we are dealing with a node here. If it said ThemeHook user, we are dealing with a user. Field, we are dealing with a field and so on. So that is how you know what you are dealing with at this level. And then we get the file name suggestions. So for example, in the case of a node in Drupal, you might want to modify how all the nodes in the system are presented, but maybe instead of doing that, you only want to modify the articles. So if you want to modify only one content type, how one content type is presented, you can use node dash dash and then the machining of the content type, in this case, article. And then the modifications to the template will apply only to articles and basic pages and any other content type will remain unchanged. You can also apply file name suggestions for view modes. So maybe you might have heard about teasers or full content. Those are view modes. So you can also apply file name suggestions based on that. And you can combine both content type and view mode. In that link, in the first one, you can get a list of different template suggestions that you can use. Unfortunately, there is a book in Drupal Core that not all the template suggestions are available. I checked today that it is actually in RTBC, which means that it should be available very soon. But while that happens, for example, if you're dealing with views, one single view actually provides several templates. And in that link below, you can see all the templates that abuse provides. Okay, back to the example. We want to modify the tagline. So we already know which template to modify. And if we inspect the template in line number 42, we actually see where this thing is being printed. And if we go a little bit up in the same file in lines 26 and 27, we see that we have these two variables, date and author name. And in the case of the date, it says theme creation date field. And it might not be apparent, but we actually have a problem here. In Drupal 8, it is not recommended to pass HTML directly to the template. It is better to pass render arrays. So in Drupal 7, after the pre-process layer, we had a process layer that converted the render arrays to HTML strings. And that was passed to the template. In Drupal 8, we have changed that. Now we expect to receive render arrays. Because if we receive render arrays, it will be easier to modify them in the template. If we receive an HTML string, we will have to apply regular expressions to make any change. And it is going to be really hard to do. So because it says theme, that means HTML markup. And if we want to change it, we will have to use regular expressions. So we will find a different way to do this. And just for you to know, this is actually very rare. Drupal Core, for the most part, gives you render arrays. But these two variables, they are HTML strings. And in a moment, I will explain why. So because we cannot use those variables, let's see if the templates give me another one that I could use. And indeed, in line number 10, I see that I have node.getCreatedTime. And this returns the node creation time stamp, like a Unix time stamp. So I can use that in addition with a date filter and then passing some parameters to modify, to make the change that I need. So now that I know the file and the variables that I have available, I copy over the file to my theme and I reveal the cache for Drupal to pick the new template and I make the change. So in this case, in line number 94, I set a variable, you know, node created time, filter date with some parameters. And then I use that variable to print the string. Now, for the most part, you don't need to assign variables and then print them. Usually you can print the variables directly, but we cannot do that. And we cannot do that for the same reason that Drupal cannot pass render arrays in these cases. When you, here in line number 95, we are inside trans and ntrans tags. Those are used for translations. Translation tags in Drupal 8 only work with scalar values. That means either strings, numbers, integers, or number floats. If you try to pass node.createdTime, a pipe date, the filter will not be applied. Filters and functions do not apply within the trans and ntrans. So that is why Drupal doesn't do it and that is why we are required to have an extra variable. For the most part, you just directly print whatever you need. And now we get the results that we want. Now, if you were paying very close attention in the node template, the comment said that we will use node.getCreatedTime with parentheses. But in my example, I use node.createdTime. And this is probably an overuse of tweak syntax, but I just want to show that tweak is very flexible and it will actually try to do a lot of things. So all those three lines at the bottom, they are equivalent. Tweak will try to look for a get method and call the method. So all of those are available for you. And they are equivalent. Now, a word of warning. This was for demonstration purposes only. There are many reasons not to do what I just did. One, I took the template from Bartik and you are never supposed to sub-think from Bartik. In Drupal 8, you either choose stable or classy as your base theme from the ones that Core provides. At the end of the slide deck, there is a presentation, a link to a presentation where you can learn more about this. Another reason why you might not use this technique is because when using the date filter, the server will return the language of the server itself. So if the server is in English, you will get the strings in English. But if you are working on a multilingual site, then you don't get the proper translations. So for those cases, there are modules. One of them is called bamboo tweak. I have a list of resources at the end that actually allows you to pass the Unix timestamp but then apply the internationalization process that Drupal does. Okay, now we are going to go to the recipes themselves but before one last recommendation. When working in a node template, we have two very important variables. One is called content and the other one is called node. And they serve a very different purpose. So the content variable has render arrays. As I said before, in Drupal 8, the recommendation is to pass render arrays to the template. For all the fields defined in the managed display section. So the managed display section is how you configure the view modes for your nodes. And the content variable is going to have the render arrays as you configure the view modes. And you also have the node variable. We see the node object itself. As you remember in the example, we use that variable to get that creation timestamp that is not a field, that is part of the node itself. But in addition to those metadata, you have the field values and any reference entity as a store in the database. For example, for a Boolean field, you will have either a one or a zero. So there will be some cases where using the node variable is actually very useful. And in that link, you can find a blog post by Berger, a high profile Drupal contributor that explains a little bit more about this. And in particular, how to work with the node variable with reference entities. Let's say that you have one node that calls a user, and you want to check one value, one field value of that user. So you can do, you can change this stuff using the node variable. The first recipe, how can I pass information from Drupal to Tweak or basically from the backend to the frontend? So in everything, you will have a file called, you know, the name of, or your theme called theme. So you will have to modify that file. Then you need to implement a pre-process hook. And in this case, we see lowercase hook and uppercase hook. Lowercase hook is going to be replaced by your theme name. And the uppercase hook is going to be replaced for whatever layer you are interacting with. Remember when we enable theme debug, it says theme hook node. So that is what you're going to replace the uppercase hook. And then you receive an array of variables that is a key value array. The keys are going to become the variables available inside the Tweak template. You make all the changes you can add, you can remove, you can, you know, modify, and then you simply print the variables in the template. So this is an example. Let's say that I have a node and I have an image field in that node, but I want to print in a different region that image. I want to put it somewhere else. So how do I do that? To modify the whole page, I use the page preprocess. So in this case, Nicaragua is the name of my theme, underscore preprocess, and then underscores what theme hook I am dealing with. In this case, page. When you are visiting a Drupal node, you will get a variable called node. So you check if that variable exists, and then I am doing an extra check for the bundle. The bundle in Drupal is the content type. So if this is a node of content type page, which is basic page, then I want to do something. And that something is, I am going to create two new array keys. Those two array keys will become variables in the Tweak template. And what is going to be a story in those array keys? I look for variable nodes, so get me the node, then get, fill image and fill teaser. Those are two fields inside the node, and then I call view full. Full there represents the full view mode. So if you want to print the variable using the configuration in the full view mode, you can use that. You can also change that for teaser or for any other view mode. And then you are going to be populating these variables with render arrays as configured in the full teaser or whatever view mode you are using. And once you have those variables available in your template, you simply print them. Now, let's analyze for a moment line number three and line number five. It's the same variable. But in line number three, I am calling the render filter. Why do I have to do that? Remember that when we use the dot notation, Drupal will call render automatically for you. In this case, we don't have a dot, but the same logic applies. When you print a variable, Drupal will try to verify if it is a render array, and if so, it will call the render function. In line number three, we are forced to do it because this automatic rendering only happens when you print something. If you are doing something, it doesn't happen, but what we do with here is because we don't want to print this markup if there is no value for that variable. So the content, the HTML is going to be printed if we actually have a cover title. And again, render only is called with the print something syntax. In a do something syntax, you have to explicitly call render yourself. Another example, how do I conditionally render field values based on the content of other field values? Let's say that I have a boolean field in my node, and depending on if it is yes or no, I print something else, some other fields inside the same node. So in this case, I am using the node variable because again, this will give you the raw database storage. So not field lightbox, in this case, field lightbox is the boolean field, and here it will return 0 or 1, and if condition is going to be evaluated and if it evaluates to true, I print the video in this case. Recipe number 3, how can I render an image field as a background image? So this recipe applies from Drupal 8.3 onwards. In the past, we needed to use an extra module, but because we are about to release Drupal 8.4, I don't see the need to explain how to do this. So this is the old method, and in the new method is when you go to the managed display configuration for the view mode, you now have a new formatter that says URL to image for the image field, and then you simply render the variable itself. So this is like how you do it. This is the managed display section. So you can use the URL to image format, and optionally, you can define which image style you want to use. And with this, Drupal will give you the link directly to the image file. And then you just print the image. In this case, I am using a style tag with background image, and then I print the image content that field horizontal image. In line number 2, I am using that space lace operator, and why is that? You know that the Drupal community is very friendly, Drupal is very... It gives you a lot of stuff, and sometimes it gives you stuff that you don't need. So when you print a variable in Drupal, it will actually give you white spaces before and after. And if you have white spaces in a URL attribute that is actually invalid, so it will not work. So what you have to do, you have to remove the white space. And to do it, you use the space lace operator. So anything that you put between a space lace, all the white space between tags is going to be removed. And with that, we get valid CSS and we get our image field as a background image inside the tweak template. Something similar, you can use that as an upload and then use that as an image source file. So in this case, I configure the file field to hide the label and show the URL to file and the same stuff. I have an image tag, I have the source attribute, use the space lace operator to remove the white space that Drupal will give me and print the content of the image. So in this example, let's say that you have an entity reference field and you want to use the destination of that entity reference field as a href attribute in a link tag. Let's say that in this content type, you have an image, but you want to use the link of the entity reference field. So in this case, feature content is the entity reference field, you hide the label, you make the entity reference field to point to the entity and then you need to use a fine name suggestion to print that field specifically. In this case, I am printing a field inside a node, you just print the URL. I don't want to print anything other than the URL. And once you do that, it's the same recipe over and over. You just have an href tag, an href attribute, print the content of the URL and then use a space lace to remove the white spaces. With that, you have your ATAC and inside your ATAC, you can put an image or whatever other field that you might need. So this is actually, I'm not going to go in deep. There are some things that we still need to do for make the theme layer more usable for themers. So someone asked in Slack once that they wanted to print a link to a node and how did they do it. So maybe this doesn't make any sense and I understand it's really complicated. You have to use a URL function that expects to receive a symphony route inside Drupal. Why do a themeer needs to know about routes in Drupal? And then those routes expect certain parameters. So if you ever have to do it, this is how you do it, and actually Drupal console is your friend. With Drupal console you can look for all the routes and when you know the route in particular you can go to the Drupal command to see what parameters this route expects. So again, this is something that we can improve in Drupal, but as of today, that's how you do it. Now, what we have covered so far, it's Drupal core and tweak core. But as you can imagine, we like to make things easier for the friend developers and we have added a few different types of tools to extend tweak. So as I said before, Bamboo Tweak and there are many. Some of these are very popular, others are not that popular, but if you ever need one of their functionality, they are available. And I am certain that there are more modules that I have on the slide. I'm not aware of them. So if you want to learn more about tweak in general, you can use it as a sub theme. You can see this other session by Dario Norris from Twin Cities last year. And if you need help, you can jump into either IRC or Slack. Those are the resources. And just before going to the questions, if the slide is already available, I would like to have it ready. And please rate this session. I would really love to have your feedback. And I invite you to the sprints on Friday. So the best way to learn is by doing, actually, I am a backend developer. I am on a themeer. I am on a frontend developer. Once I was tasked to create a theme in Drupal and I had no idea how to do it. So it was a long and somewhat painful process. And this session is actually the result of that first exercise. And because it was difficult for me, I wanted to save other people a little bit of time and that's why I am here today. So come and learn. Thank you very much. So if there are questions, you can come to the mic. Hi. In terms of performance, is it okay to go deeper or is it okay to play or object to get a value in a TRIG or in a pre-process? So question about performance. I know that in TRIG itself the dot notation, because it has to do a lot of checks, there is a performance there, but it is negligible for the most part. And one thing to remember is that you need to do it in a pre-processed function. You can do a lot of performance improvements, but unless you are actually certain that it is a problem, don't do it. My recommendation there is actually, there is a C extension for TRIG for the dot notation and installing that will actually improve how that works. In terms of doing in a pre-processed function, TRIG is a way to compile to PHP, so I don't think there will be a lot of difference there. Okay, thanks. Thank you for the good presentation. On slide 36 where you are showing how to set up the TRIG debug, you have cache set to true. That means you have to manually each time clear the cache. Ideally for a development set, you want to set the defaults. That way it doesn't cache it and every change you make you can do it. So one observation is about the caching and yes, I leave it as true and the reason is because even though during development, you won't have to reveal the cache every time. On a real website, you will have that turned on. And sometimes, things sleep and you get unexpected results when you have cache disabled versus having an unexpected behavior. So at the beginning, it was recommended to turn cache off. Now we just leave it on and there are arguments and issues about that. I just follow the recommendation in the slide deck. And one example of having unexpected behavior, remember that I enabled Thindybug and I said that you should disable Thindybug at the end. And the reason is when we are doing this attribute, then if we have Thindybug enabled in addition to the value itself, we get the HTML comments for the fields. You know, every variable at some point might be a field and you will get the HTML comment for that and that will render the whole thing, you know, invalid. So that's why it is better to work as if you were in production. So that might happen. I might have a first off great presentation. And I might have a tip when you enable the template suggestions, the helper, the debug function. It's pretty annoying because your entire web developer tool gets filled with these suggestions and it's pretty hard to see the structure. There is a Chrome extension, Drupal template helper that you can install. If you want to get it working, you need to enable experimental settings and enable custom theme in Chrome. But then it separates those comments in a separate tab in your Chrome so you can quickly copy the suggestion and find it with PHP storm or whatever. Can you repeat the name? It's Drupal template helper. Drupal template for Chrome is actually a helper for Chrome. It makes it a lot cleaner. Thank you. Any other questions? One more. When you have a lot of tweak statements or functions or filters using your template, it can get quite cluttered. And the purpose of tweak, as I understand it, is just to remove the clutter. Do you have recommendations on how to get those big chunks out of the template or just use variables in your preprocesses? Actually, many of the modules that I show at the end as extra modules, their purpose is to just be wrappers around a lot of filters and functions. For example, there is one called field value. It's not zero. It's something that, whatever, this field value module will actually just, like, buy field value and you get the result. So these modules are, you know, aimed to do exactly what you say. Instead of having this long change of, you know, going deep or applying filters, you have one module that provides one filter function and you can use the HTML function. It becomes less readable. Thanks. Any other questions, comments, suggestions? If not, just a reminder, I have some stickers on the table. You can pick some and please fill out a survey for feedback and come to the sprints on Friday. Thank you very much for your time.