 Today's session is going to be about, well, Drupal 8 and Purse 2 for best practices, whatever that is. Before we begin, I'm Branislav. I'm a Drupal guy. I was actually a doctor guy before I became a Drupal guy. I studied medicine and I had substantial IT knowledge, but they changed. So now I have hair and everything, and I became a developer guy with substantial medical knowledge. So it's a change. I lived until seven months ago in a beautiful city of Panksevo in Serbia, close to capital. But now I live in Rheinbach in Germany, close to ex-capital. So I changed. I work for a company called Union Betriebsgambira. We are working for, well, for a major German political party and we are doing IT, internet printing and publishing. So yes, a lot of changes. And the thing is, this session is going to be a lot about change management and how to embrace changes, but keep your identity, you know, the ways you are doing. And of course, in Drupal 8. Now Drupal 8 gave us, well, new core, new APIs, 200 new features, new paradigms of coding, object oriented coding, proudly built somewhere else, and of course, big. So it yells out with the old. It yells with, you know, we need revolution. We need to forget everything we knew and start all over again. And I really hated the concept because, well, I learned Drupal for 10 years and I don't want to forget everything. I want to, you know, start building on top of Drupal 7 and Drupal 7 practices and just learn something new. And it is really difficult because of this force, seeing force to change and to embrace totally new thing. So let's start with goals. You know, we need to focus on goals because goals didn't change. And our goal is actually to do as least as possible to build as best product as possible for, well, and, yeah, enjoy it. So, and in order to do that, well, we have good software design. And that problem was more or less already fixed. We have, we know what to do. We know that we need to build software that is good quality software that can be easily maintained, easily upgraded, easily reused and deployed. And, well, programmers invented design patterns. And that's awesome. That more or less solves their problems because, you know, you have patterns. You know how to solve some general problems using some general patterns and that's it. But it doesn't really work with Drupal because, and especially site building. Because we are working with visual programming with settings and not really typing stuff. So that can be a little bit impractical for site building. So we invented best practices. Now, they are similar to design patterns only suggestions how to solve some problems. But, well, design patterns are unique for every programming language, every framework. And best practices is kind of framework and version specific, meaning whenever you change a framework you're working on, you need to review your best practices or even redo them, start from scratch. And, of course, version specific, which we know in process of immigration from Drupal 7 to Drupal 8. And, yeah, they're also task specific, meaning that, you know, you don't have that much design patterns in the world. But we do have a lot of best practices depending on what we really try to achieve. So I don't want to talk about, you know, whether to use node access or rabbit hole to solve a problem, that's too focused on a special task. I want to talk about general stuff. And, of course, we don't have any literature on best practices. We don't have any repository of best practices, and that's really a problem. We really don't know what is a best practice to solve a problem and what is not. Finally, we're not really sure if best practices exist. Are they the best? Are they better practices? Should we just stop searching for better practices if, well, yeah, current ones are the best? So our first problem or the biggest global problem we have is, well, problem with deployment. But not any deployment because we don't care about code deployment. That problem was solved with Git. We care about config deployment. Now, config deployment was generally a problem with Drupal, and there are still a lot of companies who do manual deployment. Are there people who are doing manual deployment here? Don't be shy. I'm doing manual deployment also. So unfortunately, we do a lot of manual deployment these days, even though it's 21st century and we have all those beautiful tools. So we invented something that will prevent us from having to do stuff multiple times and reduce margin of error. And, well, first thing I could think of, we created was hook update and process. Who is using that? A lot of people, awesome. So I don't have to talk about it too much. So we just, you know, use some custom module and just any time we want to deploy something, we write a new hook update 10, push it, pull it. But it's time consuming, and, well, we don't have too much time. Another thing we invented was features. And who uses features here? Okay, who doesn't use features? Okay, features are awesome. So they helped a lot. Now we are able to visually pack stuff together and just create modules out of it and just add it to Git. And we know who did it, if somebody breaks something, we know precisely who broke something. So it's good. However, it's not so good. Due to limitations of Drupal core and overall user unfriendliness, we have problem with auto increment indexes in Drupal 7. To be precise, for example, using blocks and putting blocks into features, you cannot do that without features extra. And features extra is something, it's like hell, I hate it. Who hates features extra? Okay, so, yeah, that doesn't work really. And you know, come on, re-create, revert, what's that? I had a lot of problems trying to explain what is re-created, what is revert to people who are, well, who are good developers, they're not really from Drupal world. That's crazy. And finally, this is a big problem. When you disable a feature, it is going to delete every setting inside that's, well, deployed using that feature. So you can use, lose a lot of content by disabling feature. And finally, there is a big problem if people are using features for something, but then overriding features in live, they end up with this screen. And this is a nightmare. This is a nightmare. And you know, when you start working on a new project and you see something like this, and you're not really sure where to start, what to do. So first thing you can do is like create a group called delete me. And all the things that you don't need, just put it there. Because you must not uninstall it. Or even worse, you cannot uninstall it because it is like circling dependent from something other. So it's a mess. And that mess happens like this. So if you have thing called, well, you created an article. An article has node containing body, which is a field base and field instance. And then you created another content type called listening, which is actually also having body as, well, field and field instance. So listening is dependent on article. No, just imagine you want to create a list of listings in the article because client wanted that. So you're going to have entity reference to listing nodes. And then you have circular dependency. And this is a nightmare to disable because, well, you cannot disable it. Well, not without too much troubling. So we created, again, some best practices. And one of the practices is we can force our features not to be dependent one on another by, for example, creating unique fields for every single node or content type. And that works. It results with a lot of tables and it's also a mess to maintain. Who uses this approach? Not so many people. Okay, so we have another approach. Another approach is a little bit better or leery. So we're going to do the opposite. We're going to create feature for every single field we have. And then we can create dependencies, well, for every single node, which also has a feature. Then we result with, you know, we have a lot of features, but everything is unidirectionally dependent of each other. So we can create views and those views will be dependent on nodes and nodes will going to be dependent on fields and everything is going to work okay-ish, but we are going to end up with a million of feature modules. Who does this? Okay. So it solves our problems. But do we have to think about this? Because now we have configuration management or short CMI. I don't know who invented CMI's configuration management. It's like occurring from initiative, but still we still use CMI and I use it as well, even it's wrong. So CMI allows you to do the stuff into database, export YAML files and then just add those YAML files in Git, add those YAML files, well, push them and then import them. Who uses CMI already? Wow, awesome! So and of course we have Drush and Drush helps us a lot with config export and config import and finally we don't have problem with revert features and whatever. So it's awesome. It's great. But let's talk about practices. What is good practice here or bad practice? For example, do not like the location of exported files, which is, well, in files folder. Again, this is totally logical because that's the only folder that is supposed to be writable by a purchaser or so, it's okay. But this is in some development environment. I want this to be somewhere where Git can pick up those files and just manipulate with them. So there's a fix for that, of course. In settings PHP, config directories, array sync item just can be changed to something anything and after Drush config export everything is going to be working perfectly. So we end up with a lot of files and Drupal took care of security so it added HT access, which is awesome. And now we can see hundreds of files with various settings. Those hundreds files can easily become 1,000 files in complicated projects, which could be a problem. So my initial idea when I saw this bunch of files is can I create a lot of directories and just categorize those files so that I can use them afterwards? No, I cannot, of course. It won't work. So if we want to categorize all those features, we are going to use features module again. But it got seriously updated and totally rewritten and now it is built on top of config management, which is awesome because now we are not using features to deploy any configuration or anything, so that's all by Drupal. We are only bundling configuration into various bundles or various modules. Now due to the fact that modules are being shipped with their own sets of config and that's the features are using messily. And that config is being imported into active configuration of Drupal on install. Drupal cannot really detect the changes on already installed modules, so features are taking care of that. Of course, features are exporting and importing changes. They are auto-packaging, which is the same they did before, so it's like normal. And they are doing namespacing and namespacing is really awesome. So it solves the big problem of creating a feature which already has a module with a similar name on Drupal.org and then who had that problem with name collisions of country modules and features? Anyone? Yeah, so you create a feature called blog and you're in problem because, yeah. So namespacing solves that. And of course the best thing with features is it's a dev module. You're going to enable it only in development environment. You don't need it on live server or on production environment. However, you still have problem with dependencies. And if you're going to use features for your stuff, you still have to use the same techniques you used before in order to manage dependencies. Nevertheless, good thing is if you disable a feature, you're not going to lose your content because all the settings you created are going to remain that. And that's huge advantage. That's something unbelievable. So as a conclusion, features should be only used to bundle configuration. You don't have to use it for deployment and that's awesome. And okay, so you manage to deploy your site and you start working on that. And there is this huge problem with, you know, people, site builders like to do these tiny little changes in live environments without, you know, moving stuff back to local and, you know, that's bad thing and we do that. So how to save ourselves when you have discrepancy between your local environments and your live environments and you want to keep changes in live environments. Well, the easiest thing you can do is, of course, to export settings in live environment added to Git, push them to the repository and pull them back in your locals. That works. Sometimes you have a problem where you want to keep both changes in local and remote environment. And for that, there is a thing called Drush Config Merge. Now I first heard about it six months ago and I still haven't tried it. But I read a lot about it and it uses Git to merge local changes and remote changes keep them all. Does anybody know anything about this? No? You should try it. I should try it. Somebody should try it. And talk about it. And well, this is my favorite, you know, just forbid config changes in live and that's, there's a module for that called configuration read-only mode. Just, you know, forbid it. Goodbye. Problem solved. Now, our installation profile is that. There's this thing we invented in Drupal 7 to create an installation profile during our web development process and then just all the modules, all the config, all the stuff we created just to put in an installation profile. So once we are done, once we want to deploy the site, we are going just to, well, push everything and install using that installation profile and we are done. Who uses this strategy here? Installation profiles. Not a lot of people. Okay. So it's an interesting strategy. It's awesome. It's easy to test and maintain and everything's good. But do we really need them due to the fact that we could possibly do something like this? We could build a site in our local environment, export files, push them, do minimal installation and then import config. Did anybody try this? How did it end? For me, it ended like this. So it turned out config management helped with continuous deployment but not with initial deployment due to the fact that once you install the site, you get site UUID. Once you install the site another time, you get another UUID. And that discrepancy just kills the kitten. So as a way around this, you can just do minimal installation, deploy files, push the database, just deploy the database and then you're going to have the same UUID and then you're going to just push files. Or you can use installation profiles. And we're back at the installation profile, same thing we used in Drupal 7. So you can just create installation profile. And really installation profiles in Drupal 8 are not that different from installation profiles in Drupal 7. So, well, directory is the same. Info files became Info YAML files. Install files are the same. Profile files, same. We're not packing features, well, or configuration into features directory. They're not modules anymore. We can just add all the configuration to config install. And modules are in the same place, things are in the same place. When you look at Info files and Info YAML files, it is really difficult to find the difference even though it's different syntax. So, same. And the only interesting thing is, okay, this setting files or YAML files that are being placed in some magical config slash install folder, and they just simply work. So one can really be attracted by this and try to do something like, okay, I'm going to build the entire website. I'm going to export my settings into some directory somewhere. I'm going to copy all the settings into installation profile. And I'm going to, well, install a new site with those settings. Did anybody try that? Did it work? Nope. I hate it. So it didn't work. And turned out, again, these files were built to do continuous deployment, not to do installations. So if you want to do installations, either you're going to cherry pick YAML files in order not to break the entire installation, or you're going to use features. So next, noble practice in Drupal 7 world is Drush Unsuck. Does anybody know what Unsuck is? So Drupal by default sucks. Drupal 7, that is. So, and nobody uses an overlay, I guess, I hope. Toolbar is a little bit, you know, useless. And you want to disable those, you want to enable admin menu, you want to enable module filter, jQuery update, I mean, jQuery 1.4, that's ancient. And of course, Drupal websites without C tools, use libraries, they're not really useful. So you want to do all that. But in Drupal 7, Drupal 8, you already have all of this. So the only thing I could find, as my standard Unsuck practice is just enable admin toolbar, toolbar which allows me to have this wonderful drop-down. So give them a try if you haven't already. Which ends up with all the old practices, and they're kind of the same. We have a new practice, totally new practice in Drupal 8, which is like Drupal 7 as well. So we have Composer. And Composer is de facto standard for, well, all the modern PHP applications today. It handles dependencies, it provides you with autoloader, it keeps the codes updated with Composer update, and it feels really good to use it. It's a shell thing, and it's really good. But the question is, is it Drupal friendly? Is it ready to be used in production environment? So let's start with basic stuff. So setting up a project. So with Drush, you would just use Drush DL, Drupal, and then install it. With Composer, syntax is a little bit different, but nothing too complicated. So sounds okay for now. There is this problem of performance. It turned out Drush is 10 times faster than Composer. So Composer with warm caches, totally full, everything up to date, needs 31 seconds to deploy, well, working core, and well, Drush needs only 12 seconds. Things can get really nasty with cold caches for Composer, then it's more than two minutes. So performance-wise, it's not so good. You need to set up Composer. You need to prepare the entire environment and everything to use it. So first thing you need to do is you need to use Drupal repository, and there's a command for that. Then you need to make sure that all the stuff you download are going to be in Drupal directories, not in slash vendor. So you're going to have to install this library custom installer and then add some settings into Composer.json file, which is not a big problem. And then, of course, if you're going to allow Composer to manage all your contrib stuff, you have to make sure that, you know, it ignores all the contrib stuff. Then you're in problem with patches, you know, if it ignores, and, okay, I'm going to talk about it later. So once you're done, you can get a module relatively easy. Composer require, I believe this is an error. It should be Drupal slash admin toolbar, so, yeah. But otherwise, and it's okay. Once you're done with it, just enable the module and it's going to work. Developers might like only to avoid this Composer thing and just just enable and it is going to download and install. So it is not really good. Well, the best performance thing ever. And I said patching. So you're pulling a module, you need to apply patch. If that module is not going to be part of your Git, then you need to apply that patch in production as well. So there is a way to set up Composer to apply patches, but it is not by default supported. So what you need to do, you need to add this library Composer patches and you need to then in this patches file, add, well, connect patches to patch files to, well, modules installed. It's a lot of setups. So somebody was smart and gave us Drupal Composer, which is, well, starting point for you to bootstrap all your Composer projects. It already supports patching. It's already supports custom directories, scuff folding. It has a pre-built Git ignore and all the goodies you really need. So just touch with it and it is going to work. So with all of these things built in, if you are using Droshmake workflow, Composer can really help you and replace Droshmake workflow in a way that is going to be readable to other PHP developers. However, there is this big question. Can I sell this to my boss? So I probably can sell Composer to your developers, but managers are a little bit different. So they are going to ask me about return of investment. They are going to ask me about, okay, so 131 seconds against 12 seconds. That's kind of bad. So I still have not the entire answer. I know that with Composer you can save a lot of time on deployment. So for example, platform s age already included this entire Composer build into their workflow. So once you push all the changes, well, in Composer file and only in Composer file, it is going to install all the required modules. It is going to install all the dependencies for you. It is going to apply patches for you. So it is going to be, well, it is going to do a lot of wonderful stuff for you. And I hope this process can, well, save enough time or provide that return of investment your managers require, hopefully. And to conclude, I started this session as, well, story about best practices. But the question is, do they exist? And I don't really think they exist. So I would really like to call them current practices. And why current practices? Because they always need to be questioned. They always need to be refined. So when you have some idea, it should be documented. It should be time-tested, rethought again. It should be shared with other people, again refined with them. So other people should question and refine those ideas. And it is a circular process which returns back to another questioning of practices. And hopefully that will provide us better software and better working paradigms. Thank you. Questions? Yeah? If you're using Composer, how would you, can you go to the microphone? I can repeat. So the question was, if you're using Composer, how can you add your custom modules to it? Basically you don't. You don't. You just push it in, get in, continue with that. Unless you're happy to share it with other people. And then there is a process for that, of course. Which includes publishing it to the Drupal org. It doesn't work. I can repeat. Does it work for Multicite Composer? Does it work for Multicite Composer? I have no idea. It should be working. I mean, why not? But because Composer only handles files and dependencies. And they are shared between Multicites. So I don't see the reason why not. So the question that was asked earlier is, we're currently architecting it so that we have a site repo that has a module in the themes directory and then the composer JSON. And so then what we do is run a post script after you do your Composer build, that sim links those folders where they need to go for Drupal. I'm not going to repeat that. It's too much. But if you want to use the microphone or, but yeah. Anybody else? Yes? Ladies first. I believe last change was really good and it was in September 22nd on Drupal org. So and it's really full of new stuff and it's good. But I suggest you to take a look at this. Oh, wait a minute. Okay. So this Drupal Composer thing or platform message example Drupal 8. Because it's basically everything you need to know about Composer. It just squeezed in and with it, you're just we just clone this and you're ready to go. No problem. Yeah. Any questions? Yeah. Okay. So the question was, what's the best way to handle situations where you have multiple environments and you want various configuration to be in various environment? So I have no idea. I guess, well, that's really interesting question. I guess you would have to use features and just decide where to enable those features and where not in which environments. So I guess, but it's a good thing to think about in terms of how to create this best practice for that or recommended practice for that. Yep. Yep. I can try to answer what question about Dev and if you want to not to deploy Devol for example, there is a Drush CEX to export, but you can use skip modules and you can give names of modules that you don't want to export so that it's not in your git. You don't have the problem with config that you don't want to have in production and another problem is with config that you want to be different in production or in Dev and you can use, I don't remember exactly, but you can write it in files, some like you can override the config that is in database with config that is in files like in settings and things like this so that even if in your form, in your config form, you see like CSS is a CSS packaging, compressing is on, actually it's not on your Dev because this config that you see in the form, it's overridden by a file. That's it. But there is a little problem with Drush CEX skip modules because it skip some modules but not always the config that depends on that modules and I'm currently working in a patch of Drush to do this and I'm not the only one, but it's still a little problem. Thank you. Well, it's, I'm only thinking about how to automate all of this so that's kind of next question. Okay. So you still need manual power, human power to decide what is going to which environment but it would be interesting to think about how to automate the process. Other questions, comments, rotten tomatoes. So the question was, if I heard correctly, isn't it possible to just disable modules with some settings in various environments? Oh, that actually could work. But then you cannot really, you cannot really, hmm. So if you'd like to have various settings, local settings in various, that could actually be interesting to try. I have no idea. But yeah. Anyone else? Okay. Thank you very much. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you.