 Can you hear me? Yes, that's amazing. OK, so today we're going to talk about plug-in API. It is by examples. I'm Gabby, or gambry in Drupal.org, or Gabriele, which is my name. I've been a PHP developer for too long, actually. Drupal developer for almost 10 years. And I'm the lead Drupal developer and manifesto. I like Drupal like PHP and JavaScript. Currently, I'm playing with chatbots and encryption with Drupal mainly. And I'm currently watching Altered Carbon. It's a TV series, so I like it. And I'm just really excited, so I put it on my slide because I think it deserved a mention. So again, today we're going to talk about plug-in API by examples. I don't like examples. I don't like to go on Stack Overflow and copy and pasting because I think it's the best way to not be a good developer. So the example to them giving you, they should be a spark of curiosity. And then you go back and check the code and check my slides and check other people's slides and other people's articles. So you can make the topic your own. So don't copy and past, OK? I'll repeat it. Fine. Everybody, is there no Drupal developers in here? Or someone that doesn't know Drupal at all? No? Fine, cool. So you should know what entity is. All the session will be full of examples, right? So everything will be an example. What could be an example of an entity? It's something that's like a same model just with different data, an article or two articles. They're the same model, right, with a title, with a body. We just place different data, but the model is the same and it's stacked. And one example with the origami bit is we have a shape, which is, for example, a butterfly. We use different paper, different colors and pattern to build the same model, so to build the same butterflies. We can have a lot of butterflies with different colors, but we'll be again the same model and the same different data. In your project, an entity, again, is your article and is not shareable between projects. You don't have the same article in different projects. It's the model itself is not shared across projects. You can have the articles in all the projects, but all of them, then, we have a different bit, so it's not easily shareable. What plugins are then? So plugins are the same thing type in different ways. Taking the origami example, we want to make animal shape with origami, right? So it's the same thing as an origami animal, but in different ways. We can have an elephant, we can have a lion, we can have a giraffe. The concept is the same. At the end of the work of the process would be an animal made of paper, but the process to reach this final result is different. To make a lion is a different process than to make an elephant. It's completely different, but the output that we have is the same. So if we should compare with the entity, it's shareable between projects because it's the same thing type, so we can have an art competition and we can use the same origami. I can take this presentation and do the same in different presentation, so the plugin itself is reusable. You can change a few bits, but it's thing that you can reuse in your project. If we start again with examples, let's take some plugin types, examples in Drupal Core. Feel for matters, feel rigid, feel block. We probably know the fields are plugins, so the field is a plugin. It's the field components that are plugins. Blocks are plugins, migrations are plugins. So let's try to understand the concept that we explained in the slide before, applied to the Drupal Core plugins. So it's the same thing type in different ways. Feel for matters are form elements to get the values input, right? It's a form element. How many form elements do we have? A lot of them. It's a dropdown, it's a check box and the complexity for the browser to render it or for you to build it. It's different, but at the end of the way, so it's a different way to build a form element, but at the end of the way, it's a form element, right? You get the data, it's the same form element. Feel rigid, again, feel rigid are HTML elements, normally, to output the value of your field. Same thing in different ways. Same thing because it's an HTML element, but how can you render an HTML element? In a lot of ways. It can be just a plain text or it can be a dynamic thing. There can be a bit of JavaScript somewhere, right? You still, it's the same thing showing a value, but the way you show it is different. Blocks is another example. I mean, Blocks are HTML blocks, right? To do anything, how many Blocks you have in Drupal? A lot of them, the complexity, the logic of printing a block in core is, this is my logic and then build the block. This is what a plugin block type is. It's just something and build the block. Migration source is a really good example to explain plugin. So how many, migration source is a plugin to, you know what migration is, is to migrate data, right? The source is from where and how you can get the data. A database, a file, a remote service, an image, whatever you can think about. So you can get the data from so many sources. It's like an infinite list that you can build, but it's the same thing, right? So it's a CSV, read the first line and then the other line and the other line is comma separated. It's a database, select this table and then the next row and the next row. So the output is the same. It's the same thing type. It's a list of data. The input for the source plugin, it can be anything, it can be anything. Destination is the same, just with destination. The destination can be, again, a database, a file, a CSV, an image and the plugin is just, the output is the same, but the input from where, sorry, the other one. The input is the same, it's coming a bit of data. The destination can be anything. So it's the same thing type in different ways. Let's start with the example of the demo today. A client comes and says, look, I had a brilliant idea. Can you make a website like TripAdvisor when it's just a simple form where they use to type the city and then we load all the information about this city? Yeah, yeah, it's cool, it's cool, this project. What's your budget? Well, it's 200 pounds. Yeah, I cannot build TripAdvisor with 200 pounds, but maybe if we work like in a couple of years in my spare time, no, no, actually, our deadline is yesterday. So this guy wants a website like TripAdvisor in a day. You would say, yeah, that's impossible. It's not, it's not. Plug-in API will help us, so this is our, is it there, it's not even taking the laser. So this is the output that the client wants, right? They say, why in one day? How can we do it? And then the client says, you know, I want these two items for now, a weathercast and forecast and restaurants, but we can add more, like kids, like my developers are really happy. You build the thing and then they can add something like pooling hotels or cool stuff to do in the city or the number of the habitants. You say, you have so many things. I say, yeah, but it's the same type, right? It's about outputting information from the city. You say, yeah, plug-in API, they can help me. So let's see how a plug-in is made. The first thing that you have to identify is the plug-in type. Let's call our plug-in type a city widget, right? So our website, our page, we made of city widgets or our project. A city widget is a plug-in. They need to receive a city name as argument and has to build the widget about the information about the city. So the plug-in, the same thing is the plug-in gets a city name and output some HTML code. The logic inside, it depends by the implementation that we want to make. A plug-in type, a plug-in itself is normally an object in object-oriented programming. So all the Drupal 8 code base is now finally object-oriented. So a plug-in type is an object. Normally a plug-in type is predefined by an interface. Everybody confident with the definition interface? So if someone is not confident with the definition interface, don't be shy. Cool, perfect. So an interface is quickly just a promise, a protocol, something that is the base of our plug-in. Our plug-in, they must have these as like manifest or the definition. Our interface say, look, your plug-in needs to build instead of this method, build widgets. The method argument is the city name and then the output is a renderable array, for example. So the output will be rendered as a HTML. The logic inside is up to you. So this we defined our plug-in type and our plug-in type is, sorry, I have just information, so you build a widget from the city. Our plug-in type is the base definition. We know what it is, it's a city widget. Now let's start all the process. To load plug-in, you need a plug-in manager. The plug-in manager is a service, Drupal 8 is full of services. It's a service which is responsible for defining how to find your plug-ins, how to find plug-ins on, this is the next one, find your plug-ins, instantiate your plug-ins, and you can manage anything about your plug-in type. So basically it's the manager that says, set the rules. You can get your plug-ins in this way, you can get this amount of plug-ins, you will get a load in this way, you will get instantiate in this way, you can do this, you can do that, so this will be like this guy, like the manager of your mini project about city widgets. So this is the plug-in manager. The plug-in manager has a few friends, which is Discovery and the factory. The Discovery bit is, again, this is all of these piece of code in your project. Plug-in manager is a service, it's an object-oriented piece of code that defines ways of loading and rules of using your plug-ins. The Discovery is something that is used by the plug-in manager, and it finds your city widget plug-ins in the code base where they are, if they are in the code base, and it finds the derivative, the specific icon set is in English, so sorry, the derivatives which are normally plug-ins are piece of code in your code base, so one object is one plug-in normally, but there are ways where you can load thousand of plug-ins dynamically on runtime on Drupal, we will see in a minute. And then there are ways to do the Discovery, the one that we are gonna use and the one most common using Drupal code is by annotation, which is a bit of code in the doc block of your plug-in class. There are other methods like YAML or the old one, which is now, it was used for legacy reason, now it will be removed, which is the hook. It can be Discovery plug-in by static way, so nobody can define plug-in, I just, those ones, or you can be your own. My plug-in, they are on AWS instance, so you have to discover them in a completely different way. This is a Discovery, and then we have the Factory, so when the plug-in is discovered, what Drupal knows is just its ID. So we have five city widgets plug-in, we have two city widgets plug-in, one is restaurant, one is forecast, just all the names. The Factory is the one that loads the class, does all the magic, and then the object is ready for Drupal to be used. It's not something new, it's the P3 Factory pattern. It's lazy loaded, so at the beginning we just know the ID, and then when we need a plug-in, we load the plug-in. This is to avoid memory consumption. Consumption is consumed, so it's loaded in memory only when it's needed. And there are different way of loading a plug-in through the Factory. The default Factory, the one that is most common is we are gonna use is the Container Factory, which is basically, it's a container-aware plug-in, so you can use the Create, if someone is confident with dependency injection, you can use the Create method, static method to construct your, to inject any dependency on your plug-in. A lot of information, a lot of information, and say, well, the guy is doing a basic knowledge session about plug-in, and I'm really confused. I have to be so many, so I have no idea what I'm gonna do. I'm gonna go home, I'm gonna swear against the guy. Drupal Call helps you, can you see it? Is it visible? So I'm using the Drupal console to help me to build my city-wanted project. First, I'm building a module, so your plug-ins are part of your module, so you normally have your module, and then inside your modules, you have the plug-in. I'm generating a module with the Drupal console for now. The module is called Drupal Camp. It lives on my custom folder, so it's nothing new. It's what you normally do every day. Just I'm using the Drupal console, helping me to generate the skeleton of my module. Module is done, the .module find, info.yaml. Now I need the plug-in type, and I say Drupal console, generate a plug-in template. It's a plug-in type that I want, and the type of discovery is a notation. This is Drupal console, it's nothing new. You go online and you check the documentation. Let's start asking, where do you want it? I just create the module in Drupal Camp module, please. What's the type of your plug-in? We said the plug-in type is city widget. I call it city widget. And then you say, what the machine name, this is to recognize like the service everywhere, Drupal, we know that my plug-in is called city widget, and everything is built for you. You have the, let me get to the next screen, which is easier. So we just use, can I go there? Yes, we just use this command. The first one is to generate a module. The one is to generate a plug-in type. And we have all these, I have the different module naming here just to relate to the project. Everything is done from Drupal console and by the Drupal console for us. We don't have to do anything. Everything is in there. We have the manager, we have the interface. We have a base class our plug-in should extend for facilitate our life. We have the annotation. We have even the interface, the set of the city widget plug-in. We have the services. So everything is ready. We don't have to do anything. We have just to, as a developer, build our plug-ins. For me as an example, we have two plug-ins, which is the weather forecast and the list of resonance. How do we do it at this point, right? So a client came and said, probably we can do it with plug-ins. We use the Drupal console to generate our first skeleton and then we start. The weather forecast is our plug-in. The plug-in is made of a bit of annotation, which define our plug-in in the lot in the list. Our plug-in is called the ID, which is really important, must be unique in your plug-in list, plug-ins list. It is weather forecast. It extends the city widget base plug-in and basically we use the interface method to build our output. What is saying this, if anyone is not familiar with that, is use this tweak, let's call it tweak file and pass this file, this forecast information and then we get the information for whatever our logic is. So this is our logic. It can be the logic inside our service. It can be the logic in here. What it's doing is basically connect to weather.com API and pull everything about the city that the user has passed through the phone. That's it. We don't have to do anything else. Then we made, you know, we can be a bit of complexity on the team, on the styling, but I mean, it's 200 budget so we can just output whatever is coming and a bit of sun and cloud and that's it. Oh, sorry, this is the file. So when we define what our plug-ins are, normally there is a folder structure that we have to respect. This one is gonna live inside plug-in city widgets. So if someone is gonna create another country module, I want to use your plug-ins, they must live in this folder and they must have these annotation definition and then there will be automatically discovered by Drupal. Restaurants, same thing basically. So again, our plug-in definition top, the ID is restaurants in this case. You can use another team because the output is different. We have maybe a service, maybe the logic in there to load the restaurants from the city. And then it's, the folder is the same. It's just, you know, it's inside plug-in city widget. Again, this one can hook Google API places, filtered by restaurant and then the city, it's not the difficult. So what I've done so far is there are a little bit of code. No, well, it's there, but it's two, four, six, 10, let's say 15 line of codes, not counting the template, and you have cheat but vice or done. And it's like, look, I've done it, I've done it in a day. You can do that day. Again, the template could be a bit tricky, but it's not a big budget, so you can rely on reusable CSS framework or whatever it is. The project is done. You finish in a day, thanks to plug-in API, and then the client said, look, I had a brilliant idea. I found a lot of links where basically you can just, you can just place the city at the end of the URL and they magically give us information. Can we use another widget on our website? You say, you are crazy. How can I implement all of them with 200 pounds budget? You say, look, I know, can we use iframe, right? So I want the, every time that I create like a node called URL, iframe, I just paste a label just to identify and I paste the URL and then you magically show on the list of the widget, you show iframes, where is my URL plus the city from the user. You say, it can be done, but how many plugins should I create? I mean, this is extendable. This is where, so iframes, this is where, I don't know, I don't know how to say links. This is where derivatives comes in help. So what it is, I won't say the name anymore, okay? So what that is, is you have a plugin, you still have a plugin, which is called the plugin, the base plugin, and it lives in its own thing, which is basically, it's a normal plugin. It's how you do the output of the plugin. In our case, the output of this iframe plugin is iframe where the source is the URL passed posted by the admin, the editor, and then the city coming from the user. So it's a simple iframe. And then the power of this is you can define the river. You see the definition of the plugin is different. Now there is a driver class. And the river class define the way we can create these dynamic new plugins, which is on the right side. This is the river. It lives in a different folder because this is something that also by Drupal is inside plugin derivative and iframes. So basically, what's happening is when the discovery search for plugins, when you get to this plugin, it's a look that is at the river. So probably there are more plugins that I can load dynamically. So it goes to the other class, and the other class more or less says where here your logic to load dynamic URLs lives. It's basically what we do is we create a node type called iframe with a title and a text field where the user can put the label and the text field the URL, right? So in here, the logic is load all the content types iframe gets the, do I get the name? Yeah, get the name, the title of the content type, and this will be the label of my plugin. Then get the URL, the text field, and this will be the base URL of my plugin. And so this will be a new definition of your plugin. It will be a new plugin available for you. So the more iframe content piece of nodes the admin creates, the more plugin you will have available. So at this point, the client can do whatever, what's there in there? Whatever he or she want, whatever they want, they can create as many as they want as long as you follow this rule, this URL in the city. And they have, it's a beautiful, well it's not very beautiful, it's cheap advice or website. So how do you use all this in block, right? So we have two widgets really styled in a nice way and then we have all this beautiful list of iframe. How do you use it? So this is a controller for the root city slash city. So the way we do is, is we build a form that basically send the user the action is, go in this URL, which is city slash the city that the user added to the form. And then this is the controller, what it does is we call our plugin manager and the plugin manager say, okay, call the, call the discovery and find all the plugins. Then call the factory and build all of them. And for all of them, for each of them, you pass the city, you give me the widget and then it will be the output on my page. That's it. So with a 20 line of code that we've done before and I'm not counting the first and the one and the three, with 23 lines of code, we have a website. We have a powerful website. That'd be shit, but we have a powerful website. Everybody's happy. Everybody's happy. Nearly there, okay, nearly there. As a, do you get me so far, right? So it's really difficult to explain plugin. If you go online and feel read for documentation, all of them are really good and really powerful, but you will find very weird examples. I'm not blaming anyone. I read all of them and I loved all of them and I shared all of them. But some of them are about ice creams. Some of them are about grocery shops. Some of them were about a zoo. Oh, can I explain to people with zoos? I mean, it's something about, because it's really difficult to, it really difficult to give an example of plugins. We know it's easy because it's the same model. We plugins can be, that's why it's the same thing. It can be everything. It's your thing, it's what you decide. Just to have to get, that is something that you decide, right? And then it can be implemented in a lot of ways, all the ways that you want, really. I will give you another example. This is a real example and this is how I go into plugins. And this is why and when I start loving plugins. Why? So there was a, oh, by the way, someone went to the session that I've done yesterday with Chatbot. It's the same slide. So feel excited anyway, okay? Don't say to the guys, I already saw this one, it's just shit. So there was our client, which had a Drupalite website. Very happy, a brilliant website. And they said, look, because it's an event base, we have a lot of events. It would be really useful if someone can connect the website through the Alexa Echo device. Can you, can you do it? Can you expose our content through Alexa? And we did it. We built a custom module with our code logic to connect to Alexa, right? And I said, yeah, and then when we were, this is true and we really like to finish and then Google did a huge, whatever it's called, event, event, of course. Google Home was out. And the guy said, oh, look, are you there? Yeah, can you do the same for Google Home? We did just do it for Alexa. It's a different device. But it's not different. It's the same thing, right? It's a conversational device. You say something in English and natural language and it replies with our website. Why is it different? It's the same thing. Yeah, it is, yeah. And then they say, oh, by the way, can you do the same for Facebook? Sure, okay, this is different, right? So this is conversational device with a microphone. Facebook, it's digital, it's online. And the client said, but it's the same, you know? It's, okay, the command is by voice, but it's the same sentence. What's happening tomorrow in Cundentown, right? So it's the same thing. You type it or you say it, it's the same thing. And yeah, by the way, even on our website, can you put a chart? We said, right, it's the same thing in different ways, but it's the same thing that they want. So in the chatbot conversation, this is called, so a command is called intent, right? So they usually want an intent and we have to build an output for this thing. So a response. The intent can come from different ways. It's like the migration source, plug-in type. The source can be different, but the output is the same. And that's why we built Chatbot API, which is basically, it has a lot of features inside, and we can discuss and talk after the session. But it's a lot of features, but the base is a plug-in manager. So to build this, there was a bit of knowledge and learning, but to build this, it took me one day to implement with all of them by doing a plug-in manager and a plug-in type called intent. And then I discovered that all of these platforms, they work in the same way and they can be implemented really easy. All of them, and many more, yes, they've done the session, and from the audience, I've been suggested of two more Chatbot sources, let's call it, way of using UVS conversational devices. And I had a look and it can be implemented with line of code. So, again, are you alive, okay? Again, so it's the same thing in different ways. Thank you. Any question? Any doubt? Any anything? Don't be shy. Yeah, yeah, sure, sure. Recently, they became very, very popular. What do you think, for example, and with Drupal, or is it something that there are a lot of people looking to play with this or is it something very specific to Drupal, big companies that they are interested in? So if I give you my opinion, it will be an opinionated answer, I will give you a small one and then I suggest to you, when the session that I've done yesterday is online, I suggest to you to have a look because it does answer your question in a way that you will never imagine. The answer that I can give you, it depends by your project. So don't think that it's something that you can add, like, okay, we have a website, now we need a Chatbot, it's not in this way, it's something that you have to plan. So it depends by the project and the way you implement and the source that you use, like Alexa or a chat on your website, it depends by your project. But the reason why you need it, again, that's the session that we had today, don't feel that because the market is doing it, you have to do it. You have to be smart, you have to find the way of connecting to your website, I don't want to spoil anything, what's the session? The way you connect to your website and why and how to launch it. So have a look, because yeah, it's interesting the way that I suggest in there. Jessica, do you want the question? The plugins. If you go, so all the plugins just for simplicity, they extend our class called plugin base. So if you see how many classes are extended plugin base, which will give you a good understanding of how many plugins we have just in core, you will be really surprised which is a really long list. Everything is a plugin. The example that I've done with entity and plugin, it looks like a big old, but I said the entity model with different data, right? Why? So it's like the butterfly origami made of different papers. And the plugin is all the origami animals. Entity types are plugin. So the example is fit, right? So if entity types are plugin and entity are the instances, let's say this plugin, not really, but let's say in this way. It's the same of the origami example. The plugin type is the origami animal and the entity that we create, the article that we create, the butterfly that we create with the red paper is the entity. So the plugin fit and entity types is a common one. It's a lot of them. These components, these components, the style component, the filters, the sort by the argument, the whatever you see on the view list, all of them are plugins. All of them are plugin types. And all the, when you click, I want to add a new filter into the long list of filters. All of them are plugin types. All of them are plugin types. Sorry, all of them are plugin instances of the same plugin type. One example which is difficult to get about the, I said, I never did say, the reverb tips. You know when you create a view and then you want the view as a block, right? Or the exposed view as a block, right? Blocks are plugins. But exposed filters of this view, they come from your configuration, your configuration website. So something you create on runtime. It doesn't exist in your file system, in your code base. This is a derivative. So what the plugin manager does when the block plugin manager does when it creates the list of block plugin definitions. It loads all the ones in the code base and then for example, ask a view of view. How many exposed filters, how many views with exposed filter do you have? And views say, I get five. Okay, this is my list of block plus fives because they are coming from views. Everything, I know everything's a plugin, but it's a massive list of plugins. And I didn't see any history with this. I think it's a group of thing, the plugin, but it's amazing what they do and what it does and the simplicity, the power, the simplicity for using them and the power that they give you. Does he answer your question? Wait, it doesn't, but yeah. Sorry, yeah, I get excited. I'll talk to you in a minute. Yes, so the service, it's a logic to do an action, right? So if I want to walk to there, right, my brain needs to action the service legs, right? To move in there and say, you call the service legs and say the service legs, do this action, move from here to there, right? So this is the service. The plugin is something different. The plugin is a component. And with this component, you do something. So the service, let's say, yeah, it's a good example. So the service makes use of the components to do something, right? Like the service, in this case, will be the brain calling the legs plugins and say, now you move, right? But the service then the brain can say to the arms plugins and now you wave, sorry, I can do this just because they want to look me silly. So say, the plugins is the component that actually does something, but the action triggering and doing all the logic is the service, right? You build the plugin manager, right? The plugin manager is the manager. So it's the one doing action, the manager is the one that manage something. There is a service. The plugin by itself is a piece of code doing something, whatever it is. Anything else? Well, I thought there was a lot of announcement, yes. Thinking one point. If you use these as example, then yes. That's why it's very difficult to understand plugins. Because, no, no, no, yeah, because in your intention, which is helping on building something, then it's a plugin. But it doesn't mean, the plugin does have to output HTML or build something. It can do everything else. For example, the immigration source, it does output data, which is, this is an array. The ID is five. The name is, it's a record. So it's an helper if you need a helper, like outputting data in different ways, right? So in this way, it's a helper. It's something that helps you, that you can have different instances. So the same thing in your case will be a helper processing something, and then different ways is whatever you wanna put it. So if you use an example, yes. Giving out a right definition of plugins, plugin API or plugins, I think it's impossible. One that fits everything, you say, wow, I got it just with one sentence. It's impossible. By example, it's probably the best way. Yes. Yeah, because, so, because it does something, it's a helper, right? If you give the helper example, it does something, but because it's the same thing, they always, they all have to follow a rule, right? All, your plugin is an object, and all the plugins, they have to follow a rule. The only, the only way, I would say the only reliable way in PHP and object-oriented programming to define rule for classes is using an interface. Your interface should be the definition of your plugin. Then the plugin can implement whatever you want as long as the interface is respected. For example, the example that I gave with the city widget, the only requirement was, I must have a build widget method and a pass a city. That's it. And then this is the interface, and then you can apply whatever you want in your logic as long as this is respected. Does it answer your question? Yes. If they extend it, if they just create a plugin, they have to follow your way. You are not forced to create an interface, but the right way of doing it is, is defining an interface. And then of course, not all the developers, they can follow the rule. They can not just implement the interface, but they should because it's there. So yeah, it's a way to make sure that you don't make mistakes basically. And in the future, it's a way to, for example, when you add a new functionality, you face out to the interface. So all the other plugins, they will fail because of them respect the new rule. While if you don't implement an interface, everybody can do the fact they won't. Any more, any more questions? Did you like it? Yeah, yeah, it was cool. Yeah, it was really good. Okay, so thank you. Yeah, yeah, it was cool.