 Okay, welcome, DrupalCon Prague, day two, good stuff. This is core conversation about the history and future of Drupal theming. Hopefully you enjoyed the session description. I hope this is as entertaining as the session description is. This is based on a session I gave at a Drupal camp a few months ago that was more about the history and it was more a narrative of how we got to where we are in the theme system. And it didn't have a lot of like forward-looking what's next stuff. This contains less history and more forward-looking stuff because it is a core conversation. And hopefully we'll have plenty of time to have like what about this, what about that. This is, I will say this too, it is rated as an expert level session. So it assumes you know a lot about the theme layer in terms of the architecture and how it works. And it's also not much about like HTML but more about like the underlying systems of like the theme registry and things like that. So if you feel comfortable with that stuff and you feel comfortable a little bit with object-oriented code, then you're in the right place because we're going to kind of talk about those kinds of things. We're also going to talk about render API. And if that seems boring or intimidating and you get bored, you can leave and that's, I won't be offended, I understand. Because it is a very hard subject. So my name is Carl Wiedemann. I'm C4RL on Drupal.org. And I have worked some on the TWIG initiative, especially at the beginning. And I've been working more, well I haven't, I've been a little quiet lately, but I'm more interested in kind of the future of render API. And this is actually going to talk a lot about render API going forward. So my goals today are to talk about where we've been, where are we going, and then have discussion and planning and see like who might be interested in this or questions you might have about the future here. So I'm going to go kind of year by year and discuss what has kind of happened. What did we get in Drupal over the years? If you go back in the commit history, you can look in the get history all the way back to the year 2000, which is kind of fascinating about get and just the get migration. And you can see some of those first commit messages. And we actually did have a theme system in the very first incarnation of Drupal. And the idea that existed from the start was having an overwriteable system. And so throughout the years I'm going to talk about kind of ideas that we've come across and that we want to preserve because not all our ideas are bad. Some of our implementations are bad, but not all of the ideas are bad. So we had overwriteable markup. In 2001, we were able to provide default markup. That is you would only have to override certain things and that other things would be provided by default. For example, the node module provides default node markup. So that was something that didn't exist in 2000. A theme had to describe every single thing that possibly could be rendered on a site. In 2002, we actually finally had the theme function as kind of an API to get into, okay, how do I actually create markup? How do I pull things out on my own? And in 2003, everything before then was concatenated together. And we still have some concatenation at existing core, which is not that easy to use, especially if you're a newcomer because you don't want to dig through a PHP file. So we first had template-based theming back in 2003, and it was a system called X-Template. Has anyone used X-Template before? Wow. Oh, well, he doesn't count. X-Template is not very powerful. And so in 2005, PHP-Template came along. And a lot of other things came along, too, in 2005. This was kind of our first modern theming system, as we had templates that had logic in them. We could override the variables that were sent to those templates. That's what's called preprocessor functions now. People familiar with preprocessor functions? Good. And then a form API, which wasn't related to theming yet, arrived. And altering arrives in concept, the idea of a form alter and providing an API for people to abstract structure. Eventually became very important in the future. In 2007, we finally had a theme registry. It was a lot more performant in terms of keeping track of the templates that were being overridden, the functions that were being overridden. We had preprocess functions in name. That's when they were finally called preprocess functions. And we had template file overrides. You could describe those yourself. Also in 2007, this has to do with kind of the form API world is we finally had hook elements and the idea of structured versus rendered data, which brought together the idea of the modern render API. And so this is what we saw in Drupal 7. And before this, we didn't really have render API. We're just kind of concatenating strings together. How many people were Drupal 6 developers? Yeah, so you just had strings. You just mashed them all together and it was kind of a pain. And so this started the phase called alter all of the things, which is where you had the page array and hook node view and things of that nature where we wanted to abstract structure. And the way that we do that in Drupal, like we do everything else in Drupal, is we just build up this big associate of array and hope that people are going to dig through that whole big thing. And that seems like an okay idea to start with. It's kind of like when the only tool you have is a hammer, everything looks like a nail. And so when the only tool you have is an associate of array, everything you build is an associate of array. And so there's this. This is kind of the famous comment back in 2007 about how we should be returning structured data. And so this is the big shift that happens. And if you're a Drupal 6 developer, a Drupal 5 developer, you remember this. And then in Drupal 7, we were supposed to do this. But there was actually a lot of this living in Drupal 7, unfortunately. And so by this time, we had hook page alter. We had preprocessor functions. We had global preprocessors. We could override templates. We could override the preprocessors themselves. We could override theme functions. We could actually change the theme registry. So we could register different templates or functions in there. And this was, by 2009, we just had this big stack of APIs. And they were all brought in for good reasons. But by different people and with different intentions, it was very inconsistent. It was very difficult to learn. And around this time is when you've probably seen this picture. And maybe you've seen this version too. But this is John Albin Wilkins basically describing what the theme architecture had become. And I think what's important to realize about Drupal's theme system and maybe Drupal itself and maybe even just kind of a lot of open source projects is we have systems that no one sits down and designs. No one sat down with this and drew it up and said, this is what we're going to use. This came about over years and years and years. And there are things that we have, there are ideas that are part of the theme system that have been there for a long time. And it's not the ideas that are bad. It is the implementation of those ideas. Yeah. Put that on your... Remember that. So I think we reached a time around DrupalCon Denver. There was a core conversation about how screwed up the evening was. That I think is what, where we first saw this graphic. And it was this time where we said, we really have a really hard system. It's so brittle. What have we started over? And so I think this was brought about this idea based on what we've built, what do we need? And I'm kind of going to distill this into three things that I think we need, but we can talk about this. This is a core conversation if people have other ideas. I think we need kind of three basic things. We need template-based markup that can be extended and overwritten. That's pretty basic. The things that we invented to give us that were things like hook theme, preprocessors, theme hook suggestions, theme registry, twig, what used to be PHP template. All of this is for the idea of overwriting and having templates for markup. We need an abstracted, alterable structure. And this is what came out of that comment by Barry Jasmine in 2007. And so this was what gave us render arrays, what gave us hook node view, hook page alter, things like that where we have this renderable thing that we can pass around. When you create a block, you return this abstracted structure. And I think the third thing we need is a sensible, accessible API. And this is really the big missing part. And we've had some kind of things that have tried to give us this. I mean, the theme function, Drupal render, render hide and show have kind of been tools in order to deal with a lot of the underlying architecture. But I think the underlying architecture is really the big problem. And as nice as twig looks, there are certain things that we just cannot do easily because of that underlying architecture. And so we had a core conversation in Denver. The twig initiative was started. We had one of the biggest sprints in Portland I've ever seen for twig. There's a cute, you know, the enthusiasm about twig is awesome. But there's still a lot to be done. And we've done some great things. We've killed the process layer that was part of the theme system. We're cleaning out markup. A lot of people are excited about twig, and it's a good thing. So all that's kind of where we went. There's some current issues I want to talk about. That's kind of where we're going. And then I want to talk about far kind of looking ahead. And I hope that is interesting to folks. So these are some kind of current issues that are on my mind kind of, I think, in increasing importance to me personally. There's probably some other ones that maybe you guys have seen. And I'll just, I'm going to jump to d.o. to talk about these things. So the famous node 1757550, one of my favorites. This was the big... Oh, let me go to that node. Here we are. Convert the core theme functions to twig templates. So this is still active. A lot of this was the basis for the sprint and the entire twig initiative. A lot of this is done. There are a few things left. And we have a great momentum on here. Scott Reeves, Fabian X, Jim Lampton, Joel, all those folks have done awesome work here. And I've worked on this quite a bit too. So this is just finishing up. When I say kill concatenation, I mean we want everything to be in twig. Twig is a template-based system. So no more concatenated markup. We want that to go away. And hopefully we can make it performant enough so that it can go away. Question? Can you just offer an example? Sure, so the question was an example of concatenated markup. Let me actually... Actually that would have to be D7. Well, I just need to open the code base. So in theme.inc, like theme table, oops, oops, sorry. So theme table is an example of when I say concatenated markup, I mean we're concatenating a big string together. There are lots of things in theme.inc that do that. Theme table, theme item list, theme menu, some silly things, theme username. That's hard for themeers to use. That was one of the big motivations for twig, is to make that more accessible. So that's happening. There's a lot of good momentum on that. Some of you who will be at the sprint this Friday can check that out. The next one I mentioned I think is theme system architecture changes. This I think is happening and is contingent on a few other things. But did anyone go to the twig talk yesterday with Scott and Jen and Fabian? Anybody go to that one? A few people? Okay. What we'd like to do here is make the names of the current functions a little bit more clear and maybe change where they are executed. So a lot of this has to do with when we use suggest templates for a given theme callback that is actually done in a preprocessor right now. We want to take that out into its own API so you can suggest templates elsewhere, which is really important because a preprocessor is at run time and that needs to run before then. It should be part of the registry. Other things here is changing the name of a preprocessor to called prepare, which is actually what a preprocessor is doing. The problem with the word preprocess is it means different things to different people. To a themeer it means I'm going to change things that are useful. To a developer and someone who cares about the execution stack it means there's possibly a necessary layer of functionality. That's what, you know, preprocess. That's what we actually process. So that I believe is in progress. I don't know if there are much patches here. I think it's a lot of discussion right now. But this is definitely something that... How many comments we got so far? Oh, only 35. Easy. So that's going on too. And I think that is something that we're hoping to get into D8. The next one that is related to that that I think is a little stalled is rewrite theme registry into a proper service. A lot of the theme system has not kind of been pushed into the kind of Drupal 8 paradigm of having, you know, services and plugins and these things that are kind of more abstracted and things that we can move around better. For example, there's this function called theme init. And theme init is actually called... The first time you actually call a theme function. And that actually creates, you know, figures out what is the global theme configuration stuff. And that's called when you call a theme function. So if you call a theme function in, like, hook, boot or something like that, sometimes really weird things can happen there. So this is an effort to abstract that better, bring it up to speed with Drupal 8. And I think there's been mostly chatter there, a few patches, but some, like, do we need to wait on something else? So there's some other issues that are contingent on that that I won't get into the details of. Interesting thing, too. This is kind of my pet issue in the last few months that I unfortunately haven't had a chance to work on that much, but I've got this army of people, well at least one guy who's awesome working on it. And what this is, is this is trying to solve... Where's my slides? Hello. One second here. I lost my slides. Well, that's how it goes. Shoot. I just had them open. Yeah, yeah, yeah. Let me actually... I never do that before. Maybe there's an open recent? It's somewhere... It's in the cloud. Who knows where it is? Okay. Sorry, to the cloud. Where is... Let's try this again. Full screen. Oh, yeah. So what I was saying is there was a lot... See this top thing? There was a lot of this left in Drupal 7, which wasn't supposed to happen. Everything was supposed to be this. Everything was supposed to be the nice array. And so there's all this pre-rendering of markup going on. And so I actually did this big grep, and was like, this is silly. If we're going to fix Drupal render, which is kind of my pet project for Drupal 9 and you're going to hear all about, we need to fix this. And so that's what that is. And so a lot of that is done, which is great. There's a few other things that need tests, but that's awesome. For Drupal, you just get people excited about something and they go and do it. Full screen again. Four fingers where? Where does it work? Oh my gosh, all right. I'm not used to this thing. I just got this computer. It's a new one. Okay. So those are kind of things that I feel like are important. But in Portland, aside from just the weather there, there was this kind of cloud that came over me about the twig initiative because one thing that twig tries to do and wants to do is give us a drillable structure in the template. And so you have a variable and you want to drill into that variable. So content.image.source and to be able to drill through that thing. That's not something we've had before. It definitely doesn't exist in Drupal 7 and it's probably not going to exist in Drupal 8 as nice as we would like it to. So that became this very bothersome thing to me because I know there's going to be a lot of people coming into Drupal because of the symphony things and the twig things. But really that is due to a brittle render API. And so I believe that for the future of Drupal theming, the biggest thing we have to deal with is a brittle render API. And the second point of that is I think render API must move to an object-oriented design if we're going to make any progress here. And that may not surprise many people. A lot of things in Drupal are moving that way. A lot of things in a lot of frameworks as they evolve move that way. So this is an issue that I started around that time and I don't think it's not going to happen for Drupal 8 but I think we'll become a meta issue that I plan to focus on quite a bit and I'd love other people's help for Drupal 9. And let me actually show you kind of what inspired this. I don't know if anybody saw when I tweeted this but this is basically where render API has taken us. And if you are a themer or if you're someone who is just looking at the data structure of what you get when you are given theme variables, this is a lot. And the problem with this is everybody just puts things in here and they're just passed along. How many people have to have to dig through this stuff? And isn't that just like you find it and you're just like why, why, why am I doing this? And like this has... Some of my participation has dwindled a bit because I'm trying to kind of not think in this world and there are a lot of kind of workarounds where we still have to add these little hash parameters that are going to call callbacks and stuff. But we can see things in here. Maybe you can read some of this stuff but here's an example. We're passing view mode, we're passing state which are properties of the node itself and like why is it on field picture? It doesn't make any sense. Field pictures should talk to the node and say what is your view mode if I am a child of you. We have properties here that have vastly different impacts. For example theme versus title. Title is just a string. But theme is actually a callback that this whole thing is going to be sent to. It's kind of like a method if you're thinking about object orientation. We pass data in this thing. It's like the field should know it's a part of the node. It shouldn't have to include the node as part of that. We see a lot of references that are passed through here. Some things aren't passed by reference. There's duplicate information. We have items and then we have zero. And the children of items are the same as this and why are they the same? Yes sir. Right. Sure. I just want to mention. I asked you this week. Exactly. Yeah. And so when all you have is an array, you have to use array like things to get information out and in. We have entity representation of its array. For example this is a file entity which exists in Drupal 7, but it is an array of things. The data in this actually lacks any relevancy to the rendered state. So we have public, but we have to pass that to URI to resolve that into a source. And so you can get what you want. You just have to really dig. And it's a lot of work. And I don't think anyone is going to defend this as good design. If you want to, feel free to take the mic and that'll be an interesting conversation. But this is really bothersome to me. And so my pet issue now is oh, wait. There we go. I learn new things all the time. Okay. Is this node? 1843798. And this right now is a meta issue, but it's about refactoring render API to be object-oriented. And so I want to take it just a few minutes to talk about what that looks like. I also have a GitHub project that you can dig into the code. If we want to dig into the code, we can do that. I don't know how enthusiast people are about that. Or we can just talk about theming issues, theming problems, things that come up, what should be easier. The code that I have on this GitHub project, I haven't thought a lot about API in terms of like, what do people want to use? I'm just thinking about design. Like, how do the internals work? I think one thing that successful frameworks do is give kind of a non-intimidating API and kind of more detailed methods. So, you know, one thing that comes to mind is like jQuery. JQuery, you have like the slide-down method, but then you have the animate method, right? And so you have this kind of abstraction for the sake of learning. You also, you know, the get method versus the AJAX method. And, you know, they're higher-level APIs. So in terms of API, the implementation of that, that's an open book right now. I'm just thinking about what does the design look like. So I bring this up in the render API issue. This is what I just talked about is like content.fieldimage.zero and then you want to build your own image tag in Twig, right? This doesn't, we can't do this yet. I would love to be able to do this. But you're going to have to set up that source in a preprocessor and then pass it to the template. The reason we can't do this is, bear with me here, field image. So this is, let's say this is in a node template. Field image has a separate template. If it has a separate template, it has a separate preprocessor. If we are in the node template, we haven't drilled down to that yet. And because we haven't drilled down to that preprocessor yet, that preprocessor has not created those variables yet. And so those variables don't exist. I can't, from the parent template, drill into this. I can't get to attribute source because it hasn't been made yet. So I have some ideas about how we can do that. I don't know if it can happen in Drupal 8. It's very hard to do when you have these arrays. Maybe it could. I have some other examples on this node where it's like, let's say, you know, instead of building the image tag itself, you just want the first image using a field formatter. Maybe you want all of the images from the field image. Maybe you just want all the content. Or maybe, you know, and then here's another example where, you know, I say, you know, this goes for everything. This includes links. This includes, you know, dates and a lot of other stuff. So I kind of started thinking about, you know, what this could look like in Drupal 9. And I have a few meta tasks and there was some chatter. But this is relatively new. And I would love some help. I have some thoughts on this. And I've run a few ideas by a few people. But that's kind of my next pet project. And I was going to talk about what this looks like and people are interested, but there's a question. Go ahead. I was just going back to what you were just talking about. This may be a huge can of worms in terms of what templates are gotten first. And I really haven't dealt with this and so what I'm suggesting might be total crap. Okay. Hey, I just remember this. Can you actually talk to the mic because we're recording this? I'm sorry. I forgot. Okay. So first caveat or disclaimer, I haven't researched the whole templating system and the bigger templates, the smaller templates, but when you're rendering a page, it just occurs to me that you kind of know what you have to drill down. Could you, theoretically, drill down first, know what all your bits are going to be, what your building blocks are going to be and where they're going to fit in. Get those first and then as you build that up, you could do exactly what you were looking to do. Yeah, definitely. So does everyone understand the question? The question is like, well, if you have everything there, why can't you just drill everything and then access it? Part of the reason that we don't do that is we don't know what we want to render and we want to avoid unnecessary processing. So for example, you could have this big render array and maybe you're only going to render, like, let's say things have assembled all these pieces. So let's say you're rendering a node and let's say the node has a whole bunch of fields, but in this particular display, you only want to show the first field. You only want to show that one, okay? Because you have that information. Well, hold on a second. Just let me talk through this. So let's say you have it, but maybe the preprocessor is doing certain things. The preprocessor is creating classes that it's going to exist on that markup, but we don't want to waste processing power, processing all those classes for all those fields if they're not going to be displayed. We only want to do it if it's going to be displayed. And that's why render goes outside in. It used to go inside out, but now it goes, does that make sense? Like I said, I don't have enough background. Sure, okay. Do other people kind of understand that concept? Is we want to do late calculation of template variables because we may not be ever displaying that? Yes. Isn't Twig doing that automatically? Well, so Twig gives us some advantages here. And that was something I acknowledged in the drillable issue was to say, you know, look, we may not be able to do this for all theming engines and render API itself, but can we get this working in the Twig theming engine? I think that is possible. I personally don't know enough about Twig, the Twig engine, to say like, can we figure that out? If Fabian were here, he would say yes, and then he'd give this long explanation that I wouldn't understand, but he might be able to do it. I would love to do it in the API. You know, because of the third principle I said, I want something accessible that we can drill into whether we're using PHP template or whether we're using Twig. So here's what this might look like. Now, this is just something that I've thrown together. How many people have done like a bit of OO? Some folks? Okay. So I'm going to just talk about two kind of very vague, two design patterns that have been influential. How many people have worked with design patterns much? Okay. So two of them that I'm thinking about for this are builder and decorator. And I'll describe kind of what these are vaguely and how they would apply. We'll talk about builder first. The builder pattern is that the creation of an object is delegated to a series of steps and then finally invoked. So you kind of get all the ingredients together and then finally you invoke what you want to create. You don't create it right away and then add things later. You don't give everything at once and then create it. You do things step by step. It's similar to a factory pattern. The only real difference is kind of philosophical is that builder doesn't assume you have all the information to start with. Factory generally does. But the difference is kind of not that much. So this fulfills the data storage component of a renderable. Here's a very simple factory. We have a car builder. And the car builder takes parameters about the car. And maybe it doesn't want to make the car right away. It wants to get things and talk to other systems. And then it's going to build the car at the end. So this is a very silly kind of example. But this is, I think the builder pattern are kind of builder-esque. Drupalisms we have are like the render array itself. Building up this render array like hook node view and hook page alter is that we are adding things to this big array. And so we're building on to that. And once everything is there, then we render it. So that feels like a builder to me. The next pattern I want to talk about is decorator. The decorator pattern is that behavior is added to an object dynamically at runtime without affecting other objects of the same class. And I feel that this reflects runtime variable preparation. So basically preprocessing is a decorator. Here's a decorator example. I'll just kind of run through this. I have a coffee class that says I'm a cup of coffee. And then what you do is you create a separate class called a decorator. And what that is going to do is that's going to take the coffee object, you pass it a coffee object, and it's just going to delegate methods to that. So it's kind of like a delegator. Then what you do is you create two decorators that call the parent, that basically extend the parent and say, oh, I'm adding this and I'm adding this. And then what you do is you decorate your original object at the bottom. So I'm saying I'm creating coffee. I'm going to give it sugar and cream. And what that does is sugar wraps the original. It's going to call the original. It's going to say I am coffee with sugar. And then cream wraps that. And it's going to call the parent, which is sugar. It's going to say I'm coffee with sugar. I'm with cream. That's how that works. That's basically a decorator pattern. It's going to be creating functionality there. The reason I feel like this is like a preprocessor is that if you're familiar with preprocessors, you know that we have every module in successive order is wrapping the variables that are sent to the template. So comment comes and then node will come and then other things will come in and wrap the variables that's being sent to whatever template you have. Finally, your theme comes in and at any given point you can change any of those variables, but we're wrapping everything with more and more functionality. So that feels kind of like a decorator to me. These are builder and decorator are kind of similar and they could be interchangeable. Both of these, Drupalisms, I think could be reflected as either one. I just want to show kind of like a sample implementation of what this might be. So here's basically our render process. This isn't changed. This is what a website is. We get our data. We define a renderable. We alter the renderable if we need to. That's our hook node view and hook page alter and things like that. And then we render the renderable, which we're going to call theme callbacks. We're going to call preprocessors. We're going to call formatters, which are actually just theme callbacks, and then invoke a template. And by that point, we have a bunch of markup and then we send the markup to whatever client we need through whatever delivery mechanism. And so the builder kind of comes in here in the alter phase is where we're going to kind of call out to our modules and say, I have defined this base. Maybe it's an empty page. What do you want to give me? You want to give me blocks? You want to give me nodes? You want to give me a view? Great. And then in our preprocess phase, that's when we say, okay, I've got, I've built up the variables. How do you want to change those? How do you want to improve those? How do you want to give me more functionality? Okay. So I'm going to show some code. And I know that in Drupal, we love to say, well, I don't like how that's named or can you change the hyphen to a dot like let's not worry about that too much. This is just kind of about ideas. And I know that's really hard to do and we all do it, but let's just maybe think about, here's an idea that I've had and then you can write me nasty messages on the GitHub project if you want to get into it. So here's kind of what I'm thinking. Here's a very simple example. So D7 and D8, we have our render array, right? We're going to theme node. We're passing a variable called node. That is some node object. D9, what I want to do is have a builder. That builder is eventually going to create something that will be themed. And that's going to have a class, but I don't want to create the class right away because I might want to change what that class is. That's the equivalent of like, in this render array, maybe I want to change what pound theme is. Maybe I want to alter that to be something else. So with a builder, what it allows you to do is the final delegated state of what the renderable will be is pass as an argument. And so the builder takes, what do I want the final themed output to be? And then what are my variables here? And we don't have to use hash anymore. We just say, give me a node. This is what altering would look like. So, okay, I have a renderable. I'm going to assume we're still going to use kind of hook node view and altering hooks. Maybe we're going to change that, but I don't know if there's any effort to do that. Here's what this would be. Like, here's hook node view, right? So you have, you're given a node. You have the content array. On the image field, you want to change the theme callback to foo. And that's going to call theme foo on that field. Here's how it might work with the builder. So the builder is passed to some view alter, maybe called node view alter. Maybe it's an alter on whatever renderable you have. The builder has a method to get the image parameter. It's going to set a build class. That's just overriding this first argument here. So I said, you know what, instead of this renderable using theme node, I'm going to use theme foo. And that's going to change the finally invoked renderable. And I'll show you what the invoked renderable is. So once the builder is done, it's actually going to create that thing. It's going to create something called theme foo or theme node foo. And that is going to be something that has a template that has a preprocessor. It's basically what a theme callback is. A theme callback has a template. It has a preprocessor. It lives in hook theme. What used to live in hook theme is going to be a class. Maybe. Maybe it is. Maybe it won't be. This is how it could work. Here's how preprocessing variable preparation worked in D7 and D8 was at a preprocessor. And you said, new title. I want to change. So these are the variables that are in the template itself. I want to change title to be something else. I'm going to set it there. And this is the problem with arrays. You have to know the structure of the array. You have to dig into the array to know what it is. And with objects, you just now have to know a method. You say set this to be this. And then forget about it. You don't have to know the structure. So this is what a theme class could look like. Theme foo extends a renderable. A renderable is an abstract class, which means it's never invoked. It just has child classes that extend its base methods. One of its methods is prepare. That is basically a preprocessor. And then here you can say, get my node, get the title, add some text to it, and then reset the title. Title being the title that is in the template. Question. So this is great. I know. This isn't in Drupal today. Can you say it into the mic and say it again? Sorry. I didn't quite understand what you meant. Oh, hello. That's hot. Hello, Chris. Yeah, I'm just saying a preprocess isn't only available for one person. Sure. But in any case, it would be here. Well, this is going to be decorated. So this will be decorated. And maybe that will be answered as I talk some more. OK. So the rest of this, I think, goes into render API. But the idea is that this is going to be, so in, for example, node module. You have template preprocessed node. That sets up the base variables for node.tpl.php. And then you have my theme preprocessed node. Those are the decorators. And so we'll have decorate classes that go on this. So anyway, if you fire up your GitHub and go on over to github.com.c4rl.render API, you can see some examples of this. And I'll just show a little bit of the code. But then I think we should go into questions and stuff like that. So what I have, oh my goodness. Hold on a second. Here we are. OK. This right now is not hooked up to Drupal. I have a directory called fakeDrupal. It fakesDrupal. It doesn't do anything. It's not a content management system. Here I'm doing exactly what I was saying before. I have a renderable builder. I'm going to invoke this class. And here's a node. So this is like a dummy node. And fakeDrupal has a fake node module. Fake node module just returns like a silly thing. Here's fake node module. You ready? Yeah. So the idea here is we create the builder. And then we have like a deliver function. This is like the page delivery mechanism. So in fakeDrupal I have something down here called deliver. What it's going to do is look at our built thing. It can be an array of renderables or it can be a renderable builder itself. It's going to call something called create. It's going to build the renderable. If I go into the renderable builder. So I have something that takes the build class. It takes the parameters. There's some setters and some getters. Very simple. And then what it's... And this is basically our builder model. It's going to get some alter callbacks. It's going to basically parse through everything and create sub-renderables. It's going to get whatever module decorator classes we have and then whatever theme decorator class we have. So let me just... Let me do some hand waving and show you kind of the idea here. So imagine this is our Drupal site. So we've got node.tpl.php. Is there a node template? It says I am a node and it's going to give me a title variable. Let's say this is our preprocessor. So we have a class called themeful node. This is like our hook theme implementation. It has some registered template with this. This could be an annotation. This could be enamel. This could be somewhere else. I don't really care. This is just for the example that I'm doing here. We have a prepare phase and what that's doing is it's getting the node and just setting it as a template variable. So this is a template variable. Maybe there's parts of the node that we don't want to be in the template and it spits it out. So let's say we have a alter callback. So in my fakeDrupal.php here's my fake alter registry. So let's say... This is not how it will really work. This is just an example. Let's say I have an alter function. I have a module called myModule. This is hook node view. And so here's myModule. MyModule hook node view. It's going to receive some build. And what I'm going to do is change the build class to themefoo. And let's say I have a themefoo class. It's going to register a new template. And then it's going to set the title variable as overridden by themefoo. So I uncommented that code. And if I go in and I reset this, let's look at food.tpl.php. Here's food.tpl.php. It says I am module food.tpl.php. It's going to give the title, which I pre-processed. It says I am node123 overridden by themefoo. And then I have a new variable. Which I set to bar. So I did this in...this is the builder. This is like hook node view. This is something else. This is altering the builder itself. So once the builder is altered what it does is it will create whatever class it's been given. And so when I altered that it turned into themefoo. But I could change it to something else or then I could decorate that. So in fakeDruple I go to... Oh, that's an... Sorry, it's in the renderable builder. I think it's in the building. Because I'm going to get module decorator classes. So this is some registry. Get a decorator class. And then wrap it. This is like the coffee with the cream and the coffee with the other stuff. I wrap it in a decorator. So there could be module decorators and theme decorators. Module decorators are like module template preprocessors. Theme decorators are basically the theme preprocessor. So what I'm going to do, I have a fake module decorator. Let me just not override this anymore. Here's the module decorator. So I'm going to say if it's a full node, use myModuleFullNodeDecorator. And so I have myModuleFullNodeDecorator. What it's going to do is just going to use the parent template that's given by what the parent class is. It's going to prepare the parent variables. And it's going to change that. So this one I'm saying modified by myModuleFullNodeDecorator. So if I go here and refresh, it's using the parent template. It's using the core template, but it's overriding the variable. And let's pretend our theme is also overriding this too. So I have a theme called Prague. And here's themes, Prague. Prague FullNodeDecorator. Prague FullNodeDecorator is going to use a new template. So this is something we do in themes all the time. We register a new template. If that's done automatically it would probably work the same way. And then I'm going to add a new variable called subtitle, called hereisSubtitle. And then in my Prague node I'm going to say I am themesprognode.tpl.php I'm going to print the title and I'm going to print the subtitle. So I think I uncommented that code. And so here's my theme decorator. So now I'm overriding the template. The title is being overridden by module decorators which is what module preprocess functions do. And then I'm adding a new variable via the theme layer. Another thing I do here is you'll notice that the renderable had methods like get and set. So this is getting those subparameters. That is how I think we should do things in that's basically the equivalent of the dots that appear in the twig function. You'll notice something that I do here. And this I think answers the question that this gentleman had and I think the question we have in Drupal 8 is when you get something if we haven't prepared if we haven't done the preprocessing then run it. And in object-oriented code that's really easy to figure out. It hasn't been that easy to figure out in render arrays. So this says if I haven't prepared anything then run the prepare function. So that's the idea. So those of you who've never seen object-oriented code before you're probably falling asleep. I apologize for that. Some people are hopefully really excited by this. Again this is in fake Drupal but I think the concepts are there. The concept is like we need accessors. We need ways of overwriting certain things but not other things. We need some sort of registry. So I have about 15 minutes left which is not as much time as I wanted. But I'm just curious is there any feedback on this kind of stuff? You can check out the GitHub project. Or if people have other like what about this and what about other things in theming. Thank you for sitting through all that. So with regard to actually changing the class can you just pull up the code where you're doing that? Certainly. So that's in right here. So I'm changing the build class to be something else. Those build classes they could extend the class that was there but they may not because you don't really know. Right. So that's a good question. The question is why isn't this a decorator maybe? Why isn't this wrapping it? To a certain no, I like the power that you have here. Okay. There should just be some sort of interface enforcing it. You can't just toss some other class at it and be like you can read a note. So that's an interesting point. He's asking you're just setting an arbitrary class on here but theme foo extends renderable. It doesn't say extends theme foo note. That may be something that is worthwhile to say okay you can only use this class to extend this other class. I mean yes that's kind of a nice thing but at the same time there are lots of things in Drupal I mean with a render array you can put whatever you want in there. So you could put a WordPress site in a render array I guess. Yeah I know. So could we use the system to get the rendered output? So I'm thinking about if we wanted to have template rendering on the front end but we need the prepared data to sort of match the templates and send them separately. Right. Yeah so I think what answers that question I think is separating the builder from the renderable itself. When we set up the builder we give it some initial variables and that's like a render array. When you have a render array you give it some certain variables but variables that apply to the template specifically like classes and other HTML related things those are created in the preprocessor. And so that's kind of the difference between the renderable builder as an object and I think the renderable itself as an object is that in the builder that's kind of like the storage component of the render array. And so what's nice I think about that is the builder kind of represents the abstracted structure and so whether that turns into HTML into JSON or whether it turns into something else you have an abstracted structural thing. And you know by virtue of being in a website it's turned into HTML but it couldn't turn into other things. Does that kind of answer your question? Yeah definitely because one of the questions we're going to ask in the backbone buff is how do we get templates like twig templates shared across the server and the front end because if you get the template without the data you're essentially if you're just getting like a rest representation of an entity you still have to do all that processing on the front end Yeah and so I saw that as kind of part of render API as we have the render array itself and then once the theme preprocessors run we have all this other data that is specific to the templates but maybe we don't want that to start with and that kind of answers like do we want to do that preprocessing first. In this case we don't. We just want the kind of abstracted structure. So I think it applies. I also think there's a lot of overlap between the entity field API which I haven't used that much but like a lot of this getters and setters stuff I think is very much I don't want to bug those guys too much because this is like Drupal 9 and I don't want to like show up to their table in the code or language but like guys let's talk about this so but I think a lot of that applies too. Cool. Yes sir. I just wanted to make like one quick caveat I really like what you're doing with the builder just ideologically I think that's really smart. Watch the decorators though Jenkins paid the price for that in spades. Decorators are great like one maybe two levels but the second you start doing more than that like it gets really really hard to figure out all the interaction patterns that are going on there. Right. So if you can like if you can essentially alter the params which is basically what you're doing with that by some other methodology I'd encourage you to research it. Yeah and that's a great point and this was brought up by other folks is like as a themeer and maybe there are some people in this room who'd feel this way already is this may be gobbledy-goop rather than like a simple preprocess and array of variables and that's what I was kind of talking about like public-facing API public-facing API may still be a processor but the guts of it may be this. Now the problem with that is you're obscuring things which I don't like doing and I was talking to Mark Sonobom earlier today about some of this stuff and you know we were saying like you know I think computers are smarter than we give them credit for and he's like yeah they write JavaScript you know and half of that stuff is like you know gives people headaches so yeah next question. This might not make much sense but I really think you should book the entity API guys because I could go to the talk about REST API in Drupal 8 and it sounds like you're both tackling the same problem from a slightly different angle. Yeah totally. It's a consistent representation of an entity. Yeah. I see this as being both looking at the same issue. Right. It's not an entity. It is a abstracted structural element that doesn't necessarily represent content which is kind of what an entity is. There are going to be entities in this. My example actually is happens to be an entity itself but this could be something like a theme page or something like that. And it's kind of a higher level thinking of that but definitely the accessors are the same kind of things they're doing. It just would make sense that at the level here where you're representing entities that it doesn't look completely different to Yeah. And we may just write wrapper classes that extend the entity accessor classes they're writing. Yep. I'd love your help on that. One thing I struggle with when theming is if I've got a source and I've got an HTML tag in there that I want to change. Yes. Locating where that is. Yes. It's partly because the system is so flexible and it could be in 50 different places. Yes. Does this help that at all? They're still in as many places and it still seems... Yeah I mean extensibility is kind of a two-sided coin. It gives us that power but then you have to say well where is this coming from? I haven't thought about that too much I think one thing that we get away from Oh. One thing... Just swipe everything on these things these days. One thing we definitely get away from is... Oh wait it's not even in my slides. I'm sorry. I mean we're getting away from this. And so the nice thing about an object and like a builder is I can say get image and it's just going to give it to me and I don't have to worry about where it is or where it came from or who it belongs to really it's just going to be there. And I think one thing that I am also getting used to and it's kind of tough is the idea of having to know where everything is all the time and knowing structure and having to inspect this to figure out where that is. Now it's important to know how to overwrite it you know and in the old-fashioned Drupal you had to know where it is to overwrite it if we give you a method and all you do is call a method you know then that where is it being done is less of a problem I think that's kind of a vague answer but I think maybe we have... I think you're saying that you'd probably be looking at smaller bits of data so it might be easier to track down... Yeah and hopefully I mean you have an API and instead of knowing an array structure you know an API. That's kind of the distinction I see there so maybe it's... Hello. Can you give me a moment to think about describing the build object through a REST service like get me pieces of a page at a certain URL and you know calling those back. I'm going to write that down, yeah. That would be phenomenal. Okay, yeah definitely. Good idea. Yes. Can you pull back up your prepare statement you had somewhere? Maybe. Sorry in the code here? Yeah. You had a prepare statement up here. Oh okay yeah so this may have been in renderable when we actually render it so we were saying like have we prepared the variables yet if not prepare them? Prepare is pre-process. Pre-process. Why don't we call that pre-render I'm like we're not talking about an implementation. Call it something else, yeah. But you actually have an implementation of it somewhere like maybe okay. Yeah so I do, yeah. This is the abstract class. I think for now we have to always have to call the parent because the parent is going to tell that everything has been prepared in themeful node but here is the prepare. So I mean I get that we should call prepare and that makes great sense but again I'm not entirely sure why this is a decorator pattern at all because you need to say hey prepare then call an event and anybody who subscribed to that event can just do this set because that's how you're setting properties and I assume you have a getter as well so they can manipulate the string if they want as well. So I don't think just to try and kill this decorator pattern that you need decorators at all for what it is you're proposing to do just drop a symphony event right there and you're done. And my symphony knowledge is like I need to okay are we putting money on this? okay yeah that's something to think about you know this is fake Drupal this is living in my own my own head and this is why I kind of have been away from Drupal for a little while because I want to think about this in a very abstract way that conceptually fulfills it but this is just kind of implementation yeah you should probably be using the symphony event since we do them available and you don't have to grab all of Drupal in order to get them and then you can absolutely fire off you can dispatch an event there and have any class in the entire system that wants to change this interesting I'll look into that okay Friday Friday it's brand on Friday I have a couple of questions I see some smiles so hopefully I did okay anyway please please take the survey I have to show you this node 1863 on the website and I'll hang out for a few minutes if you have other questions what I think we're about at well we got two more minutes so we can hang out for two minutes that's all I have that's all my material geez we can go all day we can start for 32 minutes okay well you're welcome to stay but thank you for coming and enjoy the rest of the conference and enjoy a beautiful Prague at the window here so thank you