 I did add the slides online because we had a couple extra minutes. There are a couple of code examples for the most part. We're going to be talking conceptually about things that are happening here. So this session, in case you're in the wrong room, is about plugins, composer, and PHP 7, which you can probably tell from the title slide. I am Chris Vanderwater. So I have been doing Drupal for about 12 years now. In that time, I've helped maintain C-tools, contributed heavily to Drupal 8, really focused my time and my effort into doing a lot of page layout work. But for the content of Hock, and it's one of the plugin subsystem co-authors, and so I influenced it very heavily. Also, if it's not obvious, I worked for Acquia, and they helped me be here today. So in order to have a proper discussion about the plugin system, we should first understand what plugins are. And I've had a long time to try to come up with an analogy for what plugins are. So in case this is new to you, or in case it has never just made sense, we're going to try out a new analogy today. Now, I have sometimes been standing in front of my projection screen, so just imagine that that lightbulbs over my head. But it's relevant because lightbulbs are the analogy. There are lots of lightbulbs in the world. There are LEDs, there are fluorescence, there are incandescents, and there are all sorts of different sizes. But you can plug lots of different sizes into, say, a fixture in your house. So keeping with the analogy, if we have a house, maybe say a Drupal house, then fixtures within your house would be anywhere that there's a plugin system. So going to raw Drupal for a second blocks as an ideology or a fixture within Drupal, and conditions are a fixture within Drupal, and input filters are a fixture within Drupal, and they all have different kinds of bulbs or plugins that could just be screwed into them and swapped and used. This is the very idea of an interface. Screw it in because it fits. It only fits that. It wouldn't fit something of a different size. So hopefully this seems sensible, but it's worth noting for purposes of this talk that there are a lot of other houses out there. Ours is not the only one on the block. I want to call this out up front because I think it's really important to the conversation as a whole and to us as a community. So I've got a big question mark up here, I guess mostly because of the history lessons that I'm about to give. When we started writing plugins, we did so because we couldn't find anything else like it anywhere in the PHP world. And so we set out to build something that seemed kind of new in a lot of ways, which is sort of strange to say out loud, like everybody's been programming everything for a very long time, it's strange to find things that don't already exist. But at least for purposes of what we needed, we couldn't find anything like this. And so the question was like, why hasn't anybody done this yet? Now it's worth noting, let's see, when we wrote the plugin system since we hadn't found it anywhere, we really wanted to share it with other people. And so because of that, the plugin system in Drupal 8 was actually the first component. If you're familiar with Drupal 8's actual code base, there's a Drupal component library that has code that ostensibly should be reusable to people not Drupal. Plugins was the first thing to land in there. We were the first ones to really say, this is something we want to see done. And so we went and did it. Unfortunately, attempts to make plugins exposed to the rest of the world have largely stalled. And this isn't like due to any one factor, it's just we've written a lot of code, Drupal as a whole. We have a lot of code to maintain and getting our components out there where other people could make use of them just has not been that big of a priority compared to killing critical bugs, right? And this is understandable. It's unfortunate, but it's understandable. And yeah, I've got the IDs for a couple things up there. So if you wanted to go look at this, it's like a five-year-old issue, I think. So it's worth looking at and reading through and seeing where we're at. It's actually a pretty short issue. Truthfully, I believe that we will eventually get there. I've even had talks this week about what it would take to do it and I think it's something worth doing. But it has not been done yet. So to that end, I want to point out a couple of things. Plugins has been around for a while. This is the issue where plugins was originally committed to core. You didn't work with anything in Drupal 6 that long if you've worked with Drupal 6. And most of the modules that you've worked with, they iterate more quickly than once every five years on the code that you're using in there. So it's worth noting that when this went in, it became the foundation of all of our info hooks, not all of them, but the vast majority of the things that were info hooks in Drupal 7 converted to this. We've had a really, really long time with plugins because it went in early in Drupal 8's life. It was, at this point, one of the first things to really land. And since it's been around for five years and we have done so many implementations of it, there have been a number of things that have been kind of tacked on over that time that I at least took great issue with. So some of those things would be like how we chose to do dependency injection from our container and my own experience with object orientation when we wrote it to begin with. So I think my point here is really just that the plugin system is kind of ancient technology in a lot of ways. I know it's new to a lot of people, maybe even in the room if you've only been working with Drupal 8 since its release. But even at that we just did 8.3, which is the fourth release of Drupal in once every six months. Okay, it's been out for a couple of years. So let's see. Just to belabor the point a little bit, when we built the plugin system, anybody want to guess what version of PHP we were running against? 5.3. Yeah, we wrote it against PHP 5.3. Now a lot has changed since then, a lot of language features and things like that have come along. Things that we didn't and couldn't make use of at the time. So kind of between a half decade of working with the system and a half decade of PHP running ahead of us and continuing to get better and better and better, I personally felt like it was really time to revisit the plugin system and just rewrite it from scratch on all the same basic concepts. So to understand some of the changes that I've made here and what they entail, it's important to understand the things that really irritated me about the final product in D8. And so in no particular order, these are static factory methods. Let me just see. Who in here has actively worked with Drupal 8's plugin system? Okay. So just so I know who I'm addressing are a lot of people in here mostly because this is like the PHP track and you want to see what Drupal's hopefully sending back to PHP. I'm getting some head nods. Okay. Well, you're in the right room. Cool. Well, then I will fly through this a little bit and we'll kind of talk about it as we go. But for those of you not familiar with the plugin system, it has a static factory implementation on it, which would make sense in a lot of other places but it doesn't make sense for reasons that I'll go into here momentarily for the plugin system. Also, constructors, as I mentioned, when we wrote the plugin system initially, it was not my first foray into object orientation, but it was very early into it. And so expectations around what sort of parameters had to be passed to a plugin were kind of explicitly defined as part of what we built. And that turned out to be really problematic throughout the entire Drupal 8 lifecycle. In addition to this, we use arrays for almost all of our definitions of things when objects would have sufficed. And again, I try to be very clear about whose fault this is. It is mine. Because I couldn't even conceive of dealing with them as objects at the time I was so new to OO. Additionally, we have a couple of instances where we don't necessarily always want all of our plugins, and so an idea of plugin filtering really needed to be brought up high-level in the system. And finally, something I refer to as plugin mutating, which is the notion that... All right, actually, I'll explain this since a lot of people in the room don't have experience with it. In fact, I'll explain the whole point of it. In Drupal 7 and earlier, we used big arrays for everything all the time. So if we had a whole bunch of things that you could use with some sort of metadata attached to it, like, say, a human readable label and some description of something, there was a key with those data elements attached to it. And so when you have a big PHP array, it can be quite tempting sometimes to have a table somewhere that you want to address and then just build a for-each loop in the middle of that array and add stuff to it. You can't stick a for-each loop on a class annotation. You can't stick a for-each loop inside of a YAML document. Like, these are not things that you can really easily do, but we needed the capability to allow a single definition, a single class, to have multiple instantiation mechanisms with different sets of config basically passed to it. And so we came up with this idea of derivatives, which actively changes what plugins are available by expanding the library based upon some other class's knowledge. So when we talk about derivatives, just think it's a for-each loop to make one thing act like many things. That's all it is. Luckily, I've had five years to come up with that definition. Hopefully it was okay. The other thing we do in Drupal all the time on this is Drupal's really famous for alter hooks. We have hooks and we have alter hooks, and alters are like, hey, let's just pass crap around and let anybody change it however the heck they want. And that's really useful and also very dangerous. So we have to have kind of an approach to doing that that is sensible within the plugin system. So with that being said, I wanted to rewrite it on PHP 7. Truthfully, I found more of the features of 5.6 to be what I actually needed on a day-to-day basis. So bare minimum, I had to have 5.6, but I went full bore all the way to 7 as I was rewriting it and used a number of features of it which we'll talk about. So let's just kind of go through my list of crap that I hated and what we did to change it and then where we've landed. So the first is this notion of the static factory. For those of you who maybe don't have experience with static factories, I came up with this as my graphic for what it is. So if you consider the beige here, all-to-be classes, in fact, they're all essentially the same class. They have all the same code except for one method. One static method that knows how to instantiate itself. And Drupal uses this all over the place. We use it for route controllers. We use it for a number of different things where rather than, say, document something directly into our dependency injection container, we let the class document it itself and then just pass the container to it. Well, the plug-in system went in so early, there wasn't even a dependency injection container in core yet. So of course, we made no allotments for it. Or they happened close to the same time, something like that. It was very early days. So when we started running into plug-ins that really needed services from the container, this was introduced pretty early on as how we would do it. I took great exception to it, though, because it means that in order to get another plug-in with different dependencies, I have to subclass the original class every time. And that means that I probably need to stick a new annotation on this class, and even though everything's the same except for the dependencies, I have to do an awful lot of work to get there. And moreover, it tightly coupled dependencies with the class, which a lot of people have grown to accept and I still have never really accepted it. I dislike it. So the new plug-in system works a little differently. We just have a single class definition, and we go ahead and we document factories that can be used for them. Now, saying that out loud, I guess I want to be really clear. Most of the plug-in system operates through an annotation on the class. So this is still tightly coupled. I said this factory class is what you'll use to instantiate yourself, right? So initially, this seems hypocritical. All I did was kind of rearrange the chairs. But if we go back to this notion of altars in Drupal, if you want to think about it like event dispatching or something, if I were to hand all the definitions around, someone could actually subscribe to it, say, I want this definition and let's copy it, change its ID, change its factory. Everything runs through the same class. They just have different factories on there, and I get totally different plug-ins out of it, which means that the behaviors, of course, all the same, because it's all running through the same class, but I can pass a different constructor argument to it if I want. Hopefully, let me check my notes and make sure I didn't totally go off rails. Yeah, no, that's basically it. I'll have a time for questions here after this. But if I'm explaining something and it's like, no, raise your hand and we'll address things as we go. So with that, I'm going to move to the topic of the constructor. Now, this was actually one of my favorite things about the rewrite because we got to leverage some of 5.6's language-level features in order to solve some of this. But in order to understand it, I want to give kind of a clear picture of how Drupal 8 worked for this. So Drupal 8 plug-ins classically have to know three things. First, they have to know what their configuration is. And this is actually almost optional in a lot of instances within Core, and you'll see why in a minute. But they absolutely had to know what their plug-in ID was. And a plug-in ID is just a machine-readable string that identifies the class. It's like rather than needing to know the class's full name in order to instantiate it, if you know that it's called foo, you can just tell the plug-in manager to instantiate plug-in foo, and you get a class back. It also needed to know its plug-in definition, which the system could look up from its ID, but your class, your plug-in, was given all of this information all of the time. So if you found yourself in a situation where you needed more information than this, you probably ended up using config as a dumping ground for all the things, which to be perfectly honest is why I put it there. It was suboptimal, but it was what we had, and again, the degree to which I understood PHP and OO at the time really limited what we could do, because I was one of the driving factors early on here. I just want to acknowledge that doing this kind of sucks, like a lot. The component, by contrast, actually has no prescribed constructors or parameters of any sort on it. We make no assumptions that you're going to pass certain things through the constructor. We didn't even write one into the base class. That, of course, means you need to write your own constructor. And subsequently, it also means you're going to need to write your own factories, which is part and parcel to why the code base, if you go and look at it, is actually quite simple. So I mentioned 5.6 and language-level features that made doing some of this easier. And so first on this is variatics. Who in the room has used variatics? Two people? Okay. So who in the room has used funk-get-args? Ah, okay. That seems right. Did you like funk-get-args? Always seems like a hack. Okay. Well, variatics are in many, many cases essentially a replacement for funk-get-args and a really cool language-level one. They are way better. You can even do things like type-hints, the type-hint, these sort of parameters that are going to be passed into a method with variatics. I'll show some code here in a second that I blew up really big, so I hope everyone can see it. But I want to talk about the opposite of it. So if variatics is making it possible for you to pass in number of things to a method, then, or have in number of things passed to a method, then argument unpacking is the opposite. It passes in number of things to a method. Who in here has used call-user-funk-array? If you have done any work in Drupal, Drupal basically only exists because call-user-funk-array exists. We could not do what we do without it. So as I said, it's essentially the opposite of variatics. It's kind of like exploding an array into top-level parameters of a method, okay? And I already mentioned call-user-funk-array. So is that code awful? Can people even begin to see that? Yeah? Okay. Can you see the dot, dot, dot in front of dollar constructors? That means I can pass as many things to this method as I want. I have to pass a definition, and then I can pass as many other things as I want. And all of them will get dropped into dollar constructors. It's actually really nice. You can even do things like type-int it. So in this case, I'm saying all the things passed to this method, however many of them there are, they must all implement foo interface. So rather than iterating over an array of junk that you got out of funk get-args and making sure that they all implement the interface you care about, language-level type-int, done, done, done, right? This is super, super useful stuff. And this is sprinkled throughout the plugin system. I'm going to make the point that what you're seeing here, the top method, is a truncated version of what we actually use to instantiate a plugin. We pass the definition to it, however many constructors were passed to us. We also pass to it. And of course you can rewrite all of this, but this is what we're doing by default. And it really means that if you have a given class that needs like five or six things passed to it, you can absolutely get away with it even though all the other classes only take two things or whatever it might be. Who in here is actively using PHP 7? Of those of you actively using PHP 7, who's using typed returns? Okay, trying to. All right, typed returns are awesome. In Drupal, we document the code as heavily as we possibly can. And so a lot of this ends up being that, you look at your doc block and it says, at return and has some interface or something like that. Hopefully it says something like that. In PHP 7, you don't have to do that. You can actually go ahead and just tell the method itself what kind of thing it has to return. That can be scalar, it could be a string, it could be an int, it could be an array, it could be an interface of some sort, which is really great because it blows up if it doesn't return that. And of course if it didn't, something else that was depending upon its return value would blow up when it tried to call a non-existent method. So this is really nice. Invariably, I have to love on PHPStorm a little bit because if you write this out this way and then go add your doc block, it'll auto-add return statements that are right to your doc block for you, which is pretty great. So worth noting, typed returns are a thing. They're awesome. Of course you need to use them in the right circumstances. They could be used wrong, but take a look at them, learn them, love them, they're great. Let me check my notes here. Yeah. All right, plug-in definitions. For those of you who haven't used the plug-in system, I keep talking about this annotation. That is what we mean when we say a definition. It is literally like metadata about the class. It resides with the class, and we can go and find this stuff. So in Drupal 8, I've already mentioned a couple of times that my inexperience was very much showing when we wrote the definitions portion of it, especially because it all ended up being arrays. Objects are technically supported within the system, so we have the new layout plug-in in 8.3. Layout Discovery has a layout plug-in that comes with it, and all of that stuff is actually doing object-based definitions, and it's great. If you ever deal with entity-type definitions, they're also all objects, which is great. They're the only two plug-ins, plug-in types out of like 40-some odd plug-in types in core that use objects. The rest are all arrays, which is really sad to me. We have Tim Plunkett to thank for the fact that this is even doable because he spent the time to get it working, so it wouldn't even be possible without him, but it was kind of a bolt-on feature that was added after we wrote the plug-in system. And this is super frustrating since you have to actually write an annotation class and you get arrays. Like, you wrote the class, you went to all the effort, and then we threw it away and handed you arrays. So this is really kind of irritating. Has anybody in here worked with doctrine's annotations at all? Oh, that's more than I expected. Okay, so we're dependent on that system. We're using it, for those of you familiar with it at all, you know, it does the same sort of thing. Unfortunately, Drupal 8 ejects the object and just stores basically the key-value pairs. So this was the kind of problem that we really needed to just solve by writing it appropriately in the system to begin with. There weren't any if, ands, or buts about it. We just had to sit down and write it properly. So we do objects by default because this is probably the 99% use case. Most people don't need an array as their definition when dealing with metadata. Having an object with actual methods on it that you know how to deal with is kind of nice. And PHP supports dealing with objects as though they're arrays, so I can have my cake and I can eat it too if you really wanted to deal with it as though it were an array. You just implement the appropriate PHP interfaces and move on with life. I don't think I have to say that objects are nicer to deal with than arrays. It's probably something we can generally agree on in most circumstances. I said that already. Okay, so we're kind of into the guts of what's new in this as compared to Drupal 8. So I'm going to continue with the Drupal 8 analogies for those of you who have that background, and I'll try to keep it lively for those of you who don't. So in Drupal 8, we have a need to filter our plugins. So we have some big set of plugins, and we need some smaller subset of it under certain circumstances. A great canonical example of this is the context system. So for those of you not familiar, Drupal 8 has this idea of plugins that require context to operate. They say I can only operate in the presence of a data object of this type. So in Drupal terms, that's like a node or a user, something like that. So if I wanted to display the field value of a node, well, I can't very well display the field value of a node if I don't have a node. So we can actually filter what plugins are available based upon what contexts are available. And we can say, like, oh, if you don't require a context, then you're in. And if you do require a context of this type, then you're in. Otherwise, get out. Unfortunately, only Core could have done this because we hard-coded it as its own thing into Core. So anybody else who needs similar but different functionality is going to have a really, really hard time implementing it. In fact, so much so that even Core has this problem in other, like, edge cases. We have this notion of custom blocks, which are their own kind of entity. And every time you create one of those in Drupal, it creates a new plugin definition for it so that you can reuse that block, which at first glance sounds great. But when you realize that when you hand Drupal to a customer, and they go to a page and they just want to, like, add an image to that page, they use this system to do so, that image is never meant to be used anywhere else ever again in the customer's mind. But now it's in their list of plugins that they might want to place on the page, a list of blocks. And so if they do this, like, a thousand times across 100 pages and have, you know, 10 custom blocks on every page, they have a thousand new plugins polluting their user interface. I think that that's bad. And so I maintain a lot of the modules that touch on this topic tangentially, and we've worked really hard to begin fixing it and are close to a fix. But had we had the ability to just filter things in some meaningful way, we might not have had to go to all of the effort to do that. So as part of the rewrite, I included filters. So filters inside the PHP component are just a custom class. They're a class that knows how to filter things. There's actually some talk of just making them callables and running them through array filter, so that you just have a group of callables you can pass. We can do multiple filter passes on this stuff. So to go back to the example that I've used, that'd be like asking for all of the blocks in the relevant context that are considered reusable, right? Those are two filters that operate on completely different axes of information, but they filter the list of plugins appropriately. And so I also want to point out for you PHP heads in the room that Drupal exposes an awful lot through the UI, and plugins is intended to help expose those things through the user interface. So if you want to begin building user interfaces for your non-Drupal PHP components, this is a really great place to start with that sort of stuff, rather than just having some config file where you hardcode what you want to be available, which is what things like symphony might do with bundles and that sort of information, right? And we can filter it on demand, too. So what that means is that every time I want to get a list of filtered plugins, I can pass it a different group of filters. We're going to see another couple of examples here, using variatics. So if that didn't make sense earlier, you'll see it here. But you can see, like, I have a filters array. Can everybody read this okay? Okay, I have a filters array here where I'm instantiating filter one, two, and three. And then I pass this off to the discovery component of the plugin system and say, hey, get me a filtered list of plugins, given these filters. And that dot, dot, dot annotation on top of, in front of dollar filters there, that's your argument on packing. It is functionally identical to this code, okay? In which I made a filter one, filter two, filter three variable, and just passed them as commas to the method. So if you haven't used variatics or argument on packing yet, I'd really, really encourage you to go and play with this. Questions before I move on? Or is that all, like, kind of, yeah? Um, you could just call that method with two different filters once each time, and then do, like, your own array intersects or things like that. Is that, okay, cool. So plugin mutators. I've spent a little bit of time talking about plugin mutators already in terms of derivers and alters, these kind of crazy things we do in Drupal. So derivers said that, alters said that. So when we did this in Drupal 8, we attempted to implement it via decorator pattern, which seemed really, really cool to all of us OO newbies. Didn't work out so well. So we ended up rewriting it with just, like, hard-coded expectations of what should always happen, and then people could opt into those things that we, as Drupal, thought they should be able to opt into. These aren't the sort of things you can do when you're writing a PHP component necessarily, though, because you want people to have control over what it is that they're doing. Ultimately, it's worth noting that this problem was an order of operations problem, and any developer who came behind us, if they didn't get the order of operations exactly right every time, would have gotten really weird results. So in the component, I rewrote this all from scratch and just said, like, derivers are gonna be part of what we know about at the base level, and on top of that, we're gonna take the system that uses that and open it up to everybody so that you can define your own mutators as part of your dictionary, right? When you're saying, I have this group of plugins that I care about and I want, these are the types of mutations that are going to be able to occur on them, and so you can kind of opt into that. Let's see. Yeah, I said that. Oh, so, no, I didn't actually. So a mutator actually operates on the whole set of definitions simultaneously. So we just hand the whole thing to you, you mutate it, pass it to the next mutator. It gets all of the new ones, mutates it further, hands it to the next one, and so on and so on and so on. So it can be like a really powerful way, again, the drivers are like the for each loop sort of thing. Alters are essentially, imagine taking all of your definitions, dropping them into an event and dispatching that event to anyone who wanted to make a change to the list of plugins, and this is the list that'll be cached, right? This is the list that everybody during runtime operation is going to see from that point forward, and so it can be a really powerful way to let people do things like change what sort of strings appear in the UI, swap out classes that they actually want to be executed in their case. So you might have provided a plugin that does most of what they want. They subclassed it, added some extra functionality, and then overrode what class was to be instantiated when you asked for that plugin, right? This is a really powerful paradigm because in Drupal terminology, it means that if you already have a plugin active, you can swap what class is running for that plugin with a simple cache clear, and now it's running through your specific code base. Example of this being like blocks. If you had the user login block on the page and you wanted to make a better user login block, you could extend the existing user login block, make any changes you wanted, and use an alter hook to put your own class in as the class that gets executed. Super, super powerful stuff, and with one cache clear, simultaneously anywhere that the user block, the user login block had been used. Derivatives are implemented by default. I don't expect anybody to probably be able to read this. No, or do I really care that you do read it right now. My point for putting it here is if you're looking at the slides later and you want to actually see how this is done, this is an example of the one mutator we ship with, the derivatives mutator. I mean, it's not that many lines of code, it's actually pretty small and straightforward, and so this makes dealing with all of your plugins simultaneously actually pretty easy. Terminology, this is really only for those of you who have used the plugins system in D8, so I will fly through it, literally. There are like five new terms to really know, and some of this you have to kind of know the old terms. We used to call things managers. There's not really a pattern in any programming anything that I know of that's called a manager except for plugins, and so it's difficult if you don't know what we're doing to look at it and go, oh, that's a manager, I know what that is. No, you don't. It's not a thing, right? So I changed some of the terminology. I used the word dictionary because I spent five years looking around and that seems to be what it is. It's a dictionary with an attached factory. Okay, that's plugins in a nutshell. So, or a library, however you want to think about that. In Drupal 7 and Drupal 6 we had this notion of plugin type which is really just like how we addressed it. It was a string so I keep talking about blocks. It'd be nice to be able to ask your plugin dictionary what type of information do you hold and it could say, oh, it's block information. So we added that. It's a nice to have. But then we have Sets which are the set of definitions, right? We have filters which we've already talked about and mutators which we've already talked about and so just kind of having the basic knowledge of what these are is good going into it. So, let's see. So, why did I propose this talk? Some of you are probably asking yourself that question at this point. I did this for two reasons. My first reason is that I feel like the component is actually reaching a level of maturity that is worth at least beginning to compare it to what Drupal 8 does. Begin talking about Drupal 9 or Drupal 10 and hopefully begin maybe reeling some other people into it who want to use it outside of Drupal completely. And I'm going to actually give a few examples of that here in a minute. The second reason I'm doing this talk is because I feel like there's a really significant opportunity for the Drupal community right here that we have not yet taken advantage of and not in the plugin system itself but the plugin system is kind of representative of the opportunity to a certain degree. And that opportunity is around decentralizing our code base and sharing it with the rest of the PHP world. Does anybody know how much of the scripted web runs on PHP off the top of your head? Yeah, 82 is the number I traditionally hear. What's the number that Drupal is? About one to two is what we debate over. If if we were to take APIs that we knew and understood and make them publicly available to the rest of the PHP world we could do Drupal outside of Drupal when we're not Drupaling and we could get a much bigger part of that other 80 odd percent we are not currently a part of today. Right? You become an expert in one of these APIs and it's like having a whole different career all of a sudden. There's a zero and some involved. Right? I'll get back to that. Component maturity. Kind of like as a supporting point to my first point here I've done three completely different implementations of the plugin system. And I wanted to have some videos ready for this just to kind of talk over while they were playing in the background. But I was running at breakneck speed to get here for this after finishing my slides. So if anybody wants to see those things you should feel free to come up and talk to me afterwards or online. I will make sure that you get a demo of the things. But the first is a little project called Hedron. And Hedron is a tool of my own making because I'm kind of irritated with all of my local development options right now. So I started writing which is a PHP and Docker-based utility for spinning up completely new Docker instances with whatever sort of code base you want on them. For those of you who've maybe used something like PlatformSH or something where you're largely dealing with like a composer.json file and you can just kind of push it and it builds your system it's sort of like that except it has your entire Docker stack with it. So you have to fork or branch the system and change your Docker stack and when you push it push to get it recognizes that you have changed these things and spends up an entirely new environment installs your code base on it gets it up and running and now you have two completely different Docker groups running like Docker environments running and it goes what commands to fire in order to bring it up and it's still very early in its stages but it does things like support project types so you can do something like say I just want to manage this purely and get I'm going to give you exactly the files I want and you just host it properly and it sets it up with like InginX or Apache or whatever it is that you want it to be doing from your Docker config and just builds the thing out for you and you just have a really minimal composer file that says oh this version of Drupal 8 and these modules and then it stands up all of that for you inside of your Docker environment. So Hedron is kind of a pet project that is nowhere close to ready for prime time but is out there where people can play with it it's hedron.sh if you want to look over my shoulder and see how badly I'm screwing up go for it. But yeah it uses the plugin system to define different project types so like Git, Magento, Drupal, raw composer you could do all of these sorts of things and then it uses plugins in a separate subsystem within it to define what the workflows of each of those projects are going to be and what the individual operations you might want to do at any given step of say building up a Drupal site or a Magento site or something like that becomes a really powerful way to define your own workflows for building projects. Second is a little did I miss an M? I might have missed an M Second is a project called Communicata that my cousin and I have been working on and so my cousin sat down to write a Discord bot one day and he hasn't been working with OO to the same degree I have so I came alongside him like a month or two later and said like oh this is cool can I rewrite it in plugins and he's like yeah sure so I did and now we have a Discord bot that you can add functionality to just by writing different composurable libraries and saying like oh I want the bot and that library and that library and that library and now you have a custom bot that only responds in the ways that you composed components in because for each individual composurable component you can define what plugins are available in there and the plugins all, I mean they're just using regular expressions to figure out what people are saying and whether it's something they should respond to or not and then have basically a method for building up their response whatever that might be but it's kind of a simple and elegant solution to building a bot that you can compile however you want you can compile what sort of reactions that bot is going to have again very new only wrote it in the last like month or two just happened some fun just showing that different things are possible my last example here is actually something that we're using at Acquia and we haven't open sourced it yet my boss and I are both going through the effort of trying to make that happen right now but my boss is Cash Williams some of you may know him he's been in the Drupal community for a long time awesome guy he does a lot of performance testing for Acquia and a lot of that ends up going through Jmeter now I won't say what Cash says about Jmeter because it's not fit to be rebroadcast but the point is he likes it and and it kind of sucks so if you've ever used Jmeter it has a user interface that has a tendency to crash I get some chuckles some people have used it okay so he came to me and said hey I want to stop using the user interface I said okay and then I built the plugin system and I went back to him and I said hey do you want to actually do that and so we started spending some time doing it and now we have a system that implements maybe 20% ish of what is available to Jmeter but it's like the 20% he needs to do his job and it's very clear how we did it so adding new things to it should be relatively straightforward all plugin based and it's basically just this large stack of plugins that generate an XML tree but they have a whole configurability notion built into them so that he can configure exactly how Jmeter is going to react to any one of those components and it knows what the XML output is going to be for that stuff so this gives him the opportunity to have PHP code that does 90% of what he needs from one test to the next and he can just change out a couple strings hit the button new XML file yay he doesn't have to import an XML file into Jmeter risk it blowing up on him while he's editing those handful of strings and hit save and hope that everything went okay so the next thing is about a whole new other set of possibilities which are that you could begin to build Drupal, Magento, WordPress whatever extensions on top of this that already script together your notion of things that need to be done in order to say do a Drupal login or do a Magento checkout or something like that like you could have individual commands that you build that are just a group of commands inside of them and you perform that operation and so it opens up the opportunity to build libraries on top of Jmeter and PHP where one or two commands could have taken hours under normal circumstances to get them set up the right way it's really cool, really like kind of interesting opportunity that we've not begun to explore because we're only like 20% in but it's there yeah I guess all of that to say I'm using it in production in a couple of places you know, for some value of production it works I have a lot of test coverage I screwed up my code climate integration so it says I have less test coverage than I do and we haven't figured out how to solve that particular problem yet but even at that it says I have like 75% code coverage on the plugins part and 100% code coverage on the annotations part and it's a lot higher than 75 I have some really good test coverage for this I have a lot of tests written the code is fairly well trodden at this point if you're interested in trying it out I have a bit of documentation on the plugins system and I'm still lacking docs on the annotation system I will attempt to fix that tonight it's usable it's kind of like Drupal outside of Drupal if you've been writing plugins within Drupal these plugins look like Drupal plugins very little difference so this is going to bring me back to my earlier point about let's see I got a few more minutes this brings me back to my early point about decentralizing and sharing our components and what that actually means I said some of this already but I got up on stage let's see two and a half years ago at Drupal Amsterdam and gave a very similar talk I didn't have the plugin system yet I was thinking about doing it but we were really just releasing Drupal in some ways we were right on the precipice of releasing Drupal 8 so I didn't want to go debase what we had already just done with some new system that was new and better and PHP 7 wasn't to a state that I was going to go and just use it yet but I stood up on stage there and gave this notion and so I'm going to actually read direct from my notes because I want to say something very specific here and it's about how Drupal is an open source project doing what I'm doing here it really draws a few things into question and so I want to try to answer what one of those questions is and I think it's that so many people think of Drupal as like a FOS project or they think of it as a product that does something that they need or it's a PHP framework right we've argued about this for at least the last 10 years or so definitely since Drupalcon DC and there was some before that this has been an issue that people have talked about small core people have talked about large core we seem to be going to large core route these days and so I just want to point out that we do this because Drupal it's so many things to so many different people we all use it really differently I know I certainly do when I have conversations with somebody about something I think Drupal should do most people scratch their head and look at me like I'm crazy and I might be but that's a different point but we talk about Drupal a lot and something I think we often miss is that the most important aspect of how we speak about Drupal is the thing that it has in common we keep using the word we because the code is not Drupal we're Drupal okay if we take some component of Drupal and pull it out and make it available to the PHP world we didn't lose anything we gained a lot of things in fact and one of the things we could genuinely gain from that is more community because discrete usable parts of code have a tendency to bring in more developers who might not have looked at something that's like a stack of code this high right if I hand you 40k and you look at that if I hand you 21 meg no one looks at that okay so Drupal is a community not a code base we already maintain hundreds of different code bases not one because we maintain everything that's on Drupal.org all the projects and there are a lot of them so I think my conclusion to this is that Drupal is awesome PHP 7 is also awesome I can say from personal experience that using plugins outside of Drupal is also awesome and I think that if we were to do this to many other Drupal APIs that too would be awesome so I'm wondering whether or not there's any blockers to making this happen because I think this is very important and we should very much consider doing it. I'm going to open the floor for questions at this point I know I've thrown a ton of stuff out there and I took a really hard right turn in like the last five minutes so questions, comments, concerns floors open no as I said I will do my best to provide demos on demand although we are on a limited internet connection right now so if anybody would like to talk to me afterwards you're free to do so please keep in mind that we do have contribution sprints on Friday and that's for most of the day nine until six with a mentored core sprint in the morning and also a first timers sprint in the morning and also the feedback that you give on people's presentations is used to help figure out what we're doing at the next Drupal Con so if you liked me please say so, if you didn't I love you anyway thanks everybody if we already do oh I thank you Cash Williams for showing up thank you