 I'm gonna go ahead and get started. I know that the photo just finished up and everybody's trying to get caffeinated before they sit through all of these really long sessions. But I've got a lot to say, and so we'll get the boring intro stuff out of the way while people continue to wander in. This session is titled Altering, Extending and Enhancing Drupalate. There's a link here that you can use to go to these slides. And if you want to follow along, there's also a handful of slides throughout this presentation that are actually just like a big list of links. And rather than have you try to write them all down, the easiest thing to do would be to go to this URL and get the list of slides and get the links from there. The idea is that in the coming weeks after you've left Drupalcom and you want to go home and you've been dreaming about altering and extending and enhancing Drupalate and you'd like to review some homework, there's a lot of good reading with those links. So, yeah. Anyways, my name is Joe. I'm Joe Schindler. I am EOJTheBrave on Drupal.org or Twitter or just about anything internet related. I currently work at DrupalizeMe. My role there is as a trainer. I help to produce training videos to teach people how to do all kinds of different things with Drupal. And as you would guess, we've been spending a lot of time recently figuring out how to do those same things that we've been teaching people how to do in Drupal 7 in Drupal 8. And that's kind of the genesis for this talk. Looking at there's all these different ways that we've learned over the years to extend to Drupal 7 and work with Drupal 7 and create modules for it. And we'd like to be able to do those same things in Drupal 8, but the tools that we use for doing that have changed a bit. So I'm going to be talking about those. Let's start off by talking, though, kind of like set the framework for what it is that we're going to be looking at. In the Drupal community, we have this idiom, don't tap core. The idea is that you should, as a module developer, even as a Drupal site builder, somebody implementing applications with Drupal, you should be able to build your entire application and make all the changes that you need. You get Drupal to do whatever you need it to do without having to make changes to the code that makes up Drupal core. This allows you to make sure that your application and core maintain that integrity. So you haven't modified it at all. It makes it easier to perform security updates. It means that if you have questions about things that are or aren't working, you can ask the community, and people can pretty feel confident in the answers that they give you. Whereas if you had made changes to your version of Drupal core and you asked me a question about how it worked, I would give you the answer based on the expectation that you're using the same thing as everyone else. And if you change it, that might not be true. So Drupal provides all of these tools that make it possible for us as module developers to modify the way that Drupal works and extend its existing functionality without having to change any of the code that makes up core. In fact, I would argue that if you encounter something where you would like to make Drupal do a thing in a different way or add new some functionality, and the only way to do that is to modify code within the core code base, that that is actually a bug, and you should probably fix it and submit a patch. So I often say instead of don't hack core, I say don't modify core without submitting a patch, basically. In addition to that, we're going to look at how we as module developers can write our modules in a way that ensures that people can use them without making changes to our module. So for example, if I was the maintainer of the voting API module, I might want to be able to write it in a way that allows people to add additional features to the module without having to modify my module. So it's a combination of using these various different patterns and techniques in order to extend and alter Drupal core, but also knowing how they work so that we can repeat those patterns inside of the code that we write so that when someone else comes along and they want to make changes to our module, the pattern is familiar to what they already know how to do. This works in Drupal because throughout the life cycle of a page request in Drupal, there's a number of different things that happen in points of interaction in which we as module developers are asked for information or given the chance to interact with the system. And it really roughly breaks down into sort of four categories of interaction. The first type of interaction that you might want to have is responding to some information provided by the system. Events, if you will. Drupal just did something and I as a module developer would like to do my own custom thing as a result of that. For example, whenever a user logs into the system, Drupal notifies any code that's listening and says, hey, Joe just logged in. Do you want to do anything about that? Whenever a node is deleted, Drupal says, hey, a node was just deleted. Would you like to participate and do anything about that? So there's responding to events or other information within the system. There's code that answers questions. I think of this, if you're familiar with Drupal 7, this would be kind of like the info hook that provides a bunch of metadata about something. There are all these instances where Drupal needs to get a big list of a whole bunch of possible options and then use those for different things. One of them might be the menu system. It needs to get a list of all of the possible paths that someone could go to. Another might be the block system. It needs to get a big list of all of the possible blocks in this particular instance of Drupal that someone could install or, I guess, enable on their site. So you're answering questions like, do you have one of these? And if so, where can I find it? The other thing that we do with modules is we add new functionality. So we might write a module that adds a new building block, if you will, as part of how people build their site. It might be adding a new field type. You might be changing the way that a certain system works, but ultimately you're adding functionality that DrupalCore doesn't already do. Or you might be writing code that alters some existing functionality in Core. For example, you're using the node module, but you want to change something about the way that it works. Drupal provides ways for you to say, this is how I do it by default, but if you'd like to do it differently, as a module developer, you can alter those interactions. So don't hack Core. Instead, use one of these patterns. Use a hook, or write a plugin, or create a new service, or subscribe to an event and respond to those events. So in Drupal 7, we really had had, I guess we still have Drupal 7. In Drupal 7, we only have one real way to perform all of these different types of interactions. You can do them all, and they still exist, but the primary means for doing that is by implementing hooks. In Drupal 8, that changes though, and we have some new patterns that we have to learn in order to answer some of those questions. We still have hooks, but in addition, we've added plugins, services, events. There's actually a few others as well, but these are kind of the big four that you'll need to know. What I'd like to do in the rest of this presentation is kind of give a high-level overview of what those things are. We'll talk about the problems that each one solves and when you might want to use, for example, plugins to do the thing that you're trying to do. We'll look at how you can implement the service or the pattern in terms of I'd like to alter or extend Drupal, but also as a module developer how I can repeat that pattern inside of my module so that if, for example, I would like people to be able to write plugins for my module, what do I need to do on that end? The first one that we're going to take a look at is plugins. This is a new system in Drupal 8. I talk about this one first. There aren't really any particular order, but I would say of all the systems for altering or extending Drupal, plugins is going to be the one that you're probably going to encounter first of the new systems. It's really widely used. In Drupal 8 it's used for basically any time that you come up to a scenario where Drupal needs to get a list of some functionality and then allow a user or the application itself to choose one or more of those units of functionality to use, those are generally implemented as plugins. Blocks is a really good example of that. Modules need to be able to provide new blocks. Drupal needs to be able to discover them so that it can present them in the UI, but then an administrator of the site really chooses which block or blocks to use on the site. Other instances of that are field types, plugins for views, so like use styles or row styles, the actions system. In Drupal 7 this was often represented as you would have an info hook that would return an array and provide a bunch of metadata about, you know, hey, I provide blocks, I'm going to implement hook block info so when Drupal needs to make a list it could call that hook and get a list of all the blocks, but then all that array really did was say here's the callback functions you should call in order to implement that functionality. So plugins allow for that. They provide an opportunity for module developers to create new configurable functionality in a way that Drupal can find all of it, aggregate a list of those together and then present the user sometimes also just the application itself with the opportunity to choose between one or many plugins. Compared to how we did this in Drupal 7 plugins are implemented as classes that implement an interface. It's kind of the basics of it. You would say I want to create a new block so I'm going to figure out what the interface is, the PHP interface for the block plugin and I'm going to implement that interface and so every block has a label and it has a body and it has a couple of other common components so I write a class that adds those methods because those exist Drupal will always know how to use any instance of a block plugin because they all conform to the same interface. I like this because it provides a pretty consistent experience for me as a developer. Once I learn how plugins work and how to implement a new plugin of a specific type the pattern is the same and I can just use it over and over for every different type of plugin whether I'm adding a block or an action or an image style or even some kind of new condition that the form system can use for validating a field. They're all implemented in roughly the same way. Versus Drupal 7 you run into this problem of you have to look up the documentation for the info hook and the array that it returns is different for every single info hook and you have to remember like wow do I use pound signs in front of the things is this a callback or is it just magically going to look up a function called hook block view if it exists. The nice thing about plugins is that's all self-contained into a single space and I can very quickly find all of the code that makes up that individual component. So if you're going to implement a plugin and if you're a module developer you are definitely going to end up implementing a plugin at some point. This is the real rough recipe of how you would do that. What you need to do is determine what type of plugin it is that you're implementing. So are you creating a new block? Are you adding a field widget? Are you adding an action? There are hundreds of different plugin types in Drupal Core. The best way to find out what all those available types are is to look at the documentation on api.drupal.org. You can also in the code you could say look for all of the plugin managers. A plugin manager is the name that implements the new plugin type. But once you know what type of plugin it is that you're going to implement, this helps to determine how you perform the next two steps. You have to do these things for every type of plugin, but it's different depending on the type. But you need to say, so once you know the plugin type that will tell you where does metadata that describes your particular instance of the plugin go. Typically the plugins are what are called annotated plugins. And so the metadata will appear in an annotation in the PHP file where the class is that implements your plugin. But you need to know where that metadata goes and then you need to know based on that also where the code goes. Again, the most common use case here is annotated plugins, which means the code lives in a single PHP file. You'll know where it goes by following four names facing convention and the metadata will live in an annotation. That's true of almost everything, but there are a handful of other there are a handful of plugin types that use different methods for discovery. Once you know what type you're implementing and what the method of discovery is for that type, the other thing that you'll want to do is figure out if there's a base class that you can extend for that plugin. And in most cases there is. You don't have to extend it for probably the easiest way to get started is by extending that base class. And so the example would be if I'm adding a new block I would extend the block base class, which provides a bunch of functionality, but it also means that I'm implementing that plugin's interface. And by implementing an interface as a developer I now know, okay if I'm providing a block plugin the things that I'm required to do are somehow supply Drupal with a label, so the title that's displayed for the block and the body content of that plugin. And then finally you need to actually write the class write the code that implements the plugin. So that's the recipe there. Determine the type of plugin which will help you figure out how Drupal is going to discover instances of your plugin, extend the base class if it exists, and then write your functionality by implementing the specified interface. This is a super simple example of what an annotated plugin would look like. I've got a PHP namespace. So based on that namespace I also know where in the file system I need to place that code so that Drupal can discover it. This comment here at the top is an annotation. So that's the metadata for this plugin and it describes some sort of roughly static information about the plugin. This is typically the stuff an example of blocks. This would be the administrator name of the block in a unique ID so that Drupal can make the list on the block UI page of what all the available blocks are without actually having to load and execute the code that makes up each individual block. So that information is contained in that annotation and it parses it out. And then I'm extending the base class and based on whatever that base class is I'll have certain methods that I need to implement in my class which provide the actual functionality of the plugin. So as a module developer you're going to write into this any time that you're adding new functionality into one of the situations where Drupal's presenting end users with a choice in which they determine which of the many things that are capable of doing this I'd like to use. And if you stop and think about it, that's a lot of things in the way that Drupal works. Fields, field types actions image styles for example the effects that you can apply to an image those are all implemented as plugins new units of functionality. As a module developer that wants to be able to allow someone else to write plugins for their module, you're going to have to create what's called a plugin type and this is the rough recipe for doing that. The example here would be let's say you're the main chainer of the voting API module, apparently this is going to be my example today. So you're the main chainer of the voting API module and you've written the ability for your module to calculate votes in one way and somebody else comes along and says you know it would be really great for my system I need to do instant runoff voting and then somebody else comes along and is like well you know what I need is I need it to tally votes like this except on Tuesdays I needed to tally them in reverse just because we've got this crazy system and as the module developed we're like oh man I do not want to write every special use case into my module for everyone that's ever going to use it so instead what I'll do is I'll implement a new plugin type and I'll then create maybe one or two basic instances of that plugin that do the basic vote tallying but anybody that wants to can extend the voting API module and add in their own plugins that tally votes in whatever way they need to on Wednesday morning for their special use case so if you want to do that what you need to do is in your module you need to create a new plugin manager so plugin managers are the thing that are responsible for declaring a new plugin type you do that by extending the default plugin manager class which is in core and when you do that you're determining a few things we said that the recipe for creating a plugin dictated how metadata for those plugins was collected and where the code lived when you create a plugin manager that's part of what you're doing you're saying for plugins of this new type here's how I want to discover them and here's where the code should live so that I know how to instantiate a new vote tallying system and call that finally when you create a new plugin type you should also make sure that you define an interface for people to use when they're creating new units of functionality of that plugin type the benefit of having an interface is that as the module developer that is now going to load one of these plugins and potentially call it and make use of it I know for sure that every instance of my voting API type will conform to this interface and they'll all have a calculate results method and so I don't actually have to care how the plugin actually got used I can just load any of them based on the user's specification but I know the method exists and I can call it this is one of those slides that has a bunch of links to things that you can read at home should you want to read more about how the plugin system works so I'm just going to skip this I'll also point out that at 2.15 today there's a session about the plugin system that goes into much more depth about how all of the different pieces of the system work so if you're interested I would definitely recommend checking that out another one of the new ways that we in this case really extend Drupal is the use of services so services are a way for Drupal to encapsulate units of functionality into sort of a bundle of code this is probably easier with examples things that in Drupal 7 are typically implemented as API which is really just a bunch of global functions in the PHP namespace that you would call in order to do some kind of tasks are usually implemented as services so caching for example you instead of having two global functions which are like cache get and cache set there's now a cache service as a module developer if I want to cache something I would ask Drupal for a copy of the cache service which then has that API so it's like cache service probably has get and set methods so similar in that it's really just a set of functions or methods that I'm going to call and able to make use of the service but implemented in a bit of a different way other examples of things that are services if you're creating a new plugin type the plugin manager itself is a service you might want to use services or create your own service if you're doing something like integrating with a third party API so if you're writing the Twitter module and you needed to create an API client to interface with Twitter you might do that by writing all of that business logic into a class and then declaring that class as a service to Drupal and then anyone else so then you can make use of the service yourself to say create a block plugin that displays all of the tweets for DrupalCon on the page but by implementing this service you also make it so that anyone else could easily get access to the Twitter client that you provided and make use of that API as well but you're not doing it by implementing a bunch of functions in the global namespace this is awesome because it means that that functionality is really well decoupled from Drupal as an application this allows me to do things like for example write tests where instead of actually having to ping Twitter every time I want to test whether this block plugin works I can substitute the service that I wrote that interfaces with Twitter for one that is just a mock of that service and it just you know rather than actually making a request it just acts like it made the request service so this works because services can be swapped out for one another it gets a little confusing because it's like alright this is two ways of providing new functionality I could write a plugin or I could write a service I think the big difference between plugins and services is that services typically represent some kind of functionality that you would only really ever have one active instance of at any given time whereas plugins you may have just one or you may have a whole bunch of plugins active at any given time so things like for example the cache system you're probably only using one caching service at a time whereas blocks you might have five different blocks enabled on the page so that's more of a plugin functionality Drupal Core has a whole bunch of services built in so one of the things that you need to know as a module developer is what are those available services so that you can make use of them in Drupal 7 we would do this by going to api.drupal.org and just start typing the name of a function into the search box and all of a sudden you're like whoa Drupal has a function for formatting plural strings like I had no idea that's cool so all of these like helper utility things that we made use of in Drupal 7 as just global functions are now typically written as services the best way to get a list of all the services is if you go to api.drupal.org over on the right there's a block with a link for services and on that page it'll list all of the available services in core it can be a little bit daunting to figure out what those all are but I do recommend taking a look so that when you start writing your own modules you're not writing repetitive functionality there's a lot of things that core is already doing so why not make use of that service rather than writing it yourself however if you do want to write your own service like let's say for example your the twitter module well okay you're not actually the twitter module you're the maintainer of the twitter module and you want to write a new service for that name with twitter what you need to do is first you need to choose a unique name for your service the reason for this is that these all get bundled together by Drupal and as a later on when you need to make use of the service you need a name that you can use to reference it so that you can say hey give me an instance of my service that I created the best way to create those unique names is typically going to be to prefix the service name with the name of your module so you might use something like twitter.client as the service that you're creating then you want to define a PHP interface for that service this isn't necessarily required but I would highly recommend it again what happens when you define an interface is you're creating a template that you and anyone else could use in order to know how to provide that specific service that way if later on someone wants to come along and provide an alternative implementation of the twitter client they could create a new service that implements that template that you created make the underlying logic a little bit different but the code that's making use of it doesn't have to be updated it can just use the new version of the service once you've created your class that is that service you need to register your service with Drupal so that it gets so that Drupal's dependency injection container can locate the service and then later on you can make use of it this is done by adding a dot services dot yml file in your module so it's just the yaml file that has some metadata about your service it says here's the unique name of my service here's the location of the class that implements the service here are any other services that mine depends on so for example your twitter client may also depend on the http request service that is used in order to make requests across to another server and it may depend on a few other services within Drupal as well once Drupal knows about that service during the life cycle of a page if you ever wanted to make use of your service or any of the existing ones you will gain access to it by using the services container so this is one example of how you can do that you would use this call like this the unique name of the service that you're trying to use and what that will do is return an instantiated copy of that service the nice thing about doing it this way this is kind of the level of indirection in that allows Drupal to say hey you know what on this particular request I actually want to use the test version of this service it also this will automatically deal with in your services dot yml file where you said my twitter client depends on these other services if I get a copy of the service through Drupal's service container it will have already loaded and made those other services available as well so I can just say hey give me a twitter client it'll take care of all the dependencies for you my advice would be anytime that you've got custom business logic inside of a module implement that business logic as a service and then use these other methods like plugins or if it's logic that displays something on a page or the controller as a wrapper around your service to do the thing where it's just like to basically to make your service talk to Drupal the benefit of doing it this way is your code becomes more portable and that it's no longer necessarily dependent on the existence of Drupal to work and you can move it to another system you can start to create composer plugins for example but kind of anytime that you've got like custom business logic think about implementing that as a service there's a bunch of links here for more information about how the services system works and there's also a talk about services today at 345 this talk is actually it's listed as a talk about dependency injection but you can't really talk about dependency injection without also talking about services so you'll I assume you'll learn a bunch about services in that talk alright so we got plugins and services so plugin and both of those essentially allow you to provide new functionality to Drupal or really to like replace some existing functionality with something that does the same job but in a different way what about if I want to respond to actions or events that take place within Drupal so one of the new ways to do that is with Drupal's events system this is a pretty common pattern it's basically the idea that when actions happen Drupal will broadcast the notification that something just happened and you can subscribe to the event system and say hey Drupal whenever a user logs in I'd like you to notify me about it or whenever somebody deletes a node could you notify me about the fact that a node was deleted and then I can want to do something with that information so you subscribe to events to get notified of when they happen whenever an event is triggered there's also usually some additional information that's passed along with the event so you might have like event name user login and then the object itself that represents the event and that event object will probably have like here's the user object that represents the user that just logged in and so now I can use that contextual information to I don't know do something useful let's expand our twitter example I can write my Drupal site to automatically post the comments on twitter whenever somebody logged in so that's useful right events are this is not a Drupal pattern and this is not a new pattern it's new in Drupal though it's something that if you've worked in other site oriented systems you've probably encountered if you've ever written jQuery you've probably implemented an event listener pattern anytime that you are using javascript to say hey when somebody clicks on this link I want to do something that's the equivalent of subscribing to an event you're saying hey browser notify me that somebody clicked on the link and I'll do something with that information I like events because it's a pattern that I already know and it means that at least at like a mental model level I understand the concept of any event happens and I can subscribe to it I can expect to get some additional contextual data about that event and do something with it I'm hopeful that this is useful for people who are new developers to Drupal or making the transition from some other system into Drupal because it's a pattern that they're probably more familiar with from other systems than for example hooks which are totally a Drupalism with the events you do you do two different things you either subscribe to an event which is basically me saying I would like to do something when somebody else's code has performed in action or you broadcast an event you say I just did something and if anybody else wants to respond there's an opportunity to do so if you want to subscribe to an event what you need to do is figure out what event it is that you're going to subscribe to there's a list on api.drupal.org of all the events that are emitted by Drupal core and symphony as well actually Drupal 8 has a lot of symphony components built into it and makes use of those in various different ways and a lot of symphony components allow you to communicate with the things that are happening within that component by broadcasting events so you figure out what event it is that you want to subscribe to and then you need to create a new service that is tagged as an event subscriber I'll come back to kind of why in a second but what this looks like is inside of your services.yaml file you add an entry like this that's basically like hey here's my class that's going to do some work whenever this event happens and here's just tag me and I'm saying this thing is an event subscriber the reason that you have to register your event subscribers like this is so that Drupal can be a little bit more performant about the way that it dispatches events so rather than dispatching an event and saying okay now I have to go find every possible place that there could be code that might want to listen to an event and then actually see if they're listening to that event so the service container uses this information and at one time will run through and find all of the things that listen to events and which events they're listening to and it compiles a list of those and basically caches it so then when an event is emitted it can just look at that cached list and it's much more performant than having to look it all up in real time of course you have to provide some way for it to find that once you've done that part you create a new class that implements the event subscriber interface in that class you do two things you have a method that says here's a list of the either the one event or the multiple events that I would like to be notified of and then here's the PHP callable so the function or the method on a class that I would like you to trigger whenever that event happens so pretty straightforward it's basically the list of things I want to know about when that happens you can let me know by calling this function or this method right here and then within that function or method you would do whatever work it is that you would want it to do when that event happens so for example this is where I would say I'd like to subscribe to notification for whenever someone logs in and then when they log in call this method and then within that method I would probably use the service container to load a copy of my Twitter client that service we created and then I could use that service in order to post the message on Twitter that Joe just logged into his website the other time that you're going to use events is if you want to dispatch events so that someone else can listen, subscribe to those and react a lot of third party APIs have this notion of web hooks so some action happens on your payment gateway website and when that happens the payment gateway pings your site and says hey this just happened here's some information about it so you write a module that receives that incoming post data and does something with it update somebody's account status or whatever you do with that web hook information but the problem with that scenario is in most cases you receive the data and you can do something with it but now what if I want to extend that a little bit and I'd like to write a module that also does something when the payment gateway pings our website and says someone just made a payment so as the module that implements the payment gateway API what you might want to do is whenever that action happens do whatever you need to do but then dispatch an event that others can also respond to that request in fact what you should really do is receive the notification and then just turn around and immediately dispatch an event and then you can just write your own and then you can subscribe to the event that you're dispatching basically like eat your own dog food that way that your components are all nicely decoupled so if you want to dispatch an event the recipe for doing that is create a new class create a new class and place it into this psr4 namespace so drupal your module name events and then your class this class is not actually really used for any functionality but what it does is it serves as documentation of the event that you're broadcasting because here's the thing if people don't know what events you're dispatching there's no way they're going to be able to subscribe to them and actually do anything useful so the first step to making a useful event system is documenting those events that's done by creating one of these creating a class in this namespace and then providing properties on that class that are the unique names of the event and that gives you a space in the document where you can basically write a doc block for that property that says you know the event name is user.login this event is triggered whenever somebody logs into your site blah blah well don't write blah blah blah on your documentation but you get the point so document the events and then in your code wherever you would like to trigger an event you'd like to say this just happened and dispatch it you'll use the event dispatcher so that's there's a service for that there's this down here line the third one basically you use the container aware event dispatcher and call the dispatch method give it the name of the event but the name of the event is that thing that you just documented in the class above so that people can discover it you'll also want to this I point this out specifically that you'll want to make sure you're using Drupal's container aware event dispatcher and not just the event dispatcher that comes with symphony because the container aware one is a bit more performant and that's the more Drupal way of doing this so that's the recipe for dispatching event basically come up with a unique name for your event document it and then in the appropriate place in your code where you'd like to notify others that something is going on use the event dispatcher to say this is what just happened and create a class that is an implementation of this event interface and that will whenever you dispatch an event you pass in an event object and the event object contains information like this is the name of the event that was just dispatched in the case that it's a notification that a user just logged in it probably contains the user login or the object that represents the user that just logged in and maybe the time that the event happened it's basically contextual data of the application when that event was triggered this slide has a bunch of links to things that you can read about more about how the event system works in case you want to follow up on that and finally the last one that we need to talk about is hooks if you've written modules for Drupal 7 the hook pattern I was going to say should be familiar to you but if you've written modules for Drupal 7 you have to know about the hook pattern because all of these things that we've just talked about are implemented as hooks in Drupal 7 in Drupal 8 we still have the notion of hooks we just don't use them for everything like we did in Drupal 7 and they still the pattern is still pretty much the same in Drupal 8 you'll primarily see hooks used for the occasion where you need to alter some existing functionality for example the plugin system allows you to create a new plugin type and part of creating the way the plugin system works is it says I need to get a list of all of the instances of block plugins so that I know what's available for an administrator the hook system after all that metadata is gathered here's a list of all the blocks the hook system allows you to say and I'd like to give other people the opportunity to alter that list one last time before I present it to the user in Drupal 7 this was often implemented as a pattern like you'd have an info hook immediately followed by an alter hook so it's like give me a list of all the menu items now give everybody a chance to alter the list of menu items that I just created the other use case that we see a lot is still the primary way of altering forms in Drupal 8 is using alter hooks so anytime that you want to make changes in existing forms you would do so by implementing hook form alter there was some work done to start to convert all of these things that are still hooks to the other systems primarily events it hasn't, not everything has been converted yet and so there's a little bit of a weird like some things are events and some are hooks and sometimes it can be a little bit tricky to figure out which pattern you should be implementing when it comes to like trying to interact with Drupal core I would say really you're limited to just saying does Drupal core let me change this as a hook or does it tell me about it as an event and you have to do it that way when you're writing your own module you can kind of make that distinction you can decide am I going to dispatch an event or am I going to call a hook or trigger a hook my advice would be in most cases you're probably going to want to dispatch events and I think that what we'll see over time is Drupal core will shift more and more to implementing events and remove more and more hooks especially once there's a performant way to handle this form altering or this idea of like here's a big list of things that I'd like you to be able to modify the list that we'll see more and more things implemented as events so once you're writing new modules for Drupal 8 for the most part I would say you'd want to dispatch events because that's a pattern that people are going to be more familiar with and going forward I think that's going to become the dominant pattern for how this is handled I kind of said this already though hooks are really great for altering existing information and part of the reason that they still exist in Drupal 8 is they're really fast at allowing that to happen there's very little overhead to call in a hook it's just a function that if it exists Drupal will call it you can pass in an array the array can be modified it really doesn't get much faster than that in PHP eventually though I think that that's going to change and we'll figure out ways to be just as performant or close to using the event system and a lot of things that we do with alter hooks now are going to change I also kind of point this out because hooks are totally a Drupalism whereas all of these other things are similar to patterns that are seen in other frameworks hooks are totally a Drupal thing and a large part of that is that at the time that Drupal was originally created and the community wanted it to be flexible a flexible system that you can alter and extend without having to have core hooks was kind of the best system available at the time in PHP PHP has advanced a lot in the last 10, 12 years and so there are new things that we can do and Drupal 8 is starting to take advantage of a lot of those in ways that we haven't before if you need to implement a hook in your module this is how you do it I'm going to go fast through this because this is probably pretty familiar you determine what the name of the hook is typically you do this by going to Drupal.org and start typing hook underscore into the search field and see which of the like 700 things that is returned looks the most like the one you might want to implement you then create a new function inside of a .module file and you replace the word hook in the documentation of that function's name with the name of your module if that function exists or so and then basically when a hook is triggered Drupal says hey of all of the modules that are currently enabled do any of them have a function that is module name underscore hook name if they do I'm going to go ahead and call that right now and then you implement your hook according to the documentation which is like okay this is one of the things that I love about all of the other new systems that we have and the idea that much of it is implemented around PHP interfaces and more modern object oriented programming techniques is that when it came to hooks it was always like hooks was the system that you would implement but then for every hook that you were implementing what you did inside of that function was different and it wasn't just kind of different it was like there's a dozen info hooks but every one of them returns a different style of structured array there's a dozen hooks that are called for different events that happen when a node is different node related events so when a node is saved or loaded from the database or updated and so forth and each of those are slightly different so you'd always have to go look up the documentation for the hook to figure out what you could actually do with that hook whereas I believe that interfaces will make it a little bit easier as a developer to determine for example if I'm going to create a new block and I know how the plugin system works well enough that at a certain point all I'm really doing is creating a new block plugin which is an implementation of some interface and I'm since I'm implementing the interface I know that my class has to have a label method and a body method and then Drupal will know how to make use of it versus the Drupal 7 version of that is like well you have to know that you need to implement hook block info and hook block info returns metadata and possibly some callback like names of callbacks as well but then you also have to know that there's this other magical function that might get called if it exists which is hook block view and if you don't implement hook block view people can place your block into a region on their site but there wouldn't actually be any content in it because you didn't implement this other function because there was no way of enforcing that that function was there and so I think that hopefully some of these new systems will make the patterns a little bit easier to discover within Drupal 8 anyway you read the documentation and then implement your hook and for good measure after implementing the hook or the first time adding it you'll want to clear the cache certain hooks or not the hook itself but the fact that the hook exists is cached in certain cases for basically just for performance reasons and so if you've implemented a hook and you're like it seems like my code isn't getting called it's probably because you need to clear the cache if you're going to dispatch hooks so for example you written a system that gathers a bunch of metadata about whatever you've gathered a bunch of information from other modules and you want to give people the chance to alter that so you want to dispatch an alter hook you would use the module handler service to dispatch those or basically to call all of the hooks Drupal calls this invoking so you would invoke all of the hooks on all enabled modules the way to do that is you can do Drupal get the module handler service this is really just shorthand for what we saw much earlier which was using the services container to get a named service the module handler one is so commonly used that there's actually just a method that you can call to get a copy of that service and then it has a couple of methods which are invoke all or alter and these pretty much are exact copies of things like module invoke all and Drupal alter from Drupal 7 they're just implemented as services because rather than putting things in the global namespace like in Drupal 7 those types of things are now implemented as services you want to know more about hooks in Drupal 8 and how they work there's some good documentation on api.drupal.org so as a quick recap the idea here was to take a look at all of the new ways or really the different ways that we can as module developers extend and alter Drupal without ever having to hack Drupal course code we talked about four of those these are really the most common ones that you'll encounter and those are plugins so plugins allow you to provide new units of functionality generally ones that are going to be presented in a list where someone can choose one or more of those pieces of functionality in order to use it's also important to remember that those lists aren't necessarily always provided to the end user like a plugin a list of plugins may be something that Drupal core itself generates in uses but then does some determination within the application itself to choose which plugin to use an example of that is the the tool that decides whether or not Drupal is going to have a response from Drupal is going to be formatted is it HTML or is it Ajax or whatever the case is actually a plugin system and so there's the HTML renderer and there's the Ajax renderer plugin and what in a request is made Drupal makes use of information in that request to say well here's a list of all the possible plugins the one that looks most appropriate in this use case is the Ajax responder and so it'll make use of that plugin this is allow you to encapsulate your business logic into like units of functionality that are all like things combined it also allows you to keep that functionality decoupled from Drupal itself which means it's easier to write tests for your controllers or your plugins our example was you might create a service that implements the Twitter API and then you can create a block plugin that adds a list of tweets into the sidebar in order to make sure that that block plugin and all of its functionality was more easy to test as long as you implement the Twitter API as a service you could when you were writing tests say swap that service out for a mock version of the Twitter API and not have to make real requests in order to test things events allow pieces of code to communicate with one another it's basically either you're listening for people for code that says hey this just happened would you like to do anything or you're saying hey I just performed this action in case anybody wants to know about it and then hooks are partially a carryover from Drupal 7 and what they are primarily used for in Drupal 8 is for altering things usually it's either altering a form or altering a big list of some other metadata that was gathered in some other way but we want to give modules a chance to change that list of metadata before we parse it and make use of it so that's the primary ways of extending, altering and enhancing in Drupal 8 there is the link to these slides I'll pull that up again but so you can get all the links that are in them and then if you've got a moment and could leave feedback on the session that would be awesome that's all I got thank you I've got a couple of minutes for questions so if anyone's got a question I'm happy to answer it or you can come up here and I can answer up here there's a microphone or you can just raise your hand and make it up as we go put your business logic into the services and then use plugins to tell Drupal about business logic to the services quite exciting really does that mean that we can like in what way is your business logic portable to another system outside Drupal? so one of the idea was implement your custom functionality as a service and then pull the service into your blend make use of it the hope is that you could write that code following PHP standards like the PSR4 standard and encapsulate it all into a service that if you wrote your service so it wasn't dependent on Drupal itself I'm trying to come up with a good example of this well okay so like something like Drupal Core uses the Guzzle PHP library in order to make HTTP requests and it does so by registering Guzzle as a service within Drupal Core but it basically says here's the service for responding to HTTP requests if I wanted to write a different version of Guzzle or if I wanted to replace it you know I've decided that you know what I really don't like Guzzle I'd rather just use my own custom code to perform HTTP requests as long as I implemented the same interface as that service and then I could register and Drupal could say you know what I need the thing for making HTTP requests and it'll now grab my version and make use of it another would be database layers like are you talking to MySQL database or Postgres database and the back end service that handles that if it's written in a way that is agnostic to the fact that it's Drupal could be used by other systems as well in practice in most of Drupal Core this isn't really done much yet because what happens is your services likely depend on another service and that service is probably specific to Drupal Core right now for example your service probably depends on the database so it can say interface with the database so you couldn't just remove Drupal from the picture completely because it still needs Drupal database system but I think what we'll see over time is that those all the services that make up the back end of Drupal will become less and less couple to Drupal and hopefully more and more just part of the greater PHP ecosystem and Drupal like the Drupal application itself really becomes this wrapper around all of these other independent services does that make sense? Any other questions? It's just a form in that case commerce is doing it because they're doing the addresses yeah because that is our terrible problem because every country has their own format and they should be working in hardware so they have done a service for addresses that they are dependent so other PHP project can use these addresses as a service and they don't That's a really great example the people working on the commerce module wrote this really complex PHP library to handle address verification and that kind of stuff This is a problem that wasn't well solved in PHP in general yet and so they wrote the code in such a way that the library of code that they wrote could be used by anyone else that's writing a PHP application that needs to address verification but it was originally written to be used as a for the Drupal commerce system by creating it as an independent library and then implementing it as a service inside of Drupal they're able to keep those components kind of separate from one another and in theory you could write up you know I guess you could write a WordPress plugin that uses that code library as well Did you have a question? I'm just wondering if you could elaborate a bit more on the mechanics of switching one service from another Yeah so the question is like if you've got multiple services like say you've got a Postgres and a MySQL service how do you switch between one or another that's it happens based on it's tricky but it's like it's configuration within your application can determine which service is ultimately used so for in one easy example would be the mail handling system so the thing that sends emails in Drupal is implemented as a service and you could add another service for sending emails and then the Drupal core doesn't have this but what you would need to do is provide some way to specify which of the two services that are available it should use. There's not a UI for doing this but in the code you can say when the service container is compiled link to I don't know the SMTP mail service instead of the built in postfix one. Does that make sense? Yeah this is it's not something I've actually had to do myself so I don't know exactly the mechanics of it but it basically boils down to you need to get your service registered with Drupal so you create your services.yaml file and then at run time or really at the time that the service container is compiled there are checks to see hey there are two things basically like what is the service of the two named services for mail what's the one that I should use what's the one that I should use right now yeah sorry that's a tough one for me to answer having not had to implement that specifically if you take a look at the documentation for this actually boils down more to the dependency injection side of it too because you've got multiple services what ends up happening is you inject your service as a dependency into some controller and at run time what you need to do is say use a different service as the dependency in this case does that make sense cool awesome we're out of time so thanks lunchtime now