 So we've got a number of people still streaming in here and I'm just gonna let the last few kind of stream in and then We'll start here in about two minutes There's some spots up here in the front like front mid So great. We got a few still trickling in but I'm gonna go ahead and get started here I've got quite a few slides to hit Just gonna start by Pointing out a couple things our topic is Drupal 8 plugins. Hopefully that's what we're all here for if not, please stay If you would like to tweet anything about it, I do always kind of have a session tag for this If not, that's okay, too. If you're just so engaged that you can't type on your phone I will not be offended in the slightest A little bit about me. I am Chris Vanderwater. I'm Eclipse GC on Drupal Actually used to be developer evangelist at Acquia. That is not my title there anymore I should have updated this slide my apologies. I am a technical specialist at Acquia specializing mostly in Drupal 8. I Was the scotch initiative owner for Drupal 8 so lots to do around plugins and I am one of the co-maintainers of C tools and a number of other things Before I get too far along here. Who in here has installed Drupal 8 at this point? Who in here has started writing a module for Drupal 8 at this point of? Those of you who are writing modules how many of you run into the plug-in system and That's why so many of you are in my room. Okay, cool so Let's talk a little bit about plugins. I'm kind of a tell you what I'm gonna tell you tell you tell you what I told you guy So We're gonna cover a number of different topics here First we'll start out with what is a plug-in because I feel like there are a lot of misconceptions just around the topic in general We'll talk about why it exists because I think that is worthy to know and Then we'll get into some of the benefits some of the foundational concepts You're gonna need to have to even really begin using and leveraging plugins and given enough time We'll look at some code and what it looks like to Maybe create your own plug-in Or the basic structure of very simple plugins and plug-in types Before I continue though, I want to throw out a big thank you to hell your Colorado If you all don't know hell, you're he's a great member of our community He and I have kind of bounced this same sort of presentation back and forth a number of times Independently and figured out we had largely the same presentation So just for hives efforts here also educating around this and also Joe Schindler who I don't have in this These guys have done a really great job communicating about plugins as well So let's talk about what is a plug-in I'll start with hell year's definition So hell year says it's a discreet class that executes an operation Within the context of a given scope as a means to extend Drupal functionality That is absolutely accurate. I think it's also Kind of dense so I took a crack at it I think it's a discoverable class and we'll get into that topic here very shortly That implements a particular interface who in here knows what an interface is Yeah Which adds or extends functionality to a pluggable subsystem. What is a pluggable subsystem? Anybody want to guess of one like Drupal 7? Yeah, any basically any info hook is probably what we would think of as like a pluggable subsystem. Okay So going through my litany of things and just kind of breaking it down number one. It's discoverable. Okay That means that we can find it somewhere What what is an info hook an info hook tells you that something exists, right? This is the notion of discoverability. It's actually kind of unique to Drupal. It's object-oriented Which it would have to be if it's going to implement an interface, right? And it's swappable Most plugins if they implement an interface, obviously you have a contract there They can be substituted one for the other Right. That's exactly what these classes are And I think very notably and very interestingly the plug-in system is While it's a requirement of Drupal Drupal is not a requirement of it So if you learn plugins and you really like and enjoy plugins it is my hope that shortly after we release Drupal that you'll see a Subtree split of certain things that have been built during the Drupal's Drupal 8 cycle and You might be able to get plugins through a simple composer Statement the composer install Drupal plugins, right? Anybody playing with composer? Good Good good good. Okay So why did we invent this so we've talked a little bit about some of the older structures and what this is replacing it's worth noting that we looked around at an awful lot of existing code outside of Drupal and Increasingly what we found out is that Drupal sort of is a special snowflake, which we all suspected But most systems really don't have the level of configurability that Drupal does like if you download WordPress Yeah, it's got some configurability to it But it's nowhere close to the same degree as what you're going to find in a Drupal install So there was a very large absence of any sort of similar code like this And I think it's worth talking about frameworks here because frameworks don't expect this at all If you were to download like symphony full stack. Yeah, it has Bundles which you can download and install kind of like our modules, but these are Hard-coded Literally at the PHP layer you literally say I want to turn on this bundle and this bundle and this bundle like we would with With the extend page turning on modules, but instead of it being configured and stored somewhere You literally write it into the PHP code you're specifying which bundles you're going to include and this is kind of stereotypical For a lot of frameworks They don't necessarily have any sort of user interface that turns things on or off or allows people to configure things For a number of different options So some of the benefits of plug-ins Who in here has ever opened up a an info hook and then needed to open up some other file or some other Function that that info hook was referencing and you had to go back and forth You had to turn your screen into split-screen mode, right? This is probably pretty typical if you've done any sort of development in Drupal on something requiring info hooks Or hook menu hook menus a great example where we say oh Here's your page callback, and now I have to look at my page callback and see what were my load arguments What parameters did those come from these sorts of things? and so, you know Stereotypically the block info hook this is system block info I'll just point out a couple of quick things about this That right there is the powered by blocks info declaration, right? It says like here I am Drupal you can place a block now And What's it do we have like this other hook that we have to go implement? Which is hook block view and hook block view has this Gynormous switch statement that says which block are we trying to render? Oh powered by you want this code, right? So every single block that system module cares about every block it could render is all in one function Which is basically the worst thing ever So we don't we don't do that in Drupal 8 Drupal 8 looks something like this. This is this the powered by block in Drupal 8, right? I have one method it specifies what the render array is going to be and at the top of it all of that green text That you can't really read that's an annotation that literally is my info declaration So it all exists in one place all together I can see everything from a metadata perspective about this plug-in and I can see what it's going to execute No split screening no anything and generally pretty small files to we'll get to that here in a little bit So it's probably obvious from the last screen, but plugins are object oriented These are just a few of the block hooks that you have to implement in Drupal 7 and earlier So if you want to block you have to implement the info hook But that's that's not a block It's not going to render anything you can place it all day long But you're not going to get any output because you have to know that you need to go and create hook block view If you don't know that you don't get any output period end of story If you need to configure this in any sort of way Then you have to also have the hook block configure and hook block save if you don't have both of those Then you don't have a configurable block. It's not going to save anything And you can only place one of them so you better get it right the first time, right? Excuse me In Drupal 8 we're backed by a real legitimate interface so These are all the methods that exist on the block interface and I'm just going to keep using blocks for the most part There are many many plugins with in Drupal 8 But every last one of these can actually be implemented by our base class So unless you need to override it the only thing you have to tell us is how you want to render Right you write one method You write a little bit of code at the top of it a little bit of metadata at the top and that's a block Any questions before I go on? No, okay So block the plugins are extensible you can actually in Inherit from a base class or you can inherit from some other class so If you like the login block, but you want to make a much better login block You can extend that class and have your own login block that does all the same things but is styled totally differently, right? No more need to copy someone else's hook and put it into your code and maintain it separately We get the the full benefits of oh as a language construct Now I'll just point out that I've lied a little bit, you know, this is I Said this was the powered by block and it is but we added a couple extra methods to it for caching later, so When you open it and you see that it's not that small It's because we had to override a couple of things for the powered by block because it's always cached Okay, fine Plugins are lazy loaded anybody know what that means like when I say that they're lazy loaded Okay, few of you For those of you who don't know which is the vast majority of the room Where do these exist if you have to implement these? Where do they exist your module file? That's right Is your module file always loaded if that modules running? Yeah, it's always in the memory footprint. Okay, so That that doesn't happen in Drupal 8 We'll talk about auto loading here in a minute, but in Drupal 8 We actually have Individual classes for every single implementation and we only load those classes if we need the classes So if that block is going to be rendered on the page, then we load it And if it's not it's completely outside of your current running memory footprint these are all the system blocks just as an example and This one's super important plugins are a common pattern. They are learn once use everywhere case in point Here are all of the plug-in types that I could find in core a year and a half ago There are more now That's 37. I believe there are well over 40 at this point in core I will show you how to find those here in a few minutes because that has been a question in the past that is uneasy to answer So let's talk a little bit about some like foundational Drupal 8 Kind of concepts that you need to have a handle on or at least know exist Before plugins are going to make any sense really Auto-loading we talked about auto-loading just a little bit before who in here is familiar with the specifics of it as far as Drupal 8 goes Great If somebody says lazy loading to you they also kind of mean the same concept We aren't going to load it unless we need it. Thus it is auto load or lazy loaded, right? So for the rest of you PSR 0 and PSR 4 are super technical jargon for how we auto load things so PSR 0 says something really simple. It says Your class has a namespace on it Drupal core maybe and that maps to a directory Core lib Drupal core. So if I ever see a class whose namespace starts with Drupal core I know that it's got to be in this directory or some subdirectory thereof Cool makes sense same thing with Drupal component and many of our Third-party vendor files as well But that's kind of verbose like we know it's Drupal core. Why is Drupal core in The directory structure. So there's also another one called PSR 4 and PSR 4 Basically comes from the same notion and it says okay, so you have this Drupal block namespace I don't need to have Drupal and block in there. I just need to know what directory to look in so in those core modules block source and Inside of that directory structure if it ever sees anything that starts with Drupal block it looks there And so if there's a plug-in in there or a manager of some sort or any interface That's where it's going to find it And so this reduces the number of directories we need in order to tell Drupal about something by two Which is really nice Dependency injection who in here has ever dealt with dependency injection. Ah Good good good so This is like my good bad Not great example So if you if you ever find yourself creating a new class in a constructor chances are you're doing it wrong, right? You you actually have a dependency on that class for you to run if you're declaring it in your constructor, right? What's better is to pass it to your class and so this is this notion of dependency injection we use this all over core But this can be very difficult when you get multiple dependencies upon dependencies upon dependencies Like if the bar class required a baz class and so on and so on that gets really difficult to instantiate So we have this whole other crazy thing called service containers. Anybody gotten to play with the service container layer yet? Okay We adopted symphonies service container for things and it's actually pretty elegant in the way that it does stuff It allows us to document that we have Certain classes that are available to be used as dependencies and so any of those classes that also have dependencies On each other they can begin to document. So this is my condition manager, which is another plug-in type And it's specifying that it has a parent that it's just going to inherit from if we were to look at that You're going to see that it specifies some arguments those arguments are all going to be other service definitions for the most part So if I look for container namespace boom, there it is Declared says exactly what it is Apparently I should have water. I'm sorry Same thing with cache discovery You know each one of these declares The class that they are they declare any sort of arguments they take in order in order to instantiate and so on and so on Here's the module handler and this is just like one small chain There are some that can be quite dense in terms of the chains that are there and how how many levels worth of auto loading you have to look at So this is how we declare all plug-in managers though So that we can actually get things like the namespaces put into us and we can get the plug-in manager so that we can do alter calls and That's sort of wonderful thing Annotations So if you've made it this far into plug-ins, then you probably nearly got it working. Who's built a custom annotation at this point Okay way less hands Custom annotations are like your info hooks, right? So in a lot of ways they can just be kind of like an array that has various keys and value pairs What's really great about them though is that they are completely customizable to you the developer who might be creating a new plug-in type Right so while blocks want a fairly limited number of things in their annotation Something like the content entities can be very dense in terms of what they take so, you know, the entities are specifying what sort of Handlers they have for storage and access and view and all sorts of that sort of stuff they can specify what their base table is they can talk about their entity keys and Dependent upon your use case you are probably just going to get this back as like an array of data Entities actually deal with this as an object But what's cool is that a full object does actually back you up on your annotation? And so now you have a place to document all those keys that we couldn't really document inside of an info hook like Page callback. What does that mean? How many of these are there? Where can I find a canonical list of every single key that could be in my info hook? Like that's actually really hard and we've worked really really hard on various Drupal sites in order on various Drupal org sites in order to document this for people so that they can see oh Here are all the You know the form keys that I could use here all the menu keys I can use and so on and so forth But in Drupal 8 you're actually backed by an annotation class that tells you right up front Here's every single key you can use and what it can be used for We can also set defaults in these so that you don't have to specify every single one of them all the time if there's the same default that you can apply for People using your plug-in type you can absolutely do that so Before I hop into actually doing some code here. I want to point out a couple of quick things One annotations are not code if anything They're actually much more akin to a serialization format And this is kind of reinforced by the fact that there are a couple of different situations in core where you'll actually find plug-in annotations Defined in yaml instead of in the annotations of the class a couple of Examples you may have already run into is anybody set up a menu item local task local action anything like that Did you know you were creating new plugins? No It's pretty well hidden But those are actually plug-in definitions, right? So when you create those new yaml Entries you're creating a new plug-in definition You can actually specify the class that that's going to run through and take complete control over what happens with That menu item that you just defined That may seem sort of weird but if you were to look at like taxonomy menu in triple eight it runs all of its code through a custom class and Can do quite a few extra robust things because of that I Said that already So my primary point here is that You know annotations are their data. They're not behavior if someone says oh you're coding in comments No, you're really not right Info hooks were kind of commenting and code if anything so Let's look at a couple of practical examples I know that the slides can be a little dry. So I'm gonna hop into some real code here and we'll Show some something hopefully a bit more tangible So everybody see that okay, so I invented the simplest plug-in type I could possibly come up with which is literally just something that DSM's out a message to People on the site So this one has a very simple message. It says roses are red. I suspect you can guess what this one says Which is just simply that violets are blue and These are two specific plug-in implementations of What I hope is the simplest plug-in type in history So let's kind of dig into this and begin like really looking at it. I'm actually going to Awesome. Can you all see that okay? Oh? Yeah, that's pretty good. Okay so a Couple of quick things of note one our class actually implements an interface Okay, if it didn't implement this interface then it would not be Discoverable in the strict terms of what Drupal defines as discovery for this plug-in type Number two it has an annotation the message Specifies that we have an identifier of blue violets and we have a label that is translatable Also of blue violets and the translation system will just pick this up and it treats it like any other string within Drupal, okay? and finally and Most importantly is where this Class actually exists and so it exists within a particular Directory structure inside of our module and because it exists in that directory structure Implements this interface and has that annotation It's a plug-in of the types that I'm looking for right if all three of those things were not true This would not be available to be chosen inside of the plug-in system Now to kind of back that up and show how I know that to be true I'm going to go ahead and go into the plug-in manager for this now I'm at a distinct advantage on this code because I wrote it If you happen to be looking at a plug-in type that you did not write and are trying to figure out How do I write a new one of these the first thing you have to do is you have to find its manager if you don't know What its manager is that is absolutely positively your first task all the time and Once you have found its manager, and we'll talk about how that can be done You want to look at its constructor because its constructor is going to tell you a number of things right in our case When it calls parent construct it passes a directory it says look in the directory plug-in message This is going to iterate over every namespace in the entire system for plug-in message as a subdirectory Is everybody familiar with namespaces I've said that a lot and not explained it once Namespaces are these guys See how it says namespace Drupal plug-in message up there. That's the module in which this code exists and so Every module registers one of these every symphony component registers one of these Drupal registers a few of these and These all get passed to every single plug-in manager as dollar namespaces and it'll iterate over these and check for a subdirectory structure of Plug-in message and if it finds it it knows that it might have plug-ins that are eligible for this content for this plug-in type It then goes on to see whether or not They implement this interface we talked about the interface here it is and Finally it specifies the annotation so The plug-in manager is responsible for setting up all of these Kind of bare minimum you have to do these sort of things And what's especially interesting about this is that While annotations are kind of the order of the day for most plug-in types. They are not the only one possible I already mentioned YAML Discovery is completely pluggable. So if you wanted to write your own discovery system that I don't know Hit a service endpoint on someone else's system and let you do crazy things. You could absolutely do that Discovery is absolutely 100% pluggable. So is the factory instantiation. And so Plug-in managers from a very technical perspective are actually factories with a dictionary applied to them Okay, so they know everything they could possibly instantiate and they have the facility to instantiate them That's what a plug-in manager is I'm going to stop at this point. Are there any questions? We've got mics over here if anybody does want to ask a question Just feel free to walk over there and I'll stop and we can talk Yeah, I think Yeah, so yeah, so the question was if if discoveries pluggable Can you describe why a system like? The menu system would have gone with YAML instead of annotations and That's pretty easy To kind of summarize because in that particular case Almost every single menu item runs through the same plug-in class So if you don't specify a class its plug-in manager applies a class for you and just assumes that this is the one you're running through Because of that they didn't need to attach annotations to classes in order to operate They just needed to document yet another set of metadata to pass through the same class over and over and over again it's Reproduced throughout the entire menu system menu links do it menu actions menu tabs all of them do it and it works really really well in that case It's kind of an odd Use of plug-ins, but I really like it. I think it works really really well and very elegantly and It gives other systems again like taxonomy menu the ability to come in and provide their own Their own logic in that sort of case Another kind of point on that is we haven't talked about Derivers, but who in here's ever written of for each loop inside of an info hook Yeah, did any of you wonder how you might do that with an annotation? Yeah, so we actually have a separate class that you can define that defines the for each loop to run the annotation through I don't show that in this particular one, but if someone wants to see it, I'd be happy to show it So I saw another hand over here. Did someone have an additional question or did I answer it? No, okay great, so So our plug-in manager is really responsible for making sure that it finds our plugins and that it Can instantiate our plugins. I'm gonna go ahead and hop into Drupal here this is my administrative interface for this really simple module and It gives me an option of selecting between my two plugins or no option whatsoever So if I were to select red roses, I can go ahead and hit save on this and I'm gonna get a message roses are red okay, cool and If I want to change it, I'll get violets are blue and of course I have caching issues So I get both for the first refresh and then after that I'm good Because this is a really simple module now This module is public if anybody wants to take a look at it. It is a plug-in underscore message on Drupal.org I have done my best to keep it as simple as possible so that people can really easily dissect it but Coming back in here for a minute Let's go look at the annotation. We've looked at most of the other aspects of this But the annotation I think is especially interesting because it's so simple it didn't have to do much of anything I extended a Base class that Drupal core provides for this and I just documented the extra stuff I wanted which was one thing label and it's a requirement, so I didn't give it any sort of default I documented exactly what you're expected to do here It's an administrative label for this message It couldn't possibly be more clear about what it is that you're supposed to do inside the annotation of your class now so coming back to one of our classes We can see I add well ID is actually assumed in all plugins It didn't say that but it is and then you know you have a label that should be a translatable string for administrative purposes We can also go into the interface just to kind of do diligence on this and you can see as Promised this is potentially the simplest plug-and-type in the world. It has one method. It has one string in the annotation it it's So stupid that it almost shouldn't exist, but I think it it is educational in nature so Now I mentioned that these are supposed to replace info hooks And one of the common things that we see with info hooks is that they typically show up in a user interface somewhere, right? You have a block to place you have you know input formats to configure you have something along these lines, right and so The plug-in system allows us to do this pretty simply By calling the get definitions method just call get definitions and it will find if it doesn't already have Every single instance of plugins for this plug-in type and then it caches them So it doesn't parse annotations every single time you like go through this page. That doesn't happen Parsism once caches them If you need to add new ones, you're gonna need to clear cache and you can specify all of that stuff from inside of the Inside of the manager So I'll come on back to our manager point this out again The manager sets a cache back into interface it sets a cache back end with what was passed to us through dependency injection and then we give it a particular string so it knows oh I have a separate cache for plug-in messages right here the other thing worth noting is that we also happen to have a alter info hook and That means that I'm actually exposing every single annotation across the entire system to an alter hook So that someone else can come along later and start changing things about my implementation So if I didn't like the label that was on a particular plug-in implementation I could change it as a developer for my single site and 99.9 percent of the time if you're going to do this It's probably going to be on a site-by-site basis because you want to change something for the customer I've I've found one situation where that might not be true and we can talk about that in a second But I want to actually show this because I think it's kind of interesting Take into its logical end That means that I could also do something really nasty like replace the actual expected class So you'll see I've put the red roses class here in for the blue violets plug-in and Of course I closed Terminal, so I'm getting clear cache Yay, and after I've done that That didn't work when I refresh over here You'll see I've got blue violets selected But I'm getting the red roses message That's because the red roses class is now running for all instances of blue violets So You remember I talked about maybe doing your own thing with the user login block I've always told people like if you're going to do something like this It's probably on a site-by-site basis and I stand by that but I was talking to the guys who are trying to upgrade to factor authentication and They're like, oh no We actually do need to replace the user login block with a custom class that just takes it over completely so that we can do appropriate to factor Right there on Drupal's normal login block. It's like, oh Well crud there's like an actual use case for that And so if you need it that sort of stuff is is actually there to support you and is really Ridiculously powerful when you realize I can actually take every configured instance of this block throughout the entire system and swap the class It's going through without having to reconfigure anything One altar hook clear cache boom every single block of that type that's out there and running It's running a completely different class than it was moments ago. Let's see. What time is it? I don't know Okay, so we've got about 15 minutes if there are more questions, I'm happy to answer them. Otherwise, I'm gonna start showing really crazy crap Yeah Yeah, if you needed to do it that would be the way to override override the behavior of a plug-in just You know do me a favor and don't do it and contribute modules Like don't contribute modules back that do that unless there is literally zero Like zero other way to do it Yeah, yeah, and it's only if the plug-in manager actually provides an altar hook the vast majority of them in core do though Then well Well, if it doesn't provide it The service container that we talked about every single one of those services and all of Drupal can be hijacked and replaced with your own class Like every last service definition in the whole thing is Technically pluggable as long as you put another class in there that has the same interface on it Drupal will keep running. Oh, no, no, no that that would be changed at a different layer You can actually Specify that you want to hijack an existing container definition and point it at a different class And then it instantiates that class instead of the one Drupal to find so you could hijack the plug-in manager That's there and put your own plug-in manager in and do whatever you wanted to that entire plug-in system The yeah, the question was since I already answered it Is this how you would overwrite a plug-ins behavior and yes in general it is and most plug-in managers provide an altar, so Other questions. Yeah So the question was along the same lines Can you use this sort of an approach to override? entities or entity forms or things like that So You'll Yeah, you can read that So you'll notice this handlers right here handlers specifies all sorts of various things including form Which happens to point at a particular class for the default? Yes, this is all available to you through alters and you should absolutely positively be able to change it entities are interesting in this regard because Most plug-in types their annotation actually returns an array of just their data and in the case of entities They actually return an object But they have a really great set of methods on there that also I believe expect you to be able to alter some of these things out So something like especially a form should be very changeable So if you didn't want to go with like a typical form alter and like manually alter each individual thing And you just wanted to hijack the whole class sure like that should be doable. Yeah Other questions Yeah, oh this should be good In the beginning of your presentation you mentioned something about you gave a little overview of the different plug-in types in core and You I think you said that you'd explain how you our people could figure that out And we built a solution for that in the plug-in module and could trip and I was wondering Did we do something that someone else already sold before? Yes However, I don't think you're going to be upset about it because the people who who solved it already are the Plug-in manager interface. Yeah, I was just going to come here and Scroll through all of the different plug-in manager interface implementing classes So no from a PHP perspective, whatever you invented is probably great Because I'm just using php storm Right, but that's every every class that implements a plug-in manager interface Right there, which is quite a few other questions Yeah If you define an annotation and all of its properties or they all required Yes, and no if you define it and you don't give it a default value It's required if you give it a default value because you could say like protected dollar whatever equal empty string That's not required, right If you just say protected dollar something you need to provide something for that the plug-in class Yeah, you could but you're you're unlikely to extend anyone else's annotation You might extend the the one that core provides And that just comes with an expectation of ID which you have to have Otherwise we can't instantiate stuff for you But you're unlikely to ever extend someone else's The only system I know of that does that is entities and they share a common base class So config entities and content entities actually have two different annotations But the plug-in system is looking for their parent class as the annotation so it picks up both of them Which no one else does anywhere in core as far as I know and it's a cute trick that I wasn't even sure worked until I saw it working So other questions No Okay, well if anybody comes up with one just raise your hand I'm going to have a little bit of fun here So my job at aquia as of late has largely been helping to support various contrib upgrades of Of Drupal modules so Drupal 7 modules We all know and love and trying to get them up and running inside of Drupal 8 So this would include things like taxonomy menu, which we just helped get a beta out of pretty recently and The one that no one has really gotten to see yet that I've been working on for about the last week and a half is services module Which yes, we have some cool stuff in core, but I needed a slightly different approach So we needed a different module so I'm going to show a little bit of that and maybe show off some of the more nifty aspects of Plugins that the session doesn't normally cover. So I'll start with a fairly easy thing here Anybody in here actually ever use services module? Yeah, that's a pretty good chunk of the room One of the things you can do with services module is you can say like hey, I want you to like serialize a node into JSON and Give it to me. You're like okay great So that would be like get in the rest Terminology and so what I have here is I actually have a class whose job is to get an entity and return its data as an array and There's some some really cool things kind of going on here. I'll start up at the Annotation because the annotation is almost the entirety of this you'll see there's exactly two lines of functional code in this plugin to right So okay, what's going on here? I Have an ID of entity get it specifies its method. So it's saying we're doing a git and Then it has this driver on it I made mention of doing like for each loop since I have an info hook This is what derivers do so this is a completely separate class whose job is to know what to foreach over and how to complete the metadata for this class Let's go look at that So this guy actually gets the entity manager inject it into it and then it for each It for each is over every single entity type defined not only in core, but by any Additional module you might have installed here right like if you had Drupal commerce installed it would find all of Drupal Commerce's entities as well, okay? and so it goes through and it begins setting up derivatives for this where it specifies a Title a description the category of the thing a unique path at which to actually address it and then it sets up something That we haven't discussed at all which is this notion of contexts now Contexts are data objects that your plugin requires in order to run Anybody in here ever use panels? okay, so panels has kind of this notion that I Need a node if I want to tell you what the title of the node is So if you want to place the node title in this region, I can't very well tell you what the title is if I don't have the node object That's a context, okay? So I decided to leverage the same sort of idea with services And so my my service definitions all say well I'm currently looking at node or user or comment or wherever we are in the for each loop and it specifies I'm going to need one of those in order to get it for you Okay Anybody want to take a guess where it gets that? Right, so Drupal core does this if you want a node and you're on node slash one node one is is your node, right? And Drupal has this awesome system where you actually get a node object out of that Right in various iterations of Drupal. It has been more or less awesome It is fantastic in Drupal 8, but I'm not going to go there right now So I've specified I need this entity. I'm going to get it injected into my plug-in and So I can say hey get the context value for the entity We defined as a context and then return its values as an array in practice. Let's see. I'll bring up postman Yeah, there we go. It looks a little something like this, right? So I have JSON output of a node object Here's JSON output of a block Right I can see that this block is currently in footer second and Then we can start doing some cool things Let's see if I can pull this off Maybe I don't think that happened proper No 500 error. I definitely screwed it up But the whole idea here of course is that I can pass this stuff off and actually get it to update all across JSON or XML or whatever it is that I'm doing right and so this is actually really really powerful these notions of derivatives because I wrote one class in order to do get for both blocks and nodes and users and comments and orders and Your Entities will work there right you use the entity system I have a deriver that iterates over the entity system. It just works, right? and so like learning derivers really cool learning context also really cool because you get to actually start making these Dependent upon the objects that you need in order to operate and you don't have to manually get that you don't have to say Oh, well, this is going to be node post or node put and I know I'm going to need to serialize this thing as a node object and Manually write that code. No Drupal has a serializer that can look at JSON and figure out how to turn that into a node for you who knew right and So I don't have to actually specify node anywhere in my code and because of that I get a lot more out of it I think we are right about at the end of time Looks like we have maybe five more minutes, so yeah, oh, yeah Yeah, so so the questions like Functionally couldn't I do something awful with that and the answer is yes, you could As as an example of one that I didn't even think of It wasn't until I was standing in the hallway demoing this to some friends that I Realized services actually had all the knowledge it needed to create new service endpoints across its own API And I was like, oh, oh Do I do I want that? I don't know if I do right? Which is why it's nice to have these altars that you can just like throw crap away with and be like No, I don't want that, you know, I'll manually alter that out So, you know, we still have altar hooks in in Drupal We probably shouldn't we should probably have done it some other way But we do for the time being and they work and they work really well So I would encourage you not to do something awful Unless you just really cannot be stopped in which case make a dependency on bad judgment and go have fun Other questions No, okay. Well, I'm gonna let you go a few minutes early and if you have any additional questions, feel free to come up and ask me Thank you. Oh God, no never say never bring up Portland ever again. We did Made all the slides but we never got to go over that's a group At some point it broke down into a love fest about p.p. Storm, and I don't think we ever actually recovered from that point Thank you, but I think what's what's more interesting to me about that particular topic Is that like that slide that shows all the ones that are in core which isn't even all the ones that are in core I helped I helped create like maybe four of those For and there are like ten times that many in there, right? So other people obviously like picked it up and ran with it We we brought it in because we knew we wanted it for blocks and we knew we wanted it for block visibility via conditions That was why we needed plugins and we're like if no one else uses it So be it that didn't happen and that was great. Anyways your question It's more like it's like saying oh the behavior for this Particular type of thing exists over here. It's not behavior in the annotation itself. It's documenting where it exists Cuz cuz like from a separation of concerns perspective, we don't necessarily want that behavior in our plugin like I wrote the plug-in system Three times in the first two. I tried really hard to get derivatives as Methods on the actual plugins that just never stuck it never worked. It was always Crufty and ugly and made me want to like Oversight from some other