 All right, it is 2.15 so we're gonna go ahead and get started Hello friends. Thanks for allowing me to guide you through the next 25 minutes of your Drupal con Nashville experience Welcome to next level twig in this presentation We're gonna be discussing getting extra functionality out of your twig templates so you can really take control of how your website renders I'm will long. I'm a Chicago based Drupal developer co-founder of my drop wizard with Dave and Elliot's we do Long-term support for Drupal 6, but we also do support for Drupal 7 and 8 We also have a round earth platform Drupal 8 plus to be CRM I come to see us in booth 818 We'll be there for the rest of the events. I'm a Drupal consultants do a lot of back-end development Do hands-on custom development as well as consulting top agencies maximize the results from the development team And you can find me at Kerasai on Twitter Drupal Oregon other various places around the Internet All right, so we are here to talk about twig specifically about some of the limitations of the Drupal twig implementation and how to conquer them twig is a complex system and has a lot of very useful tools that make template authoring simpler and safer a Lot of things that we could achieve with PHP template in D7 are not possible with the Drupal 8 default twig implementation these Hurdles we encounter not necessarily limitations with twig itself But rather just holes in the implementation that we have with Drupal and we can easily fill those voids Most of the limitations are due to a lack of access and freedom within the templating mechanism itself For instance, you can only render values past to the template There's no access to context or global data or the ability to load additional data There's no access to call outside functions to process the data which itself is a blessing and a curse So we can't perform database queries directly from the templates. That's a good thing But also we can't access the safe and convenient things that would actually help us do the rendering of our templates There's even very limited access to calling methods on classes and objects So your entities they get past your templates There's a very selective white list of methods that you can call in there the label the ID for instance So if that entity itself has business logic built into it Which is really a sensible place to put stuff like that. You can't use that in the templates themselves Twig allows conditionals. We've all seen this if then the looping for us or whatnot So it's got functionality to do things like that, but it gets messy very quickly Especially when we have complex logic and we have like deeply nested logic It's also common to see the same functionality duplicated numerous times through all the templates Sometimes we'll see things repeated for everybody to display mode for every entity and bundle just all throughout our themes Previous versions of Drupal we could get around this because we had the ability to add PHP directly in the templates We no longer have that ability with twig which we just discussed as good and bad But we can get around that with the twig extensions So twig extensions add functionality to the twig environment that allow us to utilize more powerful back-end Functionality while still operating within the constructs of twig. So all the all the good stuff we get from twig We have the ability to keep that and then add our own functionality into it also Twig extensions allow a number of customizations to the twig environment, but the main crux of what we're covering here are filters and functions filters transform the value passed into something else. This is an example code that's on the Drupal.org page that describes filters and functions. So we look at the View all content rendering in the first example Here we're passing a literal string to it and we're passing it through the t filter which then translates it So this is an example of a twig filter The example of a twig function would be the link from the same example We're using the path function to take the path of the front page view and to get the URL to that And we're going to use it as the href for the destination in the template Core provides a handful of useful filters. These would be used with the same syntax. We just saw the filtered The value we're going to filter at the beginning and we have the vertical pipe and then we have the filter itself There are also a few functions Provided by core these are all fairly straightforward if you've been working with the twig tablets Of course, I'm sure you've seen these filters and functions throughout the templates So as we saw core provides useful filters and functions, but it's not necessarily a comprehensive set To really get the functionality we need to do some efficient theming. So let's take a look at some contrib options Twig tweak is probably the most widely used module for providing additional twig functionality. So this is the twig tweak Has a set of filters and functions You can see the filters here that it provides Most of these are probably familiar if you've been working with Drupal for any time You can see it even provides a throwback to our nemesis the PHP filter Luckily, this is disabled by default. You have to proactively go in and turn on that functionality The image style is useful. I've written similar implementations to this before this was available as a part of twig tweak The check markup runs it through an input format. So if you've got input format set up to Process your text do whatever before it hits your web page You can do that right from your templates and Then there's also a view filter which can take it either an entity or a field and then it will render it right in the template Twig tweak also provides a whole slew of functions Some of these are quite literally duplicates of the filters. We just saw so the same functionality is Collable via either syntax So you could do it with the pipe in the filter or you could do it through a function that we pass arguments like this The it's got functions for inserting views forms images rendering blocks and regions and templates where those aren't necessarily available to you You can load arbitrary entities and access fields on arbitrary entities We can work with config links and debugging of values in your twig templates Take a look at the twig tweak project page for additional information as a cheat sheet That while I'll talk you through exactly how these work what arguments they need to work and how to get the most out of those And also related to debugging who in here uses the develop module Okay, I feel better So I'm not even sure how I found it But at some point it came to me that Develop actually provides a twig extension that provides a few things one of which is a break point an XD bug break point So you can just throw that right into your template and your XD bug debugger will stop in the middle of your template as it renders And you can see what values are available for you So that that was incredibly helpful to me as I started my journey into twig was to be able to stop it in its tracks And see what exactly it was I had to work with In terms of Drupal modules, there's also the twig extension Drupal module which provides integration for the twig extensions project into Drupal's twig environment. So the twig extensions project is not a Drupal project It's a project is supported by the maintainers of twig itself and is very popular among PHP at large it's reported a 22 million downloads. So it's it's a thing that people use It provides various filters and functions to handle arrays dates internet intern as a flat I'll get it internationalization in text So what do we do when we want to get more out of twig? If you're a developer like me, you're you're gonna roll your own So there's two basic parts to creating a twig extension. The first part is to add a service definition So here's the example from the twig twig module There's really nothing all that special about it. It's just a very standard service definition The main point of this is it's tagged with the twig extension tag and by doing that It allows twig to find your extension. So all of the twig extensions are tagged like that twig Finds all the services that are tagged like that and automatically utilizes them in the Drupal's twig environments Next we'll actually need to create the class. We just added to that service file. It's just a regular PHP class You're gonna extend the abstract twig extension class. It's got basically empty implementations for all the methods it needs From there, you just define which filters you're gonna provide and which functions are gonna provide the actual return value of these is an array of either filter or function objects and That the filter and function objects are essentially just relations between the twig syntax and then the code that gets executed When that twig is processed. So here's the implementation from the twig tweak Once again, you're just providing an array of the filters that you're making available to the tree templates The first argument is the name of the filters. That's the part after the pipe The second argument is the code that you're sending into the filter filters Optionally can take a set of parameters also in a kind of similar syntax to functions These examples all call methods that are contained in the twig extension That's what you're seeing with the array syntax that first The first element in the arrays this referring to the class itself, which is the twig extension and then the method that it calls It's also possible to call a function directly And then the output of the code that gets called just needs to return a string or anything that can be cast to a string So the functions method is very similar to the get filters method except it returns function objects You can see once again It's got the name as the first argument and then the code that's going to get called as the second arguments And if you look at the top two elements They these are examples for embedding a view and accessing a views result these called PHP functions Directly from the views module code Just because we now have the ability to do more with twig it doesn't always mean we should So here's a few thoughts on how to do twig extensions the right way to really Get the most out of them and also do it in a sustainable manner So start off by using filters and functions for keeping things simple Move complex logic out of your templates and into your twig extensions or elsewhere Raw PHP is generally easier to read for humans and easier to debug and test Consolidate your logic as much as possible. This notion isn't Specific to twig. It's ideal to only ever have one implementation of any particular function or algorithm If your logic is specific to rendering it may make sense to put it in the twig extension Otherwise, it's probably more useful to put that logic somewhere that it can be used elsewhere in your code base Like a service for instance Then you could expose that service to your templates via a custom filter that is essentially just a wrapper Passing off to the call to the code where it lives Also, maybe more of a pet peeve, but as a beggin practice to help future-proof your templates I think it's best to access data directly off of your entities. So for instance in your node templates Access the node variable not the content variable It's inefficient to render the content of the field value and then strip it back down to the original value Using the rendered field value also leaves you vulnerable to unexpected changes to the way the field renders over time. So updates to Modules or even other templates and things like that could impact the way your field renders which would then impact the values that you're using in your twig But most of all I'm sure some of you out there feeling they've given you a big ol hammer and everything is looking like a nail right now Don't get crazy with it Keep in mind that when you add filters and functions to your templates The extension is then quite literally a dependency of your templates this custom extensions You've written is necessary for your template to function You're effectively tying your templates to Drupal and tying them to that custom extension Anywhere your template gets used your extension must also be available a lot of cases. This may be okay If you're just running Drupal on its own And no plan to reuse these templates on other projects or outside of Drupal or anything like that. It's probably Usable scenario to go a little nuts with the templates and Functions and filters provided by the extension But if your templates are shared with other parts of your development process particularly like a style guide or a component library You want to find a way to suitably abstract that functionality out of the extension or find a way to make that extension available In all these other places that are going to use the templates So I'm going to start wrapping it up now Here's a list of the resources I've mentioned You can find the raw documentation for twig that covers filters and functions and a number of other things in more detail on the twig Documentation just at a note Drupal is using twig version. I believe it's 1.35 right now The most current version is to so you may have to click your way back into the proper version of documentation so these links are on the Session page on the Drupal con website And then I will also get these slides up shortly if you'd like to review them later All right. Are there any questions? Yes So the the most practical example of one that I've non-custom was the image style one So if we wanted the URL to a specific image style You would write Twig extension that uses the image style code from Drupal core to get that URL and Provide it to your template What I was mentioning when I was covering some of the twig tweak stuff is that twig tweak actually provides that now So in the past it didn't used to but recently it's been added So you have that functionality to get URLs to the image style Writing a template There's also a number of other functions I've written We saw how the views and embedded stuff provided by a twig tweak What I've done there is I've wrote some very simple basic stuff that allow you to take like a list of arguments So take like if for instance, you had any reference field and you wanted to pass those into a view You it would be able to collect these the IDs of the entities Collapse them into a string that is an acceptable views arguments for views and or views or type of contextual filter And then it would it would execute the view with that argument Yes Yeah, we've we've been using twig more and more for Trying to put some logic in places where it doesn't like in the UI in certain areas So I just want to say I'm doing a buff tomorrow from one to two upstairs on extending twig to other places like Using it in content moderation notifications So you have conditional logic and Using it as an alternative to token Possibly doing it with like some dynamic views filters and some other tricks So I put that out there if anybody wants to contribute to that discussion or effort very cool. Yes So the question was how does the custom functionality relate to caching? so adding aggressive filters and functions If there's any concerns with the caching of the output of that I'm gonna say generally There's not a huge concern, but particularly with Things like we saw with the twig tweak where it's implementing views and different things like that those Have their own caching built into them for one, but they also have They are presented back to the template as like a renderable item Meaning they have their own caching metadata built-in to their to the output from the views code And at that point that will bubble up to the page level as needed I think the use case for a lot of this is really just taking duplicate code out of your templates So if you've got to some process Probably mostly business related if you say you've got two two fields on your entity You kind of have a main one and then a secondary one and one has precedence over the other You just want to put them in your template. So if one's there you it gets used if not it falls back to the other one This would be a way to do it and you'd be able to consolidate that logic Into other places where it gets used so you'd use the twig extension to implement it in your templates But that would really just call other code that gets used elsewhere, right? so one of the strategies for Avoiding going nuts with the sprinkles is to use twig includes so on your like an entity template for instance You wouldn't actually render markup through there You would basically just use that to kind of set up variables And then you would include the actual template that you want to use the variables So when you're setting up the variables you call all of your Drupal specific twig functions And then pass that off to the very like generic template So we had some type of mind reading happen between So the the question was How does this relate to preprocessing in D7 as a preprocessing still is available in D8 I Think the kind of general consensus is that it's just clunkier than being able to put just a little piece of functionality in your twig template. So I mean You can do whatever you want with the preprocess just like it was but In terms of reusing it across different templates and things like that at that point you then have to implement a preprocess hook for each case of this And even then you you could consolidate that function that to where all these number of preprocess functions calls So it would still consolidate it But you still have an implement all those hooks in your theme and then the the twig extension is also not tied to your theme So if if it needed to work across multiple themes or multiple projects or what not it could certainly do so Just wondering if you could dig into the access property or not accessing The entities rendered and the values like can you dig into that a bit more? Sure. So in the core templates Well, what we see a lot is content dot whatever And I guess I should back up a bit a lot of them just render the content as a whole So the content is just an array of the things that are Renderable in the content so the when you enter the entity it runs it through the entity view mechanism Which basically just turns the entity into a giant renderable array and that's what goes into content So when I was discussing the node variable, that's the actual node entity When you work with it you set the properties on a set field values on things like that the content variable is that renderable Version of the entity that has all the fields set up Per how you have it configured in the UI Did that answer the question? Sure Sure it so the follow-up was that it can be challenging to find What what the heck it is you're looking for to for the for the value, right? It's like this process. Um, I found there's a lot of trial and error in the beginning Just kind of pick it up over time But but also it's it's similar to how you would do it in PHP code in the back end It's the same structure. It's just with the dot notation instead of using the objects and the properties and methods on the object Appreciate everybody for coming. Please do leave some feedback on the session node. There's the the evaluations that are there I'd appreciate feedback positive negative whichever not gonna hurt my feelings It's on the session page on the Drupalcon websites and have a great rest of you Drupalcon. Thank you I Yeah, so I just wanted to so like