 Thank you, everyone, for coming to this presentation. This session is about Drupal 8 teaming in depth. I am expressing some of my opinions how teaming should be done in Drupal 8, and you don't have to agree with me or you can feel free to disagree. But this is my opinion on how teaming should be done in Drupal 8. I'm excited that so many of you has came to listen to about this topic today. So I guess we are going to have a good session today. Hopefully you will have also good questions in the end of the session. So let's start by introducing myself. My name is Lauria Skola. I'm a Finnish Drupal developer working for a Finnish Drupal agency called Druid. We are a Drupal agency hiring 27 people located in Helsinki and Amsterdam. Currently I work from Australia. I live in Melbourne. I like kittens, and I do some Drupalite contributions. So let's start with the problem that we are trying to solve with these things that we are talking about today. So the first and the largest problem that I find in Drupal teaming is that we have a word Drupal teamer. I would like to kill the whole word Drupal teamer. We should instead have just teamers or designers. So what does that mean? The problem is that teaming Drupal usually is so complicated that you need someone who understands Drupal to team it. But by changing the way we team Drupal, it wouldn't have to be always that difficult. Maybe some of the tasks that teamers are doing could be outsourced for the backend developers or some other people, and then you could have just designers working on your design. We will come back to these issues later, and I will explain how the steps that we've taken solve these issues. Another problem about Drupal teaming is that the whole Drupal front end has been built data-driven. What this means is that when you're looking at the design as a teamer, we shouldn't have to be thinking about what something on the design is as data. So let's say if you look at content, we would have to think that, okay, this is a node or this is a user, because the whole Drupal front end has been mapped to these entities or types of data. Instead, as a teamer, we would like to think, okay, this is a component which will print this data in this format. It could be either user entity, node entity. The teamer shouldn't have to care about what type of data is being printed in a design. But sadly, in Drupal, we have to think about that, because the front end has been mapped to the data. Another issue that we have is that a big part of the work is overlapping between site builder and front end developer or teamer. What that means is it's very difficult for a teamer to start teaming a feature at the same time with the site builder because they have some overlapping work that needs to be done. In order to do something to be able to be teamed, the site building needs to be done or the backend development needs to be done. So I'm going to explain how we can get rid of this issue. And also, the one huge problem that we face is that achieving dry, which is do not repeat yourself, is very difficult. Usually when you are creating different variable, different variation of a template, you would have to copy the whole template, and you would have the same piece of markup in multiple different templates. Also, this is something we can probably get rid of. Let's see. So let's start with very basics of Twig. I know many of you probably have already used Twig. How many of you have used already Twig? Almost everyone. That's great. So I'm going to go very quickly. I just wanted to include this, since it would be such a shame if there would be people who wouldn't understand Twig and they couldn't understand what I'm talking about because of that. But because it seems like almost everyone knows about Twig already. So I'm going to go this part very quickly. So here's example Twig file, a very simple Twig file that I'm using to print a list. So in Twig, there is three different synthesis. There is the curly brackets, which is for printing something. There is the curly bracket and the percentage, which is for doing something. And there is the curly bracket and the bracket, which is for the curly bracket and the hash, which is for commenting. So here you can see a very simple comment in Twig file. Here you can see how we use the curly bracket and percentage sign for a for loop. And inside of the for loop, we are printing an item. So you can see the printing syntax. So in Twig, when we are accessing data from a variable, we only use one single syntax. There is no multiple synthesis that needs to be used. Everything is accessed with the simple dot syntax. So it doesn't matter whether you are accessing an RAT or object property or even calling a method. You will always use the same syntax to access the data. One of the very, very neat things is that you can even call with this simple syntax the method using the get or is method convention. So let's say if a node would have method called getPublished, you could just say node.published. And it would call the getPublished method. Very, very simple and very awesome for the front-end developers because they don't have to understand what is the difference between arrays and objects. Twig also has includes. We are probably going to do lots of includes during this presentation. So it's good to know how includes work. So Twig include is essentially the same as you would have in PHP. You can just include another file inside this file. One of the very fancy features that we have in Twig is that you can say only. And what does that work do? It tells that while we are including another template inside this template, only provide these variables for the other template. Everything else inside all the other variables available inside the template where we are calling the include won't be provided for the other template, which gives a nice isolation between the templates and allows us to do pretty neat things. So what I'm doing in this example, I'm just including a link.html.twig file with two variables. I'm giving link variable and text variable. I'm finding the data from the node object for the link. And I'm just giving a simple text that I'm declaring myself inside the twig file. I'm using the twig filter T to make it translated. Very, very simple example of using include in triple. Another super cool feature that twig has is twig box. I hope you have already figured out this. I've heard some people are suspicious whether it's good to use the twig box or not. I think using twig box is pretty awesome, because even though it adds a little bit of complexity, but after you understand how it works, it's the most awesome thing in twig probably. So how blocks work is that you can define in a template small regions that you can override with another template. And on this example, I have the page template, where I define two blocks, content and footer. By the way, twig blocks are not triple blocks. They're totally different. I want to override the content block on my front page. I want to have different text on the front page, on the content block. I will create another template, page just front, which will override the page template. I will tell extends. It will extend the page template, so it will take everything from that template and override the small parts that we tell it to override using the blocks. So when you're using the extents syntax, you are not able to provide any markup outside of the blocks. It will throw an error if you do that. So I'm modifying the block content. Everything else will remain the same, so H1 title will be printed as it is there, and the footer will be printed as it is there. And then we have a third cool feature, which is twig embed. And this is a combination of include and block. So you can define blocks in a template, and you can embed that. And you can specify block overrides, just like you would do while you're extending. And using these three different technologies, you can do quite a lot of good things. So let's proceed to what can we do using these tools. So component-based teaming is pretty much the future where all the triple-teamers should head towards, at least from my point of view. I'm not the only one thinking like this. So what is this whole thing about? So component-based teaming is about thinking that instead of delivering the customer pages, we should be delivering them systems that include components. So when you're creating, when you're teaming a page, you should think that this page consists some elements that are reusable in other contexts. And when you're creating another page for the customer, they could build it using the elements that you've already built for them during the previous page. So what is component itself? So components should be self-contained, reusable. So self-contained means that the component only modifies itself. It doesn't go outside of it. So let's say if you have a component called button, the button component won't modify the header component. It will only modify the button component. It will only modify itself. It should be reusable. It doesn't mean that it's always reused, but it should be something that can be reused. It should be also nestable, so it should be something that can be inside another component. Component in the most common scenario would consist markup and some kind of styling. It could also consist JavaScript. Let's say if you have this component, you could have this component which has JavaScript show and hide functionality after a certain number of list items. Let's say you want to show three items first and then rest of them are hidden, and which JavaScript you would show them. That kind of JavaScript could be inside a component. Sometimes components could have other assets, maybe icon, something like that. Not always component could have them loaded from somewhere else also. By the way, while I'm talking about components, I'm not talking about any specific design system. Any design system could work like this by using these tools that I'm talking about today. You could practically include any design system into Drupal. So this is the workflow that I'm using myself in my project. So what we do is that we have a base team which includes a component library. The component library is also reusable in other systems, not only in Drupal. You could use it in a project using React. It's just tweak and CSS and JavaScript, not in Drupal specific. But that is included in the base team. And multiple different Drupal sites are using that same base team. We have a default team which we use as an integration layer. On the default team, we simply map the components into the right places on the page. I will show how that happens. Essentially, on the base team, we don't have any template overrides, no templates, no block templates, no region template, no page template. There is only a component library so that it can be loaded in the Drupal. And that component library, like I say, it could be used to multiple different purposes. So let's say if you are doing style guide centric development, you could use that component library to build a style guide, or you could use it to build the application stylings. So the component library should be reusable and swappable. So you can essentially use it for anything or give it to the customer's other companies developing their other projects. So that's about what is component. Let's create our first component in Drupal. So I'm using a very, very simple component, I think the picture is from Google's style guide. So thanks for them. So we have a title, we have a little bit of text, and we have one link. Very, very simple component, most likely when you're building a component, you will have to create more complicated components. But I'm going to start with the most basic one on this presentation. So what's inside that component? We have just one tweak file, and we have one CSS file. I'm not even using any CSS preprocessing on this very simple example. So we have a little bit of markup, where we are printing four variables, and we have some CSS, which sets a border and some margin and padding. That's all. Very, very simple. I will place that component file into a new folder, which is under my team called components. And I will create a new file for this component called card. So all card component related things would be inside this one folder. So that was all. That's how we created the component. Only one file of tweak, one file of CSS. Now we have to integrate this in the Drupal. I am giving a disclaimer. What I'm doing right now in this presentation will break a lot of Drupal's features, like quick edit, contextual links. They won't work with this approach. We will have to figure out how we can fix these functionalities to work with this kind of approach. But if you are building something like this for the customers, like I am, we are willing to make a trade-off between these two things. We are willing to sacrifice some of the features and use this method of teaming. So the first thing I will have to do on the Drupal's side is enable components module. Components module is a very, very simple module which allows us to add extra namespaces for tweak. So this allows us to load tweak files from other folders than just the template folder. So as you saw, I placed the tweak file under the components folder. We want to add a namespace for that folder. So what I'm doing, I'm specifying in the info.jamu file a new component library. The first line, where it says team name, is the name of the namespace that we want to create. So I'm just using a very simple namespace called team name. So by default, team name would be providing namespace for the templates folder, not for the components folder. But I'm adding both of them for the namespace. So both of these folders will be looked for when something is being loaded from the team name namespace. This allows us to load the button.html.trick file from the components folder. So in order to be able to debug tweak, you will have to enable tweak debugging in the services.jamu file. It will print these kind of sections inside your markup. They are very useful for finding which template we need to use. It will also disable the tweak compiling into PHP so that it will reload the tweak file on each page load. You will also need to disable caching while teaming, because otherwise you will have to clear your cache after every change. So I will add these lines into the settings.psp and a few lines to the services.jamu. There is a file called example-development.settings.php and local.services.jamu, something like that, which you can use to do this. So this is all built in in trouble. But you will have to add these lines in order to these changes take effect immediately. How I will debug the variables while I'm debugging tweak, I will use the kint module, which is provided by devil. It is the best tool out there right now, at least as far as I know. It will provide all the different properties of the object. It will provide the methods. And if it's an array, it will just simply print all the lists, all the list items. It's a good debugging tool. So this is how our list looks currently. This is the default theme of Drupal. This is how Bartik would print out the articles. You can see that there are some things that we don't need, which will be removed soon once we apply our new template. So what I'm going to do, I'm going to find the right template to beginning. I can find this kind of a block where the node is being printed. I will choose the node dash article dash dash teaser, which is specific for the article node type in the teaser view mode. So we only want to do it for the articles in the teaser view mode. I will create a new template file. So I won't copy the node template to create this template. I will just create a plain file with this file name. And what I will do here is I will tell include from team name slash card slash card.html.tweak. Then I will provide the component that we created. These variables, I will give it the title variable. I will give the text. I will give a link URL and a link text. So in the template, I'm now fetching the data from the variables that I have available inside the node template and make them make sense for the teamer inside the component. Inside the component, the variable names are very clear, very obvious. And all the magic happens now inside this template. This is where all the Drupal teaming happens. The component file is very clean, and it's something that any teamer could build. So after making this change, we can see that our articles start to look a little bit more like what we are trying to achieve. All the extra data is gone, but we have all the essential things in place. So what we have to do next is that we need to have some assets for that component. So how does that work? In Drupal 8, everything has to be loaded through libraries. You probably knew that already if you've done any Drupal development so far, because everyone has to create a library in order to be able to provide CSS files. But because we want the CSS file to be mapped to this small piece of markup, we want it to be only loaded whenever that markup is being loaded. We will create the library, and then we will tell inside the dwek file, attach library, and we will tell which library we want to be adding for this piece of markup. So this way, if the cart component doesn't exist on the page, the CSS file that you have for a card doesn't get loaded. So let's say if you have some very complicated components that has lots of CSS, but they will be only printed on one page, the CSS would be loaded only on one page. Also, because everything is very self-contained, all of your components should be self-contained, it doesn't really matter if some of the CSS files are missing from the page. Because if that piece of markup is not there, it shouldn't affect anything else anyway. So after adding these few lines, our layout starts to look pretty much how it looks on the design. It is also possible to include multiple assets for a single component. So if anyone is using smacks, you can absolutely include multiple assets from a single component. So let's say if you want to have a CSS file for state, you could include its own CSS file for the state. Andropole will load it into the correct place, correct order. It will place it after the components, and it will override the components. Therefore, you can also include JavaScript in the very, very same way. If you need to detach any inherited assets, like let's say if we have a button class on the component, you would have to remove some of the CSS being loaded, because Classy provides some markup for the button component. It adds some marching for the button class. How that happens, we have library override, which allows you to do lots of magical things. But I think the most common use case is to just remove a single file away from being loaded. And how that works is that you say library is overriding inside the info.jammel. Inside the library is override. You have to tell which library are you overriding. So the first word is the extension for the library is being loaded from, where the library has been created. The second one is the name of the library. So I'm removing a CSS file from a base library inside Classy team. Then you have to tell, OK, this is CSS that we are removing. Then after that, you have to tell, OK, which smacks group is this from? And then you tell the path of the CSS file and say, false. So it won't be loaded anymore. You can also replace CSS files and extend existing libraries with your own CSS files. But personally, I don't know why would anyone use these features. But I guess they are nice to have. Maybe someone needs them. In case you are looking for these more complicated use cases for libraries, I suggest to go to this blog post. It's written by David Hernandez. And it's a pretty extensive blog post about lots of libraries magic. So I will create another component to make it look like exactly how we created. So everyone remembers how this happens. So I'm creating a container for the cards. This is also a very simple component. You can see the address library that I'm already adding here. I'm also just printing an items list and adding some CSS to display them in a flex mode so that they will be aside each order nicely. I will create a library just like the way I did before. This is a new component. Like you can see, it's card container. And I will find a template name for this use case. So I will have to look for the views overrides. This doesn't work out of the box in Drupal. So if you want to see the views template overrides, there is a patch inside trope.org that you can use to view these template overrides. Very handy. But if you need to see which template overrides there is available for your views, I would go download that patch. And it will show template overrides that are available for views. So the integration for this piece of markup is a little bit more complicated. And this is where the issues start to be visible. So we get a pretty complicated array structure inside the views template. So we need to start actually modifying what is inside the arrays and start creating new arrays. So what I'm doing here is I'm creating a new items array inside a loop of all of the rows. And I have to just copy the row.content on the main level of that items array. So what you want to avoid inside your components is any Drupal-specific things. You don't want to be printing the Drupal data structure inside component. So in case you have any of this magic that you need to do, I would do it in the integration template instead of doing it inside the component. Because the component should be as clean as possible. It should be something that someone could use in any other use case. So this same thing could be done also in a preprocess function. But because I wanted to avoid using preprocess functions and use the template instead as an example, I did it inside the template. This is also very, very in this case. If I would want to make it in the other way, if I don't want to, if I'm unable to modify the array structure, what you could do also is to use the trick box. You could create a block for the for loop and replace the one for loop inside the trick template. And then you could use the Drupal data structure. Then you could access the data from the Drupal data structure using the embed. And it would be in the single file, the all the Drupal specific things. So after applying these styles, our components start to look pretty neat. It looks almost like on the layout. So there is a Drupal.org issue about making Drupal work component based by default. It's a very, very complicated issue because if you think what we just did, it basically broke lots of things inside Drupal. So in order to make Drupal core actually support something like this, we would need to make lots of changes for the way, let's say, quick edit module or contextual module works. And there is an issue about this thing in the Drupal.org. And there's going to be plenty of people working on trying to find a solution for this thing. So if you are interested about this, I suggest you come maybe talk to me or just go to the spring lounge and see if someone is working on issues related to this. If you want to get started with any of the design systems, there is Drupal projects, which are already showcasing how to integrate into pattern lab or KSS style guiding. So there is a pattern lab team, which is a base team for using pattern lab. And there is a Zen team, which is using KSS style guide. And they both are working pretty much in a very similar way as I showed today. And they show how powerful it could be to use some of these design systems on your projects. So let's go back to the problems in Drupal teaming. So the first problem was that there is a teamer versus designer. So we don't want to have Drupal teamer anymore. So this problem is basically solved because you could have your designers work on the components and they could create their style guide out of the components. They don't have to deal with Drupal. The backend developer could do the integration between the component and their backend magic, at least I hope so. And that way, Drupal teamers don't have to be Drupal teamers anymore. They could just focus on creating components. They could review their components using a style guide and then the backend developers would be using those components. Also, when I've talked to the backend developers, they would be happy to have something like this, because they could just build new features just like this, like very, very fast, because they could use the existing components that someone has built for their backend magic. Also, using this kind of approach is not data-driven because you can basically define your own structure inside components. You don't have to create a component called node. You can create a component called card, like I did on the example. Inside the card component, you can print a node like I did, or you could print a user just as well. There is no single data type that it would work with. Also, the overlapping work between roles. The situation is way less worse, since the teamers can start working on their teaming because they could build the components inside components folder. They don't have to wait for the side builder to finish the side building or side build themself, which allows things to move faster forward because multiple things could happen at the same time. And as the last point, achieving dry is very difficult, because Drupal was mapped into the data types, and everyone was just copying the templates. But now that you are using components, even though you have lots of templates to map the data into the components, it's pretty simple to write those in the creation templates, and they don't contain any markup. So whenever you need to refactor markup, it happens inside the components. You only need to modify a single file to modify, let's say, the cart component or a button component. You don't have to go to modify all the different node templates, oh, and I'm using button component also on the views templates. You would have to modify maybe 50 templates if you are using the very, very traditional Drupal way of teaming. But instead, if you have the component, you're loading the button for each of these templates. And if you modify the markup inside the button template, it will show on all of these places, even though you probably end up having more files than you used to have in the past. So I suggest everyone to come to the front end United, which is in Athens. It's in May next year. It's one of my personal favorite events. So I hope to see as many of you as possible over there. I've heard that it's going to be warm, and the food is good, and beer is cold. So see you there. And now we have lots of time for the questions, which I hope you will have. So there is two mics over there. If you have any questions, you can line up for the mics. And I will be happy to answer to your questions. Go ahead. So first of all, thank you. Can you give an example of using JavaScript with the libraries that JavaScript gets attached after probably an AJAX request? So if I have some JavaScript acting on the cards that are maybe loaded via big pipe, or later AJAX request gets attached one more time? So are you asking about how attaching JavaScript happens when using big pipe? Yeah, actually, I run into some problems with big pipes and attaching libraries via the templates. So have you run into problems there? Big pipe module is experimental, and I know actually about this issue. And currently, there is no good way to get over with this if you want to load the JavaScript file inside the template. So if you're using big pipe, you would have to include those JavaScript files in the required libraries so that it's loaded always. Yeah. And yeah, it's a shame. But the big pipe module is still under development. So I think that it's going to be fixed at a certain point. But do the libraries get attached even if I have like an AJAX request? So maybe. Yes, yes. So when you have AJAX request, the style suits and JavaScript files will be attached. But there is a slight delay, which can be annoying. But they will be attached, essentially. Any other questions? I have a question regarding the embedding of Twig templates. I ran into the issue that I have a template. Then you want to embed another Twig template inside it. But then on the preprocessing of the parent template, you need to build the variables for the child template. How do you avoid this in Drupal if it's possible or not? Yeah, so what's the question that if you use, yeah. So there is no way to duplicate preprocess functions into multiple functions. So that's a big question. And what we are doing, while we are facing this kind of problem, we try to move as much as possible from the preprocess functions into the template so that it would happen inside the template instead of in the preprocess functions. And then it's something that can be duplicated in Twig and can be run from multiple places. Yeah, but then Drupal suggests doing the processing of data in the preprocessing stage of the template. And so preprocess functions in general are something that we are discussing if we should remove them or not. Because in many cases, what happens inside preprocess functions is something that should happen actually before the data is put inside the theme system. The reason why preprocess functions still are what they are is because it's very difficult from Drupal to know what kind of data does a teamer want inside their template. But in many cases, the right solution would be to add the correct variables to the hook team implementation so that you would have it during the whole pipeline inside the theme system. And then you would have just very, very small modifications inside preprocess functions. So preprocess functions, what they are meant for, a good example would be you want a format date inside a correct format. That would be something that you could do inside preprocess function. But another example of something that you shouldn't do inside preprocess function is, let's say, load a new entity and put that data inside the template. That's not something that should happen in the preprocess functions. So I don't know. Can you give a little bit more specific example? Well, in our case, we had two teaming twig templates. Each one of them, behind them, they have only one variable, an entity. And based on that entity, the parent template constructs different variables to print out. And then the second template takes the same entity and builds other variables. So when we used embed, the variables needed to be defined in the preprocessing stage of the parent template. Because you couldn't call the preprocessing stage for the embed. Yeah, so I suggest that instead of just giving a template, an entity, that template should be given specific variables that it should be printing. So like on my example, I had title, text, and link. That's what template should be getting. That's closer to what template should be getting instead of getting an entity and do whatever you want with this entity. Because entity is putting raw data inside the template. Instead, template should be outputting variables that it gets. And it should be title, body, image, things like that. So you should already have some kind of an idea. What data will be printed inside the template on the hook team implementation. So it should exist during the wall pipeline. That's at least my point of view for this. But then if you call the same hook team multiple times, you need to recalculate the same values for the variables based on the entity every time. Instead of doing only once on the preprocessing stage. So that's why we thought of transmitting the entity. Then you can create a render element for that. That's also a valid use case. So you can create a render element, which has the pre-render function for converting an entity inside the render array. Are you familiar with render elements? Or yeah, good. So that's the absolute way of doing that. And there's plenty of examples in Drupal Core how that should be done. A good example would be to look maybe for maybe I is doing lots of things with render elements. You can look from there maybe. But the hook team implementation should already have an idea what is being put inside the template. Any other questions? Yeah, go ahead. You were talking about the themeer being able to work before the backend is ready. So I was thinking about if you're working on your components and you do it in the tweak files and define variables, how do you serve them with, let's say, dummy data or something? Or do you just hard code them like you would do in HTML and then replace, let's say, a href attribute with a variable? That's a great question. So many of these design systems that I mentioned, like KSS and PatternLab, they would have their built-in way of managing the default data. So let's say if you use KSS, you can provide a JSON file of the data that you want to output for the template. And then you can just generate the style guide out of that. And it will show the data in the style guide. So you need a sum design system that you are using in order to do it that in a simple way. But when you use a design system, you don't have to have any mid-stage for putting example content inside the template. You will have the example content in a JSON file. And the template file that you have is ready to be used for inside the theme. OK, thank you. Any other questions? Do you have a question? No? Do you have still some time for questions? I guess if we don't have any more questions, we can go home or go to the other presentations. I still want to remind you of the contribution sprints that are happening this Friday. It's a good chance to get meet other fellow contributors and to get started with contributing to Drupal 8. And there will be lots of things related to this also if you're interested. I also suggest you to evaluate my presentation on Drupal.org, not on the events.drupal.org on the event page so I can be better on the next time. Thank you.