 Well, I think it's time. Thank you for coming to the session. Grad NCLI command for Drupal 8 using symphony components. Always showing you how to create custom commands for Drupal console. It's a D8-only project. So how many of you are working with D8 already? Client, like, really? Production projects, nice. Awesome. How about Drupal console? Did you know that? Exists? Tried before running it? Great. That's great. Well, first, I mean, my name is Jesus Manuel Olivas. You can find me in GitHub, triple.org, different social networks, that's J-M-O-L-I-B-A-S. I'm a co-founder and head of products of Winno. We are a company, a fully remote company. We do mostly Drupal, but we also do some symphony silo-exlarval work. We've been doing some JavaScript lately, React and Meteor as well. And we were also working with a lot of automation and DevOps stuff. But most of our work is still Drupal. Again, we are fully remote. We are in, like, 12 countries now. Mostly in Latin America, from Mexico to Argentina. There's one guy on Australia, and there's someone else in France. Let's talk about a little bit of the agenda of the session. First, I will spend a few minutes talking about what Drupal console is. So if you're fast and you get bored, it's like telling you what it is for those that are not aware of the project. I will mention about the differences how to install the project, because still some questions often about how to get the project working in your system. And yes, you have to install it locally, and you can also have this global executable that we call Launcher. I will talk about the differences of both. I will also mention how to create commands for Drupal console, how we talk about something we call chain commands. I don't know if any of you is aware of this feature. So if you like automation, you will like this feature of Drupal console. And finally, I will talk about what do you need to contribute to the project. And well, first thing first, so what is Drupal console? Drupal console is a CLI tool to help you to generate boilerplate code in the first place. And this is how the project was born as a code generator. This is probably the part of the project that shines the most, because it saves you a lot of time by generating different components of Drupal. So you can use the CLI to run one command, and that can help you to generate forms, plugins, controllers, modules, entities. A lot of the Drupal 8 components, we're always adding more features. So at this moment, we have more than 30 something, 38 generators. There's always room for more. There's a specific need you have to generate something. You can just let us know. Open a new go to GitHub, open an issue, and we can probably keep adding more features to the project. And well, again, Drupal console is as a scaffolding tool, but it's not only that. So it's allowed you to generate boilerplate code, allowed you to debug the system. It means it can help you to list or debug different subsystems of Drupal, like all of the routes on the routing system, all of the services on the service container. You can also do tasks beside those tasks, cogeneration, debugging the system, and you can also do daily tasks for administrating your site. You can enable modules, install and install modules. You can export, import configuration. If you use features still on D8, you can also import features from there. So you can do a lot of those daily tasks that you do with your Drupal site. First thing, something that must be clear as Drupal console should be installed per site. When we started the project, Drupal console allowed you to install it globally. So something like Composer, Global, Require, la, la. But once Drupal started doing more releases like 8.1, 8.2, every version of Drupal ships with its package with a different version of Symphony. And we find out we have a lot of issues with compatibility with some of those packages. And probably the big problem, it comes when Drupal switch from 2 to 3 is something that's going to happen again while it's going to happen in 8.4. So in order to avoid all those conflicts between different versions, you're having a global who has, let's see, 2.3 or something, and then you have your site with Drupal with some different version of the Symphony components. We decided to go the other route. And actually, this is how Composer should be used. Composer should be used locally or to manage your packages or your dependencies per project. And how do you get Drupal console in your project? It's as simple as running one command. Composer, Require, Drupal console. And this command will take care of downloading Drupal console in your site, right? So basically, go to your site, CD, the part of your site and run Composer, Require. And you will have Drupal console locally in your site. If you have your site like that, I will show you what can you do to save you time for finding where the executable is. If this is a new project that you're just barely starting, what I highly recommend you is to use this project. This is Composer template. It's called, people call it like Drupal Composer. And you can get a fully working site just by running one command. Composer, create a project. And you have the project name. And this will take care of downloading Drupal, Drupal console, Drash, Behat, each unit. So this Composer template allows you to download a fully Drupal package. Once you have Drupal console in your project, well, since this is a stopper project, it has an executable. The executable is located within vendor being Drupal. So you can start typing vendor being Drupal. The problem here is if you change to the web directory or the doc root directory, then you need to go something like dot, dot, vendor being Drupal. But what if you are within modules, custom one module name, then you need to figure out where you are at. In order to avoid this, we provide with a global executable. The global executable is like a minify version of Drupal console with just a few commands that can allow you to find your site. So once you start the launcher with this instruction here, you use curl to get the project. Then you move your project to a global accessible path in the system to just make it executable. Once you have this, you have one global command in your system that is called Drupal. You can name anything you want. Drupal is only in ALS. Then you can type Drupal from your Drupal directory. And you no longer have to figure out where the vendor being Drupal is. So once you type Drupal within a Drupal site, it will find the vendor being Drupal executable for you. You can also run Drupal and then do something like dash dash root equals 2. And you can pass a path to a Drupal site. You can also take advantage of site aliases and register those aliases either globally on your project and go something like Drupal at alias name and then any command that you want. One of the latest features we added, it's to, we allow to run Drupal console to containers. So we allow an extra option on the aliases definition. So you can prepend their docker, exec, something, something, something. So you don't have to do that manually. So you can just add that in your site alias definition and you run Drupal at site name. And this will prepend those options automatically in your command execution. So it's kind of saving you for, keep typing docker, exec, container name, you know, things like that. And we did that because we used a lot of docker in our development and we want to make our life easy and the rest of the people life easy. Before jumping into creating a new command, I want to tell you there's a command for that probably. We have more than 150 commands now. So before trying to get a new one, just probably there's something already there. Just take a look at the other project. In order to find out how many commands we have, you can just probably go to install Drupal console and just type Drupal. And from here you will see a list, all of the list of the commands we have currently available. You can go here and figure out which commands we have. I mean, there's another list that's huge, it's kind of hard to see, but you can do something like Drupal list and then just type namespace, like in this case, generate namespace and it will filter the result only by the generators. If you don't want to do that, you can go to the documentation, which is docs.drupalconsole.com and from here, you can select any of the languages where the documentation is and we have this available command section. This section lists all of the Drupal console commands, all the latest Drupal console commands from here, you can just go to the specific command you want to see and you will see the definition of that command. You will see all of the available options here. You can also, at the very bottom, you will see examples of that command. You can do that the same thing from the CLI, you go Drupal, then the command name, hyphen, hyphen, health, and that will give you the same data that you can see here. All of the documentation is automatically generated by Drupal console, so we have commands to generate all the documentation, because I mean all of the metadata of the project is stored in Jaml files. So we decide to add the extended symphony console component and make those commands translatable. We take all that metadata to render the section, the available command section of the different languages automatically with the project as well. Okay, well, and again, we also provide some commands that can allow you to do things like real quick. I mean maybe you want to run something, but I mean probably creating a command is a lot of work. So we provide the Drupal shell command, but this command allows you to do, you can go to your site, you go Drupal, type shell, once you bootstrap the command, you can do something like this, let's define a variable, then now let's get a service from the Drupal, we're using the Drupal static class for calling a service from the container, so let's initialize entity type manager. I'm using again Drupal static class for gaining the entity type service definition, and from here what I will do, I will execute, I will query the nodes in the system and I want to load the node ID one, and finally what I will do here, I just echo what I want. So what you are planning to do is something like real quick, maybe you don't want to create a command, no, I don't want you to create commands. Something real quick could be something like this, just Drupal shell, and start typing PHP code, and this project we are using, which is called PSISH, can allow you to interactively debug and run PHP code, and what happens when you run the shell command is we bootstrap Drupal for you, so any service in the container is immediately available. You can do anything you can do from a module, or from a controller, or from any place, because Drupal is already bootstrap for you. And so any feature that will show up in the next version, so this is something that we just still don't have available, is the snippet command. Let's say you might want to run something real quick, you can write your one PHP file, and then run the snippet command, you know, and this will execute, this will execute that PHP code. So what I'm doing here, I'm calling the snippet command and just passing the flag file, and I'm just giving the pack to a PHP file. You can also pass this option that is called show code, but this option will do, is will output the content of the PHP file, and will execute it at the very end. So you can do something like this for something, you need to delete all of the content types on a specific type, or you can do like a query, you do something real, real quick, that might be is not generic enough to write a command, you can use this option as well in snippet, and just run it called a file from your local system. I mean, still we are having released this feature, we are trying to figure out, add more features like snippet, debug, and if you can, what you're planning to do, I mean, we are open to ideas, so having a directory on your project, something like console snippets, if you have different files there, we can automatically discover them and list it for you, something like I've enabled this debug a snippet command, or at least all of the snippets that you have in your system, and we are thinking to add this discoverable mechanism in two directories, one is one within your site, and one globally within the dot console directory, I mean, directory, and then snippets directory. So that's part of the idea, this is probably what you will see on a future version of Drupal console, but if the snippet command will show up, probably a one to version from now, and from there, we're gonna keep iterating and adding more features to it. Well, now let's talk about how to create a new command. And as you know, Drupal console has a lot of generators, so we have generators for your commands, so we have commands to generate commands for you. And if you are already working with Symphony or with the Symphony console component, and you already growth or write a command, you will find out that writing a command for Drupal console is just exactly the same as Symphony. We create a class, we create on the directory, we register as a service, and that definition register they command on the container. So, I mean, if you have done this in Symphony, it's just exactly the same what you will find out on Drupal. By the way you register commands on Symphony, you have this something that is called the command life cycle. And this consists of three methods. The initialized method that is optional, this is where, as you can see, based on the name, you can initialize anything, any values from that command. You can also have the interact method, which is also optional. This is the place where you put all the logic for asking questions to the user, right? If you are using Drupal console before, you run something and then start asking you, what's the module name? What is the, which is the path that you want to generate this? I mean, you want to do, you know, inject the service from the container, so all those options, I mean, all that functionality for asking questions to the user or interacting with the user and getting input from him, this is, you have that, or you just grow that on the interact method, which is also optional, as I mentioned. The only required method, I mean, of this life cycle is the execute, which is when you have all the business logic for your command execution. And you also have a method that is called, there is named configure, this is where you give your command a name, or you give, like, you add options to it. I mean, if you want to have, like, options for, like, that I show you a hyphen, hyphen file, or you know, all those options or arguments, you define them within the configure bit. But the life cycle consists of the interact, I mean, initialize, interact, and execute. Okay. While working with Drupal console, you will find out you can add commands to any extension, like in this case, when I'm talking about extension, I'm talking about modules, themes, or profiles. You can also add commands to external packages or external libraries. It means you can add commands to, to an standard PHP project, not only modules. And what the benefit for that will be. The benefit for adding commands to PHP libraries is you can just register those, you can call those, or something, composer require my library name, and then hyphen, hyphen, depth. So when you deploy your project, those commands won't be available on your production server. Remember, those commands are for administration only, and you don't want them to end up on the server, so you can add them in an external package. And the benefit of that, it's Drupal console automatically discover those commands and register on the container, and those commands, you write those commands just exactly as a command that lives in a module. The only difference is you don't have to install a module, because when you install a module in Drupal, you end up exporting configuration, and that configuration should be changed to you uninstall the module in order to deploy. Now we have config split that allow you to limit which configurations you want to handle per environment. When we start the project, it wasn't like that. Drupal used to manage the whole configuration as one big feature, and you have to explore all the configuration on nothing, right? And how this works. Drupal console command should extend any one of the two base classes that we provide as part of Drupal console core. We provide a command class, which is a basic class that allows you to make your commands translatable. So once you extend this base class, then you can take advantage of the translatable feature of Drupal console, okay? And it also allowed you to do some, I mean, I'm allowed you to do some things that Drupal console requires to it. But I mean, you don't have to worry about it. But you can also extend the container in word command class. I don't, I mean, I really highly recommend you to use the other one or the container in word. Use the other one, not this one, right? This is because by using the base one, you have to register, you have to use dependency injection to inject services to your command, which is that recommended way to do that. By using this one, you have access to the whole container, which at some point could be a little dangerous because you have access to any service from the container. And then make your command harder to test, right? If you use the base one, you know exactly which services you are inject. So let's jump into generate a new command and see how this looks like. So as I mentioned before, we have a command to generate commands. I'm gonna copy this one. First, in order to generate a command, I need to have a module. So let's call this web modules, custom, let's see. Okay, we don't have nothing here. So let's run this. What I will do right now, I'm just going to run a Drupal console command, but I'm skipping the interactive mode just to make it faster, right? So I'm using, I'm passing every single option as part of the command execution, right? And as you can see, the very last option say no interaction. I'm trying, what I'm telling Drupal console to execute based on the option that I'm passing and just skip any possible interaction. So generate the module and the module is there. Let's run a tree command. Yeah, sure, three. Okay, there's one file because in order to register a module in Drupal 8, you only need the info.juml file. There's no longer need for, I mean, adding the .module. So that was simple. That was kind of silly if you want to think. This is just one file. Got a module example. That's all that generates for you. Okay, let's now generate a command. In order to generate a command, let's use this generate command command to generate a command. And as you can at the very bottom, as you can see what I'm doing, I'm generating a command. I'm telling, okay, I'm generating, I want to generate this one and one in a specific extension. As you can see here, I'm calling this extension and not module because you can add to different, I mean either module, team or profile, and I'm passing another option, which is extension type. This is the value that I'm using for it, specify which type of extension is this. And also what I'm doing here, I'm just injecting the entity type manager service. So I'm using the hyphen hyphen services option to inject a service to my command. So what I will do here is run this. And this will take care of generating a few files for me, create the, I mean it also takes care of creating the proper directories based on the names that I provide on the command execution. So it takes care of creating the SRC command, the default command PHP class, and it's using default command because this is the name that I gave into the class so you can name anything you want, right? But it also, it takes care of generating this console that services YML file. Let's see what's inside those files. So it takes care of doing something like this. What this definition means, this is registering my command as a service and I'm using the arguments section here and this command definition to inject a service on my command. So instead of making my command container aware, I'm just extending the more basic command class and I'm using dependency injection to inject the only the service that I really want to use in this command. You can inject as many services as you want to, but again, it's easier to do something like this because then your command, when you are inject, when you're using dependency injection, it makes it clear for you and for someone else in your team to find out which services you are really using on your command execution. And something that you might be notice, this is not called module name that services, it's called console that services and we did that because when we first started the project, we used the standard module that services that YML file, but what happens, Drupal tries to raise all the services on the container. If you don't have Drupal console in your site, then your site just breaks. So we decided to go the other route and just use a unique name. So it means your commands are only available while you are working through the ZLI. It means those are not available through the Drupal execution. There are some people asking about make those commands available through the graphical interface. So what we can probably do is provide a module, something like console or Drupal console connector or something like that to add those services in the container. I mean, we still haven't decided go that route but there's people asking about it. Okay, so we have that. So we generate the module, so we generate a command so now this command is available, it's doing nothing. Let me show you what it happens. So this is the service definition but if we go through the command class but we can see this is what was generated for you. Again, it generate the file, create the directory structure, you just add on the proper namespace. It imports all of the classes that you require by the use statement. And again, this is exactly the same class that you can find out in Symphony. As you can see here, my command is extending the command class. My command class is here. It is located in Drupal console core project. So I am only making my class, extending this other big class and that's it. The only difference between a Drupal console command, a Symphony command is this little doc block. What we just decide to go, the route that we decide to take is anything that it's like Drupal only related to the command will be used through annotation, right? So we are using the doc block to define an annotation. We create an annotation called Drupal command and this is where we define Drupal only features or Drupal only metadata for the command. So we have something that we call extension, which I'm telling, you know, this command is living in an extension and the extension name is example. It means only if this module is enabled, this command will be listed in your site. So if I go here and type Drupal and I give it the name as example default, if I run this one, it will tell me that command is not available because I have not installed the module. So this command makes, I mean, it's just, I mean, it will be available only when the module is installed. So let me run Drupal module installed example. This will install the module, it will clear catch or reveal catch and then my command will be available on the system. So command is here. It tells I am a new generated command because the only thing that we add on the command generation, it's the basic method. We have the execute and the interact. And as you can see, the interact is optional, but it gets added because I use the flag interact here. If you don't want to add interaction, you don't have to use this flag and then that method won't be added in your command class. And again, what happens is my command is extended to the other, you know, the command-based class. The difference between, again, the command and the container-aware command class. So instead of running this one, you use the container-aware command class and then within any method of your command, you will be able to run, do something like this, this, and then get, and that will get any service from the container. Again, don't do this, this is dangerous. Again, I already mentioned this, all of those command, or every single command should be registered as a service. I mean, you don't have to worry about that, you want to inject services, just run the command, select the services that you want to. If you don't know which services you want to run, you can run debug container, Drupal, debug container. You can see all of the services in the container. This is a huge list. I highly recommend you to use PECO. This is our tool, build and go, that allow you to interactively filtering the results. Let's say you want to use a user, and from here you can read which services you have on the container. If you run the generate command in interactive mode, there will be a question. Do you want to add services? And if you answer yes, then you will be able to select services just by typing service name. So it might be the first time that you generate a command, you will be running that using the interactive mode to learn how the command works. Sometimes at the beginning, it's easier to use the interactive mode. Once you learn how the command works, it's easier to just kind of use the options, passing the options through the command line execution. So we have a command that at this point is not providing any functionality. Let's add a little functionality to it. What I will do first, I will add a new option to my command. What I will do, I will first import the input option class on my command. I will go here. Then I will go to my configure method and add this new option here. Let's work on the indentation a little. What I'm adding here, I'm adding a new option to my command. It means immediately after doing this, I will have something like hyphen hyphen nid and I will be able to pass a value through the command line execution. So if I call g, if I call this help, you will see on the help section of the command that I have this nid option available. Let's keep smoothing. Now let's add the interaction. What I want to happen when executing my command, I want to, if I am not using the hyphen hyphen node ID and giving it a value, I want my command to ask me for that value. I want this command to ask the user. So what I'll do here is copy this code. I will explain a little. What this code is doing, it's trying to get using the input object is input get option. So it's reading the option that the user is providing and it's just asking if there's no option, then use the object and use the helper method ask. What is going, that is going to happen is going to appear like enter node ID question and I will be able to get that value and store on the option. So as you can see here, I just get the node ID and use the input object set option to store that value, to have that value available on the execute. Remember the life cycle? How that life cycle executed is initialized first and interact and then execute, get executed at the very end of the life cycle process. So my interact method is here. So it means if I run the command without passing the option, it will ask me to do something. And finally what I will do, I will go to the execute method and add some business logic. It's pretty much the same functionality as the other one. What I will do here, instead of showing this, I'm in the generated command, what I will do. Not sure if I can do, oh yeah, I can do this. I'm doing the same thing here. I'm going in this one. I'm reading the NID option. After this, I'm executing the exactly same code that I use on my SNPET file. What I'm doing is reading the node ID. In this case, I will give it the value of five and I'm using the entity type manager service that I use injected. Remember the service definition where I use the arguments section that I inject in the entity type manager service. So this gets automatically available because as you can see here on the constructor, we are receiving that service and storing this on a local property called entity type manager. So this means I can do this entity type, entity type manager, and the entity type manager service will be available on my command execution. So what I'm doing here is reading a value, then using the node storage and loading a node using a node ID. If there's no node ID, this isn't a non-valid node ID, it will return an error, like something like error invalid node. And if it's a valid one, it will tell me something like the node label. So let's execute this one. Let's first do nothing. Remember the interactive mode? Now it's asking me for a value, because I didn't provide a node ID value. Hit Enter, and this is the value. Remember the other execution, the snippet execution that is here? So I'm using the same number five, so I'm getting the same value from the database. What if I say NID equals to five? What is going to happen? It will just keep the interactive mode and go right through the command execution. What if I don't provide this one? No interaction. What is going to happen if I say no interaction? The command execution will escape the interact, I mean execution, so it means it will not ask me for the value, and then my command will break and give me an error message, you know something like invalid error, because this is not a valid one, right? So this is how you write a command, which is like pretty simple, run a generator, making sure you add your business logic on your execute method. If you're required to, and if you are planning to use one of the services from the Drupal container, just inject that service, I mean while running the command generation. It keeps moving. Okay, again, as I mentioned before, you can add commands to packages. Any packages doesn't have to be like a module or profile. And in order to do that, the only thing you need to do is define your package as a Drupal console library. That's the only thing you need to do on your standard PHP package to let no Drupal console, you know this is a Drupal console library and it contains commands. So and then what we are doing, we just wrote a composer plugin for doing this, so we scan the libraries on your side and those that are Drupal console library, we scan those for commands and we register those commands on the container. Command definition is just exactly the same as commands on modules. You use the console.services.yml file and you tag your commands as Drupal command. Sometimes you need to execute commands even if your Drupal site is not installed, right? Let's say a command who probably takes care of site installation with reading data from a specific place or anything you want to do. If you want to do that, you can use this tag called bootstrap on install. I mean, we've been discussing for months, you just give it a better name. I mean, so we are open to ideas. We just give something like bootstrap on install. We were not happy with the name, but we haven't like really came with a better name. So again, we're open to ideas. And again, this is required if you want to make your command available even if Drupal is not installed. So basically, if the bootstrap is not happening, that command will be available. And how you add this to your project? Well, you create a package and then you do composer require and give your package name. And again, we use those mostly for commands that we don't want to end on the production server. Well, global commands, which you can still have global commands with Drupal console. It means you can have one few asset of commands in within your dot console file in your user. In order to do that, you need to go to, you need to create a console, that console directory in your system. You can do this by hand or by running Drupal init command and select your user directory that will take care of that for you. And we create a project that is called console extend. It is a composer template that allow you to have global commands in your system. What you need to do is go to that directory and just run composer create project, use Drupal console extend, just give it the extend directory name and this will create a new project for you where you can start requiring a composer require in your standard packages that contain commands. And again, you add commands used by composer require. We already provide a Drupal console extend example project, which is here. You are, I mean, feel free to for this one if you want to add commands like either globally or within PHP packages. As you can see here, the type of the composer project, if internet allows, and it's not that slow. Fortunately, I didn't run a composer create command. Well, once this happened, come on, open. Yeah, it's here. As you can see here, the only requirement of your package is to set as type Drupal console library and from there, what you can find out is we have a project, this project already contains two command classes as example, example one, it provides some basic command definition for you. Example two, it's pretty much the same one. Yeah, but this one is container aware, right? And it also contains the server, the console that services definition for registering your commands. So you can just fork this one and play around with it so you can add commands to external libraries. This is only, again, this is only for external libraries if you want to add command to a module, profile, or a library instead of copy, fork in this one, just run the, you know, the Drupal console command, the generate command command. Let's go back to the project, the lights. Change commands, this is probably one of the features that I really like being enjoying the most, working lately. A chain command, it's a feature that you can use in Drupal console. So you can allow you to read a Jammel file definition that can contain multiple commands. Let's say I can't have a Jammel file, but I can say I want to execute, you know, something like generate this, generate that, or, you know, site install, install this module. So you can preset different commands within a Jammel definition. You can pass options and argument. So we use this for do a lot of the automation that we do for our clients. The benefit of using a Jammel, I mean, a Jammel file and a chain command is you can define placeholders. I mean, you can have placeholders within the Jammel definition and provide values through the command execution. You can set placeholders and do something like hyphen hyphen and give the placeholder name. And so those placeholders get automatically, I mean, register as options in your command. You can also read environment variables. Let's say we use that a lot when running commands within Docker containers. We'd set this .emb file that contains, you know, your database credentials or any API credentials. You can read those values on your EMB by using chains. And you can also register those as commands. So how this looks like. See, this is how this Jammel file looks like. So we have something like this. We have this create data Jammel file. This contains the first lines, the first three lines. This is where we define the command name. We have the command section of my file. And here I can give it a name. I can give it a description. And then we have the commands in little section. This is where I can start adding commands. So I want to run the create users command and I can pass options. I can use the option limit and give it the value of five. I can have, in this case, I want to run the create vocabulary command and just use the limit five. But I also want to pass the option name words. The same way you can see, we are using options. You can also use arguments and pass values to it. So basically you can pre-define a set of commands and give them default values to run those on your system. It means if I go here, Drupal, create data, what is going to happen, this command again gets automatically raised on my site. Well, it executes several commands at once. And the only requirement that you have to do is your command should be living within your site. You have this console directory and within that console directory, there is a chain directory. Any files on that, any JAML files on that chain directory will be automatically discovered by Drupal console and will be registered as a command, right? What else you can do with this? We provide some chains, chain JAML files, I mean recipes, if you want to read them, call like that by default on the project. If you run the Drupal init command and you answer yes to the option of copy chain files, what is going to happen, the chain files, the recipes that we provide as part of the project will copy it in your home directory so you can play around with those commands. I mean, a little example that we have here, we have this site new command. I don't know if you are aware of this, but at some point we just have a site new command that allow you to download Drupal and for you. But then at some point the command just broken and we remove that and people ask, can we just get the command back? You are like, we really want to do that. Like, we didn't want to have a command, I mean, write a command for that because we switch from downloading Drupal from Drupal.org to Composer and we end up having problems with that. So what we define this site to do instead, we create a chain command. And while using chain commands, our chain commands allow you to run Drupal console command but it also allows you to run any shell command. So you can run Composer from here. So the site new command, what it's doing here, it's just running, you know what? It's running Composer create project. And the value from the repo, as you can see here, this is a placeholder. You can define those placeholders here. You can provide even default values for those and provide and make the command ask for those commands interactively. It means if I go site, if I run this command, I can provide a specific list of values here. We also have this other guy that we call Quickstart. I don't know if you're aware of this command. This command allow you to download Drupal, allow you to do a Composer create project and also install Drupal for you using SQLite. And finally, let's start Drupal from you. So basically you can just have a fully Drupal 8 working. I mean fully Drupal 8 inside, like in minutes, it will depend on how long Composer takes to run. But if I run Drupal Quickstart here, let me run this one. First, let me get a directory because he will ask me for it. Quickstart, remember what I showed you about the bars section? You can define placeholders, you can define the value. So if you define a placeholder as an array, you will have those, I mean an autocomplete here. And if you don't define this array, then it will be only like single value as you can see on a standard. So a standard is defined as a single value and repository is defined as an array. And the difference is on the execution, it asks you a question based on an array in a list that you can choose for autocomplete or you can use as a standard. I'm not going to run this because it will probably take way, way longer. Going back to the slides. And again, you can register, you can give it a name and it will automatically have element in your system. And well, this is the same example that I showed you. And every single placeholder you do define, it's registered as an option on your command. So instead of passing for the interactive mode, you can provide those values directly through the ZLI execution. So you can do something hyphen, hyphen directory and give it the value or something like repository. Let's create a new site using Accio distribution, the line distribution and just make sure you create on this directory. Now let's go to the final part of the presentation. How about creating commands for Drupal console core? Well, Drupal console is a modular project so we break the project in like different repositories and we have Drupal console, we have Drupal console core, extend plugin, which is the one who takes care of registered commands on external packages. We have console.emb, which allows you to create and register, created EMB file for you, make changes in your settings file so you can use EMB variables in your system. It also adds an external package called .emb, PHP.emb package. So it's allowed you to run, through using EMB variables. And we also provide some other packages that we use for development, which is the console.jaml and console.develop. So if you want to contribute to Drupal console, for a long time, this is always like a nightmare because you need to get the project and then we end up hacking around, we're providing a way to change your composure file to sim link your site to the project because you can fork the different projects but in order to test Drupal console to start getting complicated if you're not run those projects within a site, it's a little complicated unless you go to the vendor directory and fork for there, but it was a little messy. So what we decide to go is we provide a command to take care of all that for you and that's a chain command. What you need to do is just forward the repos on GitHub and just clone all the different repos and using a same root directory. I'm gonna use Drupal console code as a directory and from here I will clone different projects. And the only thing you need to do is run develop contribute command. This is a global command that we provide you in order to have this one in your system. Make sure you run Drupal in it and you need to pass two options. First, the path where you want to create a new Drupal site and then the directory where all of the projects are for it but it's going to happen, it will create this for you. It will sim link all of your vendor, vendor Drupal console project to where you fork the project. Drupal console core to the directory that you have cloned. It means you can use your IDE, go to the project that you fork, make changes and you can automatically test those changes in your Drupal site. We also provide to default commands for you can copy and paste to do your work. It's called example command, example container work command so you can start from there since we don't have a generator for Drupal console core command. The final note, Drupal console is a symphony application so the coding style that you will find out is maybe a little different than Drupal because Drupal uses its own coding style. The generated code is Drupal coding style compatible but the code within the application is a little different. So Drupal console is not a Drupal module, it's a symphony application. So make sure you can run a PHP code sniffer to fix that for you or use your prefer IDE like PHP storm to take care of the indentation and all that. And that's all that I have, so thank you. I think we have a few minutes for questions so if you wanna ask a question, make sure to pass to the mic and ask anything you want to. If there's no questions, I have stickers, Drupal console stickers, if you want to just show up here and you can use stickers because we all love Swag, right? Yeah, a Drupal site and you don't want to create a new one. Let me share something else. This, so they develop, contribute, command, it's only a chain command. So they develop, definitely, they develop, I mean, contribute, command, what it's doing is calling a composer create project so it basically is downloading Drupal for you and it's adding a new package to your site which is console develop. So this command is the one who has the new create develop create simlinks command. So this is, if you want to develop a Drupal console, you create a site, you require the composer to develop, so you can do all this by hand, but we automate it because we just tend to automate anything that we do. So we add the package for you, we install Drupal. As you can see here, I mean, download dependencies, console composer install, so it's downloading Drupal and all dependencies. Then we install Drupal for you using SQLite and then finally, we run the Drupal create simlinks using the placeholder that you are providing on the command execution, just where the code is, where the Drupal root is, and this basically gets, do all that for you, simling all of the directories, make a little change on the project that you need to do the proper outloading, outloader for it, so you don't have to worry about nothing, you want to contribute, just work those, run this command and you're happy coding. So basically we have, we are, if you run all your like Drosh aliases, like Drupal, DB, so we have a way for mapping, though. Oh, okay, I didn't know that. No one knows about it. So there's a lot of like things that are, there's a command that I want to show you that is not yet documented, it's called Drosh. No, it doesn't require Drosh, we have a mapping. If you use the command, again, if you use DB, what it happens is execute the Drupal console, I mean, I mean, the exact.