There are more seats up here. You guys come up here quick before I start. All right, I think we're a quarter after. So thank you everyone for coming this afternoon. I'm going to talk about Drupal 8. Where did the code go? This is a story about converting info hooks to plugins between Drupal 7 and Drupal 8. This is kind of the outline of what's in the talk. So I'm going to give you just a tiny bit of background about Drupal 8. Hopefully everyone knows enough that this won't be overwhelming in terms of the Drupal 8 terminology. I spent quite a bit of time talking about plugins, plugin system, plugin managers. Do a little back and forth comparison between Drupal 7 and Drupal 8 in a few different places. So in particular, I'm going to show you a conversion of an info hook in Drupal 7 to a plugin in Drupal 8 and show you that the code is really one to one. There's not different code in Drupal 7 and Drupal 8. It's just located in a different place in a different file. Then I'm going to talk about how you would use the plugin system in Drupal 8, which of course means writing your own custom module. So I'll show you a really easy example you'd probably do. One of the first things to the module, add some tabs to a page, local tasks. So there was a way you did that in Drupal 7 involving hook menu in Drupal 8 that's done through a plugin. Then talk about a couple more, slightly more complicated plugins, but not much more complicated. Custom block and a custom text filter to show you how you could implement those. And a custom module and wrap up with some considerations. If your module basically wants to provide an API, wants to provide a plugin type, just a few thoughts on best practices around that. So this is me, a bunch of facts about me. Hopefully you believe that I know what I'm talking about. In particular, I did help in Drupal 8 create several of the plugin types, including at least one I'll be talking about today. So converted the search plugins from hook search info and help break apart hook menu in Drupal 7 into Drupal 8. So we have menu link, menu local tasks, local action, and contextual link plugins. Also do Drupal organizing, and I'm on the Drupal security team. So important Drupal 8 terminology. So these are things that you'll be a little lost with because I'll keep talking about them during the rest of this talk if you don't know what they mean. So the first thing you'll need to know about is the dependency injection container. You'll sometimes see that called the DIC, you'll sometimes see it called the container, the service container. These are all referring to the same thing. This is just an object that gives you other objects. And the objects it gives you are services. And those are basically stateless utilities that the current Drupal request is going to use. They may be things like the current logged in user, the current request, the URL generator that generates a path from a route. And it can also be the plugin managers. And I'll come back to that later. You also need to know about the new routing system. So Drupal 8 basically adopted at least sort of the facade of the symphony routing system, though actually a lot of the code was ported also from Drupal 7 because the symphony system doesn't handle the scale of Drupal routes that we needed. So the key difference is that you refer to a route, which is basically a page that Drupal is going to render by a unique machine name. So it's a route name. And the path is no longer actually unique. So more than one route can refer to the same path. And that's sort of an edge case, but can be really useful if you want to do something like have different routes sort of get requests and post requests to the same path. You could do that in Drupal 8. You couldn't do that in Drupal 7. So a route name is just a machine name. It links to information like the path to callbacks, provide the content, the title, the access checks. So this is just like a menu router in Drupal 7 where you had the page callback. You had the access callback. You had the title element, all these things. Again, conceptually, Drupal 8 is not that different. It's just we put these things in a different place and we're using a slightly different notation to define them.  And this has been a feature since PHP 5.3. And then what it looks like is at the bottom there where Drupal search plugin block, search block, is the name of the class. So the class name is that whole thing, but those backslashes basically give you logical separations in the namespace of the class. And you can see how it kind of builds up from starting from Drupal, the name of the module, and then the type of the class, and finally the class name. Okay, so this talk is about plugins. And to give you a really formal definition, plugins encapsulate some reusable functionality in a class implementing one or more specific interfaces. And all those things are really important to wrap your head around. So Drupal 8, we're using classes. The code is going into class files. And these classes have to implement interfaces. And this is actually one of the really important features of Drupal 8 that because we're implementing interfaces, we can change the implementation of almost anything in Drupal 8 core. Because as long as your version implements the right interface, you can substitute it for the version that comes with Drupal core or that comes with one of the modules. So this use of interfaces, the fact that we're using interfaces to decide what to do rather than specific concrete classes is really important in Drupal 8. So plugins in Drupal 7 and Drupal 8 are basically a combination of things that we had in Drupal 7, but they were a little bit spread out. So in Drupal 7, we had info hooks and then we had implementation hooks. So this is not too common to have implemented, but if you've ever implemented hook search info, a hook search info was just a return and array of data. And that array of data gave you some things like the title of the page or something. And but Drupal core search module knew that if you implemented hook search info, you must also somewhere be implementing hook search execute because you wouldn't have implemented the info hook unless you also provided the execute hook to implement the search, right? But there was really those two things might not be grouped together, they might not be in the same file. And Drupal actually didn't have a good way to enforce that you implemented the execute hook if you implemented the info hook. Similarly, probably most people here have written a implementation of hook block info. If you've written a Drupal 7 module, that's one of the first things someone has to do, make a custom block, put something in it, put a widget in it, right? So if you implement hook block info, it returns an array, or the array is just a list of blocks your module provides. You also had to implement hook block view and possibly hook block configure and hook block save, right? So again, you see this coupling of an info hook that gives you metadata, gives you the list of the things with an implementation hook that actually provides the code that returns the content that's gonna be printed to the page. So plugins in Drupal 8 basically wrap those things together in one logical unit. So it's the functionality combined together and that interface is kind of like that hook system where we know the naming of the methods that we're gonna call to make it work. So Drupal 8 plugins evolved from C tools and views plugins in Drupal 7. So if you've used those, a lot of the concepts apply to Drupal 8, but the discovery mechanisms which I'll talk about in this talk are quite different in Drupal 8 than what we used in Drupal 7. So every plugin type has a plugin manager. So the plugin manager is a service that's in that service container. So Drupal provides you ways in your modules, in your code, if you want to get a service to just grab it basically using a machine name, the service, you have to figure out what the right machine name is for the plugin manager you care about and then you could get plugins. Usually you're not gonna be directly doing this unless it's the plugin type that your module defines. Usually this just happens behind the scenes for you. But the plugin manager is that service. You basically give it a plugin ID and it will create a class instance using that plugin ID and maybe some configuration values. So each plugin has an ID and you'll see plugins that have the ID in their definition, they're just a static string. They also can be generated as derivatives and derivatives, the IDs might look like something like a combination of a static string and a UUID. So there's multiple, different versions of the same plugin with unique IDs generated from one base plugin. For a given plugin ID, that's always gonna map to one class. So there should be one to one mapping between plugin ID and the class implementing it. But a little tricky to get your head around is that you can actually have more than one instance of the same plugin with the same plugin ID. And that notion of instance is a combination of the plugin ID, the class instance and configuration values. And those configuration values almost always in Drupalator coming from a configuration entity. I'll come back and talk more about those later, but again, just trying to introduce these concepts. So plugin instance, I instantiated class. It's a plugin ID that maps to a particular name of a class and then I feed it some configuration values that can come from config entity and that gives me the instance that's gonna do one specific thing that I want. So, do people know the saying? Dree has kind of referred to it in his keynote. Also, if you went to that, the drop is always moving, which is the Drupal philosophy that we're gonna break code compatibility between versions, right, but allow you to migrate your code forward. But part of my goal of this talk is for you to leave feeling a little more comfortable with Drupal 8, especially if you're a Drupal 7 developer, so that you understand that Drupal hasn't actually changed that much. It's that the code moved, right? So what you need to kind of figure out is Drupal 7 developer, if you're looking at Drupal 8, where did the code go? Yeah, where do I find it? How do I understand how this new system works? But most of the Drupal concepts, the way Drupal works, are still fundamentally the same as it were in Drupal 7. The code is just a different place. We brought in some libraries, but it's still Drupal. If you haven't ever seen that philosophy, there's a link to the handbook page where it's quoted in depth. Okay, so to give you some of that comfort level about the comparison between Drupal 7 and Drupal 8, we're gonna look at hook image toolkits. Now this is kind of a red herring because it doesn't have the name info in it, but this is an info hook. So all hook image toolkits gives you is basically a data array back. And you can see that data array there. The top level key of the data array is GD because this is the GD image tool kit. Then we have a title key and a value that's a translated string. And then we have an available key and that's dynamically set to true or false based on whether the GD function is available. Right, straightforward. So let's look at how that works in Drupal 8. So Drupal 8, the image toolkits are plugins and the data describing the plugin, the definition of the plugin, comes from an annotation. And annotations are these specially formatted code comments you see at the top of the class file. And they, even though they're encapsulated in the code comment, they're actually parsed out and turned into an array and can have default values filled in and have validation. So you have to get the formatting of these annotations correct. And you can see here we have an image tool kit annotation. The ID of the plugin is GD. That's exactly the same as the array, top level array key in Drupal 7. So you see we basically have mapping one to one in Drupal 7 to Drupal 8 here. The title, which is marked as being translatable, is exactly the same string, translatable string we had in Drupal 7 in the info hook. And you see that this class has an isAvailable method and uses basically the same strategy checking if one of the GD image functions available to say that this plugin is available. So again, conceptually the code is working the same way. We've just moved, the info hook is now basically, that metadata is this annotation at the top of the class. And then the more dynamic part is the class method. And then of course I mentioned managers before, so the image tool kit manager is the one that actually uses this annotation to find the plugins. All that gets back from that annotation parsing is just a data array. So essentially the same thing as the info hook. And then it iterates over them and excludes all the ones where the isAvailable method returns false. So we end up here with basically the same thing in Drupal 7 and Drupal 8. We have a data array of available image tool kits and we flagged or removed the ones that aren't available. We can go in a little more depth and again show the parallelism between Drupal 7 and Drupal 8. So Drupal 7, if we wanted to operate on an image, we called image desaturate. Then that delegates to the image tool kit for the desaturate operation. You see here we're passing through the image object. In comparison in Drupal 8, the image object itself implements the desaturate method. So we just kind of reverse that a little. So now images are real proper objects that have methods on them. And in Drupal 7, it was just a standard class object, something really boring that didn't have methods. But it's still the same strategy here. You see that we're calling just a desaturate option. It's just a string key that lets us call back then to the image tool kit and ask the image tool kit to run the desaturate option. So again, the parallelism is there more or less one to one between Drupal 7 and Drupal 8. It's just that this code is moved from a function in an occlude file to being in a class, the image class. And finally, just to look even deeper at this operation, desaturate option, take it all the way to the bottom. In Drupal 7, all we did was take a bunch of strings, concatenate them together, and hope that function existed, right? And you guys know how this works. So we take image, we take gd, we take tchass, desaturate, concatenate them together, ask if that function exists, if it does, we call it. And you see that this then, as long as the built-in image filter function exists, we just run image filter on the image object and give you the result. Drupal 8 is very similar. We actually have here another level of plugins. So each operation is itself a plugin, so you could substitute the implementation of one of these operations if for some reason it didn't work on your server. But again, the code in this method executing desaturate is exactly the same as the code in Drupal 7. You can see we're checking exactly if the function exists, image filter. If it doesn't exist, we log an error and we return false. If it does, we call image filter on the image. That's it. So again, we have very much a one-to-one parallelism between Drupal 7 and Drupal 8, but you have to know where that code went to find it and see that clear parallelism in the functionality. Okay, so you may be thinking, all right, well, Drupal 7, I always worried a lot about hooks. Do hooks still matter in Drupal 8? And the answer is, of course, yes, because it is still Drupal. And even if we wanted to, we didn't have time to remove every possible hook from Drupal 8. And in fact, I think there may be, in some cases, more hooks in Drupal 8 than there were in Drupal 7, at least more possible hooks, because every one of these plugin managers implements an alter hook. So this is one of your strategies if you want to, as I said, you could replace something using a different class for the same interface. So implementing these alter hooks in your module is one of the easy ways to do that. So you can go ahead, for example, in hook block alter, and we'll talk about blocks more later, but in hook block alter, the plugin manager is basically just getting an array of all the blocks that are available in the system. And in your module, you could actually say, I'm gonna replace the class implementing a block with a class that I prefer. We'll look more in detail with those, but again, so alter hooks are still very important. Those could be in your module. Other hooks that look like info hooks tend to be gone, but they did not become plugins. So if you think about a hook that only returned a data array, like hook permissions. So hook permissions, there's no functions. There's no permission functions, like search execute. Instead, there's just an array of data. And so what happened in Drupal 8, that actually became a YAML file. So do people know the YAML format? Mostly some. So, I mean YAML, I'll show you a bunch of examples of it's a very pretty straightforward format to write by hand, it's related to the JSON format. But basically what happened in Drupal 8 is a lot of these hooks, like hook permissions, they just returned an array of data. We decided that it was even easier, not even to have it in PHP, just put it in a file, because that's a lot easier to keep track of. And then that file could just basically be parsed into a data array, because that's all the hook did. There are of course other hooks, like hook cron, hook entity access, that we didn't have any replacement for, so if you need to implement those, you'll still do them in your module. Okay, so I've alluded to plug-in discovery a couple times, and told you already a couple times that plug-in discovery, the thing you get back from the process is just a data array. So fundamentally, plug-in discovery is pretty much like invoking an info hook, except it's a little bit different, and your module can implement, can provide as many plugins as it wants, but it would have only implemented the info hook once. So there's a little bit of difference there. You can actually implement plug-in discovery as an info hook, if you really are attached to hooks, that's still possible in Drupal 8, though I don't think core does it anywhere except in tests. And again, discovery is a process, just think of it as an abstract plot process. The plug-in manager says, I'm gonna discover the plugins. The end result of that process is it gets a data array back. That's a list of plugins and plug-in definitions. The discovery process then fills in defaults, things like the provider, which is like which module provided that class plugin. And discovery again can make derivatives, so many from one. And I saw people looking a little confused when I first talked about derivatives, so I'm gonna give you a concrete example here, but then not talk anymore about them. But a concrete example so you can wrap your head around when you might want a derivative is the field UI local task. So field UI, so the thing that puts fields on entities wants to put a tab on every bundle of every entity type. So a bundle is like a node type and earlier versions of Drupal. And so field UI can't know in advance every bundle of every entity type because you might create a new entity type any day. So it instead wants to make derivative. So we will ask the entity system, tell me about every entity type and tell me about every bundle for every entity type. I'm gonna make a derivative, which is basically the tab that will appear corresponding to that entity and bundle. So that's an example when you might want derivatives where you have sort of a dynamic thing like entities and bundles that you might get more or less of and you want to have a plugin that corresponds to each one of those. So in Drupal Core, we primarily use two strategies for plugin discovery. So that's YAML-based and annotation-based. So the YAML-based, as I told you, YAML files are very popular in Drupal 8. And this is really just these four plugin types use YAML-based discovery. And those use YAML-based discovery because they're almost all used in the same class. And I'll show you a little bit more about that. Then there's a few that use annotation like I showed you for the image toolkit. So in that example, the annotation, that specially formatted comment at the beginning of the class is parsed and turned into that data array. And then there's a lot, a lot of plugins in Drupal 8. They use a combination of annotation and a configuration entity to make that specific plugin instance. And there's a huge, huge number of them in the views module, of course, because this sort of evolved from views. Also the block module, image effects, search plugins. So the majority of plugins in Drupal 8 core are using this strategy of annotation and then together with some configuration to make a specific instance of the plugin. And finally, the entity system. So if you go and pull open the node class in Drupal 8, you'll see it's got a lot of annotation. But it's sort of not a pure plugin. It's, it does a lot of other things. So don't, if you wanna understand the plugin system, don't try to start at the entity system, please. It's very complicated, it's doing a lot of extra things. So pick one of these simpler plugin systems if you wanna try to understand how to build your own or understand how it works. Okay, so let's start learning the Drupal 8 plugin toolkit. And the only way, of course, we can define plugins is to define a module. So as in Drupal 7, in Drupal 8, all your custom code basically is gonna be in a custom module. You need a module and in Drupal 8, instead of a .info file, you're gonna have a .info.yaml file. But it really, the content is almost identical to a .info file. You can mechanically translate it if you need to. What's kind of cool about Drupal 8 is you don't even need a .module file at all. So if you just create this .info.yaml file in a directory in the right place, you go to your modules page, you can see that you can enable the module.  And that's pretty cool. But again, most of the code in Drupal 8 lives in class files. So really the expectation is this, .yaml file tells Drupal you can enable the module and then once the module is enabled, Drupal adds your module to the list of places it will look for PHP classes. And that's why you don't need the module file at all. So here's the example, the full path, if you wanna create this. And the code I'm showing is all in a sandbox. So you can pull that down from Drupal.org if you wanna play with it yourself. So the full path in Drupal 8, you can put custom modules in the modules directory. That's another fun new thing. And core modules are all under the core directory. So they're separated out. And so that thing where you always told people not to put modules in the modules directory, now you have to change that for Drupal 8. But it's the thing they wanna do anyway, so it's okay. But you create modules mymodule.info.yaml, again, name, type, description, core compatibility, the same things you would've done basically. Type is module or theme or profile. So there's a little extra metadata in there since they all use the same info.yaml format. And then I wanna create two tabs. And I can do this more or less without adding much code to my module. So I'm gonna add two tabs. And these use the yaml discovery, so I just need to write the simple text format to add two tabs to the page. Yeah, so I need to name this file. So the discovery is based on naming of the file, mymodule, links.tas.yaml. The top level key is the plugin ID. So that's gotta be unique, so you should probably use your module name in it as you would with a hook or anything else, an earlier versions of Drupal. Then you see I have a route name, a title, and a base route. I'll come back to the route name part of it. And the base route is basically a grouping. So what this says, I'm creating two tabs. I'm gonna give them different routes, different titles, but I'm gonna group them together. They're gonna be grouped around this base route, which is the same as the route the first module uses and the route the plugin uses and the route the plugin uses basically just defines the link. So that's, yeah, when you click on the tab, that's where it's gonna go.  Okay, so this is what that looks like. Turn it on, you can see that there's, the default tab is on the right. The list one, and that's the default tab because the base route and the route name were the same. So already things are easy in Drupal 8. You don't have to define a default local task. All that silliness is all gone. You just define the ones you want. It's automatically the default if it's on the same route as the route that is the group. And then you see on the left side, we have the second tab also appearing there. And a trick here is that because we're using machine names for routes, I'm no longer tied to any hierarchy of paths in the URL. So I can group together any set of administrator pages I want to regardless of the path that's assigned to them. You see the one on the right says admin config mymodule list, the one on the left, admin config also mymodule settings. That's not something you could have done in Drupal 7, in Drupal 8, you're completely free. And you see the page content, here is something custom and it's just printing out name of a class and a method. So I did kind of trick you guys, sorry, I skipped ahead and made the tabs before I made the routes. So you do obviously need routes. There's route names that it's referring to have to exist in advance. And you could have, I could have used a routes that already existed in Drupal Core, but it was easy to make custom ones. And the routing files, the default is also YAML. Again, I told you YAML was really important in Drupal 8. So if you don't like reading YAML, learn to love it. The top level key here is the route name. So these are not plugins, these are routing definitions, but they look quite similar. The routing definition format is actually borrowed from symphony. So you can look at the symphony documentation and you'll see that most of these keys are defined in the symphony documentation as well as in the Drupal documentation in terms of what they do generically. Drupal of course has some Drupalisms in here, not so much in this example, but in other examples in Core. This is a very simple example. So we're defining a path for the routes. Obviously that's how it gets rendered, went as a link. The controller is very much like the page callback in Drupal 7. These controllers are just methods on a class, they return a render array. That render array just has the name of the class.  You can look at the example code on how to get a bother showing it to you. And then title and then access checks here. They're just setting access to true. You can set access based on permissions as you did in Drupal 7 or any kind of custom access check that you want to apply to your routes. So these are in mymodule, mymodule.routing.yaml. That's how we define routes. So local task plugins need a route. That's why we bother to do that. So now we've got our routes, we've got some tabs going, what else can we do? So we might want to think about what else can we define in those local task plugin definitions, right? So and where do you find the documentation? How do you know what's a valid key? In this case, you look at the manager. So the local task manager for these different YAML discovery plugins is the place that we put the documentation and all of the default values. And you can see that the route name, the title, the base route are all among the keys mentioned here. And with empty default values because you should really provide something. The other thing in here is a parent ID. So you can have hierarchical tabs in Drupal 8, the way you did in Drupal 7 visually. But the mechanism is different here. You basically use this parent ID to say, I want to be a child of some other plugin when it gets rendered. So we tried to simplify this, make it a little more logically clear how to group these things together. And again, these are totally decoupled from the paths that those tabs link to. So you're no longer tied at all to any strict hierarchy of paths among the tabs that you group together. And finally, you'll see that there's a class key. And this class, if you want to create a custom tab, so imagine you want a tab that renders the current user's name on the tab as opposed to just a static string from the title. So you would have to provide your own class that implemented the right interface and the right methods and render the current user's name instead of a static string. But most people don't want to do that. Most people when they're defining tabs are happy to leave it as a static string. And that's why we have this system make it as easy as possible for developers to get started and add some tabs to their administrative interface. Okay, so on to blocks. So I think you'll love the new block. It's great. So blocks as plugins in Drupal 8. Every custom block is defined in code as a separate class. When you, as the Drupal administrator, go into the interface, and I'll show the screenshots of this, and you place a block in a region in a theme. There's a configuration object, a configuration entity, created the track set setting. So there's basically a class corresponding to a plugin ID and a configuration object. And those two things together define that block instance.  And that's just an abstraction on top of Drupal 8's configuration management system. So configuration management is about the ability to import, export, and look at your Drupal configuration as YAML files. So again, YAML. Very important in Drupal 8. The fact that it's an entity means it actually implements some of the same interfaces as things like nodes. So now your Drupal configuration can be listed and loaded in the same way you can list and load things like nodes. In fact, you can make a view of the active blocks on your site. I don't know why you do that, but you can because it uses the same interface and you can actually make a view of these things. In the example I'll show you, you'll see that I don't actually worry about it at all about this configuration. The default classes that Drupal Core provides handle, creating, saving these configuration entities, and I don't have to worry about it. So only if you have custom configuration associated with your block, you need to sort of delve in to adding a form and adding those settings to the block configuration. Okay, so we're gonna implement a custom block. So we have to implement the block plugin interface. All blocks have to implement that, but we can make it really easy on ourselves and there's a block-based class in Drupal Core. And if we implement that, as you'll see, all I have to do is implement one method in that class, the build method, which is the same as hook block view, essentially, and all it does is return a render array. Everyone knows how to do that, right? Right, you can method, you return a render array, you get something rendered. Really easy. So in this example module I added Drupal in my module plugin block my block as the class. So how many people here know about PSR4? Not even half, okay, so. So there's a reason why we're using these namespace classes a lot, and that is because when I write that class name, that class has to live at a particular place in the file system in order to work, at least with the autoloader standing standard that Drupal 8 is using. So the Drupal my module plugin block my block class has to be in a file under modules, my module SRC plugin block my block dot PHP. And if you look at that class name with the backslashes, and you look at the file path with the forward slashes, you'll see that there's more or less of one-to-one correspondence, especially in the last three sections. And then of course we're under my module, every class my module provides has that, and then we're under Drupal, of course, who's a part of the Drupal installation. So this one-to-one mapping between a class name and an actual PHP file on disk is how the PSR4 autoloader's autoloading standard allows Drupal to find and load these class files by name without you having to tell Drupal in advance about the classes. So you might remember Drupal 7, you had to say this file has a class in it, right? In the .info file or the autoloader wouldn't find it. In Drupal 8, all you have to do is name your classes correctly, put them in the correct file location, and they're automatically loaded. So that's what PSR4 is, it's just again, that's why there's these strict rules about where you place your classes and how you name them. Okay, so this is the block plugin, it's really easy. So this again has an annotation, it has an block annotation. The idea of the plugin is my module, my block, it has administrative label, the administrative label is translatable, and as I said, all I have to do is implement the build method. The build method, all it has to do is return on a render array. This is a pretty easy render array, I'm using actually the same two routes I defined earlier. In the render array, and I'm using a new render type in Drupal 8, type link, but you can see how it works pretty obviously. Link has a title and it has a URL. URL is an object that encapsulates the route name, route parameters, route options, kind of like a call to URL function in Drupal 7, but this object basically encapsulates these things and then can be rendered later into a URL. And that's it, so we got two links. Return those from the build method. Obviously, if I create this file, I'll have to clear some caches in Drupal so the discovery process runs and finds the block. And now we can go and create an instance of the block, have it appear on the site. If you haven't used the Drupal 8 blocks admin, there's a new thing there, and you may be a little perplexed when you first go, because you won't see any blocks, except the ones that are already active. And instead, you see in each region this button that says place block, right? And place block, if you click it, will actually take you to a list of all possible blocks that Drupal knows about, and you can filter that by name, so here I filtered it down with my module block, click place block again, and then you get a configuration page that looks a lot more like the Drupal 7 interface, right? So now you can say which content type should appear on pages, roles, region, things you know from the block system. But this, under the covers, what's happening is if I click save here, I'm creating a block plugin instance. So I'm creating a configuration object that says there is an active plugin with this plugin ID configured for this theme, for this region. And that's how Drupal will be able to find it later and create that plugin instance and show it on the site. So I save this, save the blocks page, go back to my home page, and voila, you see, we've got now a block, custom block provided by my module, with two links to the customer outs I provided. And that's all we need to do, that one little build method basically inside the annotated class. So to give you again a little more sense of the mapping, Drupal 7, Drupal 8, there's pretty much again a one to one correspondence of these things, a hook block info, talked about it a couple times, the block manager is the one that uses the annotations in the block classes. They get parsed into basically the info array and they come back from the definitions list from the block manager. Generally you won't actually be doing that call directly, but when you have an annotation, it basically participates in that process. Hook block view maps one to one to the block plugin build method. And the one thing that's different there is you see in Drupal 7, you always had to worry about deltas. So you remember deltas and each delta was essentially a separate block. In Drupal 8, each delta, each separate block is a separate class. So Drupal 8, you don't have any intermixing between the code for different blocks. Each block, independent block is represented by a separate class and all the logic related to that one block is all together in that one class file. So that's actually one of the things I think is really great about Drupal 8 that it makes it much more clear when you're reading a set of code. If you're looking at one class file, you know that everything you're looking at relates to that one block and there's no intermixing with other blocks or other functionality going on. At Drupal 7, didn't actually have a good way to control access to blocks. I don't know if anyone's run into this. You basically had to hack the view method. Instead, Drupal 8 has an access method on those block plugins. So if you want to control access very specifically to your block, you can. You get an account object which represents essentially the user trying to view the block. You can call permission checks. You can do whatever you want to return an access result there. And then in Drupal 7, we had hook block configure and hook block save. And these were actually kind of weird. I don't know if people remember the annoyance of dealing with these. They don't really follow the pattern of the form API. So you get the delta again because you have to know which block you're dealing with. And then hook block configure doesn't take a form or form state and hook block save takes an edit array and again not a form or a form state. So you had to, every time I had to do this, I'd dive in the documentation, try to remember what these things actually were and what the edit array was and how to handle it correctly. What's nice in Drupal 8 is it's much more standardized in terms of form API. So we now have a form builder function, block form, a validate function, block validate, submit function, block submit. You know how that works. Drupal 8, the form is still an array. The form state is actually an object with methods on it and you can do interesting things like set your form errors on the form state object. But again, the pattern, it looks very much like Drupal 7. We basically moved things from these Drupal 7 block hooks into the methods for the specific block that's carrying out those actions in Drupal 8. So if any of you were paying close attention, you might also be wondering how does this discovery thing and annotations work? Like how did Drupal find those annotations and parse them and know that this was a block and not some other kind of plugin? So the way that works is really a combination of two things. So the first is the namespace. And again, the namespace also determines where on the disk you have to save that file. So the namespace for a block plugin has to follow this pattern where it's under Drupal and the module name and then backslash plugin, backslash block. Have to do that. You can't use any other namespace because that's part of how Drupal finds those plugins. Similarly, I mentioned a block annotation. So the block class has to have a block annotation or Drupal will not accept it as a block plugin. It's kind of makes sense, but again, this is how that works. So the plugin manager calls some other code that basically looks through those class files, says is it in the right place to be a block plugin? And if it is, is it using the right annotation? And if it is, okay, I'll parse it and give it back to the manager as one of the things that discovered. So the annotation class, so this at block notation actually references an annotation class and I'll show you what that looks like in that. Like the local task manager was where we had to stick the documentation for local tasks, but in most of these plugins, the documentation for the definitions is in this annotation class. And that basically shows you the possible keys and values of the block of the plugin definition and also fills in default values. There's a generic plugin annotation class, but if you're writing your own plugin, you're gonna want to extend that. And this is what it looks like. The annotation class is really simple. They basically don't have any methods. They just have some properties and default values for the properties. And here you can see these are the two things we listed in the block annotation. We listed the ID and we listed the admin label. The admin label itself, you can see here is actually a separate annotation that at block or at translation tells the annotation parser. This is an annotation class. So there's also annotations for things that are translatable. This is how Drupal's integrating with this plugin system with the internationalization system. People may have gone to talks about how great Drupal aids internationalization and translation system is. So we had to think hard, for all these different subsystems, how do we indicate which strings can be translated or not? And so for plugins, this at translation annotation is the way you do it. So that's it. This block plugin annotation documents all the things that can go in that annotation at the top of your block class file. All right, so wrapping up towards our last example, filtering text. So in Drupal 7, if you use the Drupal Outer Org issue queue, you put, hopefully you guys know the trick, if you put a issue number in brackets with a hash in front of it, it's actually rendered as a link to the issue with color coding. You guys know that? No, you should know that trick, it's great. So that filter is provided by the project issue module on Drupal.org. And here's the info hook. And you can see it gives you a title, a description, a process callback, and a tips callback. Those are the things I'll focus on. So basically, just again, tells you how to display it in the admin UI, the title and description, and then what functions to call to process the text or get a list of filter tips. So we can do, basically, I'm gonna implement, re-implement the same thing in Drupal 8, but much more simply. So it's, we'll work for any node type, not just for issues. I won't have any color coding, it's just gonna be really simple. So I'm gonna create a filter plugin, give it an ID labeled with my module, translatable title, and then there's, again, a base class. So the same way we had block base, we have filter base. So Drupal 8 is full of these base classes and they make your life easier as a developer because if you extend those, everything you need, except maybe one or two key methods is already implemented. So you can basically get a shortcut to working code and then you can iterate and add more customizations if you need to. Here are the two, only two things that really need you to implement were the process and tips methods, which are exactly the same things as the process callback and tips callback in Drupal 7. Again, you can see if you had a text filter in Drupal 7, I had a process callback and tips callback, you basically just copy that code, move it into class file in the process method and the tips method in Drupal 8. That's where the code would have gone. I sort of shortened this code but basically there's a regular expression, looks for that pattern of a node in brackets with a hash, uses an anonymous function to process each of those, basically load the node and render a link to the node and then we wrap the result in a filter process result which is an object that just carries cacheability metadata. So the Drupal 7 info hook had some cache info in Drupal 8, we're actually gonna put the cacheability info on this filter process result. And then we have a tips method that returns just again a tip about how to use this text filter and that's pretty much all I need. Again, you can look at the code, create a node, first test post and then I go to the admin page and enable this text filter, so I'm gonna configure the basic HTML text format that's one that comes built into Drupal 8. I'm also gonna disable a CK editor there so you can see the text tips more easily. This string that was in the annotation now appears in the admin interface as an option I can check off. So I just check that off. Go to node two, I edit my second node and I basically wanna put a reference to the first node. All I have to do is put this bracket hash one, that's gonna look for node one, load it, render the title and you can see that the filter tip from the tips callback is now appearing underneath the text area.  If I save that, you see it works. I get the rendered first node title. If I hover over it, you can see in the bottom left, I get a link back to that first node. So, sort of moving to the last topic we was gonna talk about is creating your own plugins and just a couple suggestions for best practices. These are things most people don't need to worry about. This is really gonna be the case if your Drupal 7 module provided an info hook. So your module called module invoke all something info and then looked for implementation hooks. Or if you had, for example, a Ctools plugin type, so you defined your own Ctools plugin type. These are not common things people did in Drupal 7, but if you did, you're gonna probably wanna convert them to these new plugins in Drupal 8. I would say as the best practice, use this annotation discovery by default, the things I've been showing you where you put those annotations at the top of the class file. The reason for that is it keeps the metadata basically the info about that plugin together with the actual implementation of the plugin in the class. So you've got everything all together in one file. It makes it really great to sort of copy and paste things, start from one of those and make a new one. Also makes it easy to find that information when you're reading the code. That YAML discovery I showed you for local tasks is sort of an edge case. So we've done it for the menu things in Drupal 8 to make them plugins to give you a lot of flexibility, but most developers are not gonna put a custom class there. They just wanna use the default class. So only if your module had a case like that where the 99% use case is the same class and 1% which is gonna substitute it. You might use this YAML discovery, but that's really uncommon. So think about using this annotation system if you need to define your own plugins. Okay, so some resources if you wanna learn more. Again, the slides are already posted. You can download them, get these links, all the code I showed you is in a sandbox in Drupal.org. I tested it recently, it all works for the current version of Drupal. Converting 7x to 8x modules, there are handbook pages on the process of doing that. They go in quite a lot of depth. So if you have this as a task ahead of you, I would look at that handbook page. There's also a handbook page on the plugin API. So if you wanna know about the plugin API, go and take a look at that. And another handbook page, it actually has a good back and forth discussion so it actually kept the comments. There should have been a long discussion. If you're interested in the philosophical reasons why we have plugins and use this system, look at that page. If you're just gonna use them, you don't need to read it. And then DrupalizeMe had a nice blog post on this whole system also. Has some nice pictures and diagrams about how it works. So just to wrap up, and so you kinda leave with a few things in your mind. Maybe if you haven't started using Drupal 8 yet and you're excited to use Drupal 8, here's a few good reasons to be excited. So widespread use of interfaces. So class interfaces means I can replace the implementation as long as it uses the same interface. The Drupal 8, the plugability, your ability to customize Drupal 8 is massively beyond what Drupal 7 provided. So most people don't kinda realize that just looking at the code.  You do need to pay attention to these route names if you're converting your module, please do try to convert your code to use the route name instead of the path. And some of the interesting features that gives you again that multiple routes can serve the same path and can serve different kinds of content or different HTTP verbs. You saw that all over Drupal 8 we're using YAML files instead of those custom things like any format we used to use for info and that even a lot of hooks like hook permission were converted to YAML files as a pure data. And also Drupal's configuration. Configuration, essentially most of the things that were variables in Drupal 7 are exportable as configuration, exportable as YAML files. So you can version those, you can track those, you can actually deploy them between different versions of your site. And finally, each block instance has a corresponding config entity and I didn't show this but one of the great features about Drupal 8 is you can create as many instances as you want of the same block. So if you ever hit the frustration with Drupal 7 core that you wanted the same block to appear on a different set of pages in a different region, you couldn't do it in Drupal 7 unless maybe you used panels or used views and made two copies of the block or something, you kind of had to hack around that. Drupal 8, you can have as many instances of the same block as you want, you can configure them differently, put them in different regions, give them different rules. So it lets you really get a lot more value out of that one plugin by reusing it over and over again to make different instances. So that's kind of it for the talks. Let me just sum up. Again, plugins combine the discovery process. I'll let you find the plugins together in often the same file, that one class file with the implementation of it. In that maps back from Drupal 7 and info hook in those implementation hooks, that's sort of the same purpose. So in your head, think about, okay, if I had that in Drupal 7, that's now a plugin in Drupal 8. If you're gonna define your own plugins, please start with annotation as what you define them. Again, so it keeps everything in that one file, makes it easy for people to find. So that's all I have. I hope that was informative. We have time for questions. So if you have questions, I'd be happy to take them. There's a mic over here for questions. If you can go over there, that would be great. Thanks. Thank you for a great presentation. First question I have, you had an example of the plugin manager you were getting, you were iterating through the result of get definitions and that returns back an array of the definitions and you were accessing those by using the array elements themselves and the array keys. Is that a best practice or is it a better practice when you get each one of those definitions to create an instance of the plugin and access it through the defined getters? I think you mentioned permissions. I was talking about the slide that you had it was near the beginning. Okay. So if you were talking about one of your plugin managers, you called your example called get definitions and iterating through the array of definitions. And I'm wondering if it's best practice to do that and access those plugin definitions via the array keys or to just create an instance of each plugin and use the defined getters. Okay, so in this case, so this is inside the managers. The manager really has to know about the guts of the plugin and this particular call to get available tool kits just wants the list. So it's really would be premature to create the instances at that point because there may be some significant overhead of instantiating a bunch of services or doing something to create the instance. So in this manager, I mean, this is a little bit of one-off most plugins don't have the sort of filtering method. You just get the list of definitions back and then use them to list the available plugins. But so the manager, and then the manager will take a plugin ID, will get the specific definition and then create one specific instance from the definition and a configuration it needs. Second question, a lot of the configurable entities have methods for building lists that build it out as a table of available plugins. Is there a way to short change that to build a select list of available plugin names? Is there? I would suspect there is, but I don't know it off the top of my head. Thank you. Yep. Kind of curious, I've never seen comments have like system critical functionality in them before. Why have the annotations and comments like that instead of being a static function that returns an array in the class or something like that? So it's a good question. So the reason we ended up using annotations, and this is actually not that uncommon. So if you look at other languages like Java and we adapted this as a PHP standard library. So this is used by Symphony, this is used by a lot of other actually PHP projects. But the fundamental technical reason we did that is because once you load a class into memory in PHP, you can't unload it. So if you want to iterate over all the classes basically on the whole file system in Drupal install, you would end up with every one of those classes in memory and you would probably have PHP run out of memory. So the fact that it's an annotation allows us to basically just parse that leading comment as text. So we're not actually loading the class file, we're just parsing the text out of that. And that constrains the amount of memory we use in this process. So that's the technical reason, but it's actually, it's not something we've ever done in Drupal before, but it's not actually that uncommon in other projects and languages. Thank you. You're welcome. Is this thing on? Anyway. If it's on, it's sort of barely on, yeah. Okay. For your controllers. For the controllers, yep. You're pointing to a function. Yes. And it looked like it was called statically. That was actually, it was named in the static style but it was not called statically. Right, so does that assume that you're working within a class, it doesn't require a constructor? What's going on behind the scenes if that class method requires a constructor to have been wrong? So there's a bunch of different ways to specify your controllers in, I have to look. So a lot of Drupal 8 classes actually have essentially a static create method. And that create method then gets a copy of the service container and is able to pull out the dependencies it needs for the constructor. So you can basically have a strategy of saying, well, I'll just give you the class name and the class has basically a static factory itself. And then the factory uses the service container to populate the values it needs for its constructor. So that's how that ends up working in most of Drupal 8. So that you don't have, the other way that that can work is you can actually define your controller as a service in the service container. And in the service definition, you describe what dependencies it has on other services and those are passed into the constructor. So there's basically two different ways you can do it. There's, I think a couple more, but. The code doesn't rely on that mind as a static method. No, no, it's a instance method, yep. Thank you. You're welcome. Okay, any other questions? Not, thank you all for coming. I hope that was informative. Thank you.


e new video are either of you familiar with the youtuber doughnut operator yeah i am i've seen him on twitter i don't know much else what do you know about doughnut operator rags it's like a police kind of guy reviews police footage a lot of the times things like that arrests and criminal stuff since hollywood i like him since hollywood is dropping the ball on movies i thought there would be a rise of internet interest in independent movies separated from film festival garbage or maybe everyone just moved to youtube and streaming shows i don't think anyone's gonna hate mainstream movies so much that they'll never watch mainstream movies again because you never know it's always like a roll of the dice every time that we're like oh will this one be good hope it will we hope it will there's nothing standing in their way technically they could bring out a good movie like lord of the rings is mainstream fucking amazing looks like the normally you'd think that obviously the professionals would be really good at what they do let's like when you go to when you compare an nfl professional football game to like you know like a little league game or a bunch of children playing the game obviously the professionals will be really good at it but when you talk about film man the professionals are do a really shit job so much a breakfast now i returned good morning everyone good morning yeah morning the longer the efap the greater the tism bilbas my name is hitori bochi my favorite food is natto on rice i prefer my natto finely crushed save the mustard that comes with it so it's not wasted okay that's fair enough yeah that's fair enough man i don't know what any of that meant but it seems like you got a plan a man with a plan or that daddy very happy not sure if that's referencing something or if it's a strange super either way just a strange super chart hello you too i'm a trans woman here even though i have the perfect profile to be an sjw i think the sequel are terrible keep up the good content i love it thank you we shall do it we will make sure that the good content flows like beer in a place where beer flows a lot yes it will continue to flow like the spice when i heard you guys went starting until six here i joked about prepping for efap to end at 2am it's almost three expectations subverted i didn't know you guys were starving late as you did well yeah i uh it was because of them being australian uh we were originally gonna have just fringy and then i uh i asked if shad was available because i thought you'd be interested in the um angle and then i was like wait if we've got two of the australian then we're gonna be in prime time to have a third well other australian i was like we can try robot head the triple threat but yeah we can't necessarily run an efap at normal time and have australian guests because it's like the worst time ever for them at that point you know they're terrible people is what i'm trying to say you're on prison time they only they only get so many so many hours out in the yard different after eight hours i just don't have the stamina to keep efapping mauler and rags this is for both of you as thanks for watching tlj i found you both while looking for the answer to why keep up the great content thank you very much you're back glad you found what you were looking for i suppose i think that's the implication aid all the welts rags did you ever get your monthly thrust i'm still waiting on mine also hi mauler hello i don't believe i got my monthly thrust and i'm a very disappointed doggo going to bed thanks for the stream stay based raw well you got a fan right mauler thoughts on attack on titan and it's exceptionally good writing i've not watched it i'm afraid it looks neat really either thoughts on finn declaring he's rebels come in lj i didn't understand because i thought they were the resistance they don't need like they they swap between saying rebels and resistance a couple of times yeah they're kind of interchangeable but you just let's because they're just trying to exactly recreate the rebels so yeah i attempted to explain to a friend who thinks tlj is good that you can measure that using you can measure that using objectivity claims it's a pointless exercise since when whatever standard we use wouldn't be his some are too far gone also hi rags hello and yeah like you don't want to there are some relationships that are not worth going into the philosophical side of how you judge art if you don't want to you can just leave it alone like and plus he doesn't have to agree to the standard question can rags play akbar's theme i think we all know the answer to that also hi mauler hello in the e you i g88 was programmed with super advanced ai and almost led a droid rebellion uploaded himself into the second death star and conquered the galaxy really i had no idea okay when did that happen uh the only thing in chenobyl i'd call bad were certain conversations that felt goofy in episode two the scene in the helicopter felt like the dark night rises i like the helicopter scene you talking about the woman i like that scene he explains how a nuclear reactor works i don't know again that wasn't that wasn't just for the guy on the helicopter i thought it was kind of clever that was for june and plus it shows like it shows a lot about the character of um i forget his name uh but basically the um the assistant yeah the politician guy it says a lot about you know how he tackles problems mm-hmm oh yeah i thought he was great in that show stelin scarce oh i really liked it you know he's um he's he's wilton his dad in the parts the carabin film oh it's been so long since i've seen those movies yeah i didn't even think about it uh if you had the choice to either fix season eight of game of thrones or fix the sequel trilogy um ensuring great quality which would you pick like probably star wars i i know it's it's honestly a tough choice but the reason i'm kind of aiming almost partially altruistic here in the i know it would mean more to the world if if star wars was what we wanted it to be the the the continuation of the ot imagine like a perfect new trilogy that made people get nuts and we still always got the books for game of thrones at least yeah they're coming out right one day would you rather make out with a predator or an alien predator the predator seems to it seems like it that's that's what it's for i don't know just saying i mean yeah predator i mean plus the alien with the second mouth and everything is just plus i'm totally into to strong babes you know i'm the one who criticizes shadow vistas verbosity and i get that you like him and want to give him free reign to say whatever but i think there's a line he crosses your audience is more interested in hearing you and rags go on at length southpaw has the same problem be aware you're a guest um i don't i don't know that i would agree with that the uh when when shad comes on i'd say that a vast majority of the audience seem to be very invested in his takes as i think is fair because he's very informed on a lot of the subjects yeah i think that people i like i like listen into what i say i mean he's not like a bad guest normally when he talks about stuff there's a point to it or he's trying to express an idea of some kind and he's certainly not wasting air time yeah like being genuine now i actually don't feel like he over spoke really at all even um i think he even did a couple times like when oh you know you go first sort of thing with some people um i think i think he gets the etiquette honestly that's that's just my take yeah i wouldn't have even thought about it uh holy shit you guys are still going i should expect nothing less from the long man and the great doggo also hi rags hello oh yeah we going we're going and going this crazy train i got no breaks did disney copyright the last efap they did and uh they've monetized it which is fine because they allowed it to be viewed uh worldwide which is all i wanted they blocked it at first this is the funny thing the two strikes that hit on it said that we monetize it and we block it i was like okay like what if what you give the monetized parts pretty point you played yourself and they will uh once you appeal it they're like okay fine it's available but we monetize it and it's funny because it's like nine hours or whatever and they're monetizing literally like a 10 second straight part and it's like yeah you guys you really need that ad sense right there the whole thing belongs to you because of that moment and it's a meme video that's the funny part like it's literally a fucking parody mashup it's got nothing to do whatever it's fine and it's and the other funny part by the way is that it's about end game we were defending that film in that stream go ahead go ahead disney take it take it away take you take your fucking money uh great show guys hope you like the site overhaul oh yeah that's uh that's kibbutkins again efab.me is uh ad updates again look wanky most impressive the um is a section for uh people we've covered now and uh they've got how many videos we've covered and which efabs they were covered in the amount of statistics developing on efab.me is like statistics you didn't even know you wanted you got them so swanky um if i tweet you a video of my doggo will you play it on efab for the cuteness um we prefer i mean if it was a youtube video and it was short i'd consider it in the meme section i'd consider it but the thing is if i ever actually agreed to this fully then i could start getting spammed with videos like that so thinking about it i'd probably say no because i don't have to kill like a tidal wave it's not like efap meme related uh greetings from the russian essay community my long man's you two not speaking my language helps me sleep without fear oh all right yeah wow this has gone long hi rags hello rags king of the massives hello king of the masses that is true though you two watched hardcore henry if so thoughts i have not i haven't watched it no rewatch lord the rings cries so much at the end 15 minutes no it's quite the nicer resolution epilogue always gets me always gets me i meant finn says he's rebel scum yeah yeah yeah i uh he says it uh after he's beaten down phasma right um because she says what does she say you're like something rebel that he's like rebel scum i can't even remember the context that he walks my brain is melting and i haven't seen tlj now in possibly over a year or nearly a year i haven't seen it in ages so long it feels weird actually like yeah we talked about it so much but we haven't seen it in so long um but yeah it's it's a cringe line this is a fucking cringe dialogue throughout uh your mama um rags bedtime was like three hours ago howdy from tx yeah it was right yeah tx is texas and it was that long ago um how much are you guys thinking of charging dale for that therapy session seems you walked him through a lot of issues dr mauler and nurse rags i uh i don't know if we've we would have changed his mind on anything he seemed to be against himself already to begin with right like that i think that if responded to that video if he went into another call with some other people who are arguing things from us i think he would have had the exact same stuff to say i think he would have just kind of subtly folded in a different direction i probably wasn't um i don't think it was like like a huge moment for him coming on here and having to be like uh yeah i'm gonna have to deal with these things that i said that that while ago i guess the the highlight for me was just the lm like you would never say this thing right he was like no other than like oh i did it happens um and yeah that was uh the last super chest i just got a couple of me real quick all right only reviewing a movie about space wizards for children oh yeah this uh i was made aware this is a stretch goal or uh oh well i guess a goal on patreon i think for patrick willams where once he'd reached a goal he's gonna have his parents see avengers end game like that was patreon goal i thought that was really strange that is an odd one like okay whatever float you boat that's and we got this you are from upside down land well from my point of view you're upside down land well then you are lost yes then may at least the honey mustard a few more updated wizard takes of course milk wizard and the geode wizard this is gonna be a whole family of wizards he's not really cute these drawings are really cute yeah they are they got loads of character yeah i really like him the fucking carton of milk with a rhino on it it's like that's that's like the symbol the dog whistle of efab you're like that's efab right right oh that if you hate star wars you just hate yourself ismond freudian mentor of big ideas like his eyes if you hate star wars you just hate yourself that's the same like oh yeah definitely that you've solved it i just hate myself in the beginning is just the prelude to the extended middle freudian the elder freudian uh and yeah don't panic there are obviously more memes from today i don't think i've gotten to every one of them from different sources the annoying thing for me now is they don't just come through twitter and i'm trying to keep care of everything um but we'll we'll try and maybe do a meme section next ish time guest five just said it's only the middle it's it is technically but now i'm gonna bring it in to the end um thank you all for watching this 10 hour efab for some reason the efabs keep going really long now and we didn't even cover the other video that was set to be today and i thought it was gonna be a short efab because of that you say that you say that every time and it just never it never is but like where is that it seems like that's gonna be that i didn't think that we would have so much to talk about with this guy's video i didn't think that was gonna happen i thought he was oh it blew my mind but oh mawler you and you and your thoughts i am a naive man your efabs are only an attempt to disguise the fact that you hate yourself i'm so scary uh no everyone donate to keep read it out and so yes thank you all for watching thank you very much for the kind donations the wonderful memes and artwork and the um well first of course wonderful guests and for the respective moments and times the links are all in description for the things we talked about today in the different channels and um really say both you dumb boes need to watch hardcore henry i'll probably watch it one day i'm sure i'm sure the next 24 hour efab will be an accident i don't think we'll ever accidentally do a 24 hour i think that i think i think at one point during a potential accidental 24 hour efab will oh fuck i need to i need to like maintain bodily functions survival is kicking in i need to do other things i need to eat drink sleep because i i seriously do have to sleep like i've been i was away out of town when i woke up this morning and i we drove back and once i got home i was expecting to come into an efab midway in the middle but no no no i was it was the middle the entire thing oh yeah we're all it's always the middle uh i'm doing my part are you i'm getting married today hi rags oh hello sorry to hear that but don't worry it'll all turn out okay yes um and yeah with that thank you for watching everybody this will be live on moola as soon as it can be and we will see you next week uh tulip cheerio bye


So people today I bring you this amazing cheese for the 100 EAZ minibus kill so that rare renewed sources of heroes armor which will allow you to do this super fast people within a single run taking away the ridiculous tedious process of having to keep while flying backwards and forwards into the EAZ looking for these minibuses and getting them down. How's it going guys my name's DP Jen I'd like to thank you for stopping by and checking out my video if you do enjoy it leaving a like really helps out and if you are new around here and enjoy daily destiny videos be sure to subscribe okay so a cheese has been found people which allows you to get your 100 minibus kills within a single run we've gotten a minibus kill literally every 40 seconds which in comparison to some people doing this well it's basically taking them all day is a massive difference now if you've already done this and already have that legendary sources gear on one character keep this in mind for your second or third character if you do plan on doing them so this is done in a team of three which is important and lowered into the EAZ the one you are looking for is the Kabul one but there are two different Kabul versions where the bosses differ you need a certain one to do this and the one you are looking for is the one with the three Kabul bosses who have those sticky turrets those sticky rocket turrets on their back the other one I believe they have gatling guns if you get the one where they have gatling guns that's the wrong one and you will have to continue searching you need the unbowed legion bosses so once you get the correct version which you won't actually know until you get to the boss stage anyway if you do land a Kabul one if the right bosses appear you'll get three of these massive Kabul dudes with those sticky rocket turrets on their back what you need to do is kill two of them leaving a third alive probably start with killing the one at the center if he does spawn there but just make sure you leave at least one alive you need there to be one alive for this to actually work in doing this people a mini bus spawns in with the message on the screen of an engineer has arrived to support the kaba he does spawn in with the three buses are alive it's just if you have one bus alive it makes things way easier on yourselves not getting attacked by three big dudes so leave one bus alive this mini bus will keep spawning in literally every 40 seconds he'll drop down from the ship at the center of the map so just wait around at the center and just keep killing him over and over and this will allow you to get this crap done in no time at all people so I do hope it helps you out if you're on this stage on that note guys we have come to the end of the video if you guys enjoyed it leave a like really helps out if you're new around here and enjoy daily destiny 2 videos be sure to subscribe and if you never want to miss a video I upload you can turn notifications on by hitting that bell bottom but guys thanks as always for stopping by hopefully you enjoyed the video and hopefully I will see you on that next one


Sometimes I wonder what I'm going to do when there ain't no cure for this one. Hello everybody. Welcome, welcome. You're going to be gaming and talking books today.  I'm just going to hang out with you guys and play some games and chat about books. Update everybody. My favorite holiday. Baseball opening day. I'm doing pretty good. I can close off. I'm going to write for a bit while I watch Hell's Year. So I finished my DLC prep on the Xbox. Now I have to do it on everyone. Everybody, whatcha reading? Whatcha doing? Whatcha been up to? Whatcha listening to? All that good stuff. Come on in and chat. Dude, not wanting to continue. Why did I want to continue? But look at this absolute pimp. Look at this absolute pimp. Look at him. Never mind the camel toe. Look at this absolute pimp. Look at him. Now say goodbye. Are you going to work on the Unplugged 2? JB? Let me move the mic closer. You're going to work on Unplugged 2? Whatcha been to work on? Can y'all hear the game? Can y'all hear me? I know you can hear me. Can y'all hear the game? Everything good? Playing Prince of Persia on Switch. I only have the demo because you can't afford the game. But I love it so much. Come on. You're at 133 pages for Uptube? Yeah, I remember you telling me that. Yup, that's when I'm more cool. Alright, let's go to a new game. What are we going to call this playthrough? Let's see here. We want to go with the Samurai, because I'm going to try an overpowered build. And if you know anything about this game, you know the Samurai is the best starting class in the game. Let's go. You know Yabra aged. You know him aged. Keepsake. Always go with the golden seed. If you're bad at games like me. Alright. What's up Derek? Where you at right now? You're on the road. Are you at home? You ever at home? I don't even know where you live. I talk about... I know... Is the game live? Y'all is the game live. What am I going to do? I heard an absolutely diabolical mashup. Little Jon snap your fingers. With Alan Jackson's Ain't no cure for the summertime blues. But it worked way too well. Is what I'm saying. It worked way too well.  What's the longest you've stopped working on a story before going back to it? Twenty years. And that's not even exaggeration. Twenty years.  I want to get to a... I want to get considerably deep into it. That's what he said. Good, going good, going good. Excuse me, sir. Have you heard about our lord and savior, Jesus Christo?  Okay. There you go.  Asking because I stopped working on a fantasy novel. To focus on Unplugged 2. But I like the idea. I think... Never go into anything with that mindset, JB.  And that's okay. Because all we can do in this game is get better. That's all we can do in this game. This game of life is get better. It's the thuggish, thuggish boner. It's the thuggish, thuggish boner. Hi, come here, Rick. I'm about to get parried into Oblivion Cut. Okay, okay.  One or the other. There you go. Get that in your belly meat. Yeah, that's what I'm talking about. Are you not dead, Rick? Okay, you are dead.  I know it's my dream to write a fantasy novel, so I'm stoked. But I'm sure it needs a lot of work. And it'll just be alright. And that's fine. That is absolutely fine, brother. Like, your books are going to be bad. They're going to be. You want to know why? Because you're getting better. The book before is always going to be worse than the book you're working on now. It's always going to be, whether it be the writing, the storytelling, no matter what it is, it's going to be worse.   You know what I mean? You got to keep that in mind when you're working on these stories. That, you know, if it's not, if the new stuff is not better than the old stuff, if you don't hate your old stuff, you're doing something wrong, because you're doing something wrong. You got to keep that in mind set. I'd be like, the next story is going to be even bigger and better and better and everything. Everything. That's how me know it's okay to be better than you were yesterday. Without Guy, you are fake. Lucky me. Are you for me? You may all start trying new things and up to.  Yeah, it's going to. It's going to. And if it doesn't, like I said, man, you got, you're doing something wrong. If you see. Call me Maidenless. One more time, buddy. Call me Maidenless. One more again. Just one more again. You're swallowing crops. Oh. I need the contents of your skull. Thank you very much. Hey, move cow. Get dead. Yo, what's up bookable? How you doing? What you reading? What you working on now? Bookable in the house. The homey bookable. I'm doing. I'm doing great today. Just here to hang out with my peeps. Play some games and talk about books. Are we going to have a good day? It's technically my day off. I ain't got to go nowhere.  Been working on my first book and currently reading different seasons. Awesome. What are you writing? You know, I got to know.  You can't do it. Come on, Carly. Tell me about yourself. I don't need all this dialogue. I just like all the dialogue. All right. Purchase.  We're going to grab this. And we're going to grab. We don't need the torch. We don't need that. We are going to need some of this other stuff, but we'll come back. Hey, Brian, what's up, doc? Goodbye. Goodbye. And yes, I'm playing Elden Ring again. But remember. Remember. This ain't about gaming. This is about hanging out with y'all. This ain't about the fidget games. I got to go get my horsey. You did. Here comes the crazed butt-stabber. Y'all ready for the crazed butt-stabber? It's a fun game to watch. It's a fun game to play. So whenever I feel like just hanging out and chilling, it's the way to go. The plot is still in progress, but like what genre? You don't have to tell me about the book, of course. But what genre are you playing in? This is also, since I know this game like the back of my hand, it's also a really good game to not pay attention to. The crazed butt-stabber!  I'm sorry, little homey, ferret-looking thing. I'm just wondering, what I'm gonna do with this rainbow-cured roo-roo-roo-roo-roo-roo-roo-roo-roo. Why is chat not showing up on screen? I feel like this is a bad thing. Yeah, a new character.


The scene of the crime is presented by Billy Johnson Jr. Attorney at Ball. This week, on the scene of the crime, we take another look at the case of Larry Hinkle, who was killed in T. Berry in Floyd County earlier this summer. On Saturday, July 1, 2017, at approximately 10 p.m., Mr. Larry Hinkle, who was 60 years of age from the T. Berry area of Floyd County, was walking on the shoulder of a Kentucky 9-7-9. Shortly after 10 p.m. with some point, an unidentified vehicle struck Mr. Hinkle and he sustained fatal injuries. At this point, the vehicle and the operator remained unidentified. Now nearly four months after the hit-and-run, Larry Hinkle's son Jody says the family is still seeking answers. They've recently started a Facebook group called Justice for Larry Hinkle and a fundraiser to raise money to pay for a private investigator. It's been four months, but a car's been missing or been put up.  When Jody and I created the Facebook page probably about three months ago, it was to generate a place for people to send in tips and information that they've heard about throughout the neighborhood of Mud Creek and T. Berry that could be in contact with us. The first little bit we did have some momentum.  I've basically been keeping it up just so that the people that are guilty in this see that we're still looking and we're not stopping. If you or anyone you know has any information about the case of Larry Hinkle, please contact Kentucky State Police at the number on your screen. Reporting in Pikeville, I'm Polly Hopkins for EKB News.


We're here at ITU Telecom World 2013 in Bangkok, Thailand, and I'm very pleased to be joined by Mr. Reza Jafari, who is Chairman and CEO of eDevelopment International, and he's also a Commissioner for the Broadband Commission for Digital Development. Mr. Jafari, thank you very much, Dave, for being with us today. Thank you for having me, Max. I'd like to start off by talking about this year's events theme, which is embracing change in a digital world. And I'd like to ask you, where do you see the biggest opportunities in that change for the industry, for society, and what are the biggest challenges? Well, the biggest challenge and the opportunity almost at the same time is the fact that while we are transforming our own industry, the ICT industry is going through a major transformation, at the same time we are obligated, we are also involved in transforming many other industries and sectors of the society, because the ecosystem of the ICT is enlarging and getting bigger every day, and our contribution to the betterment of the life and the betterment of the society is going to be through our contribution to the ecosystem that is changing almost every day, but we are the engine of the change for that transformation. And can I ask you, how do you suggest that the world embraces the change? In many areas, although embracing the change is an important element for us to move on, in other areas we need to lead the change, and we've been doing it for many years, we've felt behind. First of all, we need to make sure that the access that we've been talking about for many years, it is becoming more and more available. Mobile broadband, mobility and social technology are becoming more and more available to the developed world, but the developing world seems to be still falling behind. We need to make sure that happens. The second dimension of it is the affordability. So access is there, but can they afford it? The second part, of course, the affordability comes in that we need to create the public-private partnerships that I mentioned in such a way that makes the access more affordable. And the third dimension of it is the content and access to local content in such a way that the applications and content are addressing specific needs and demands of our customers. And finally, I'd like to ask you, what in your opinion is the value of attending events such as ITU Telecom World? Well, ITU Telecom World again, and ITU in general, as a mission, the world is becoming more and more complex. Our industry is trying to make that complexity to be simple and simplify that complexity for our end user and our customer. At the same time, ITU and organizations like ITU, international organizations, as well as professional associations like GSMA, we all have a role and responsibility of making that transition from a complex world to our customers to make it simple. So any time that they choose a device, any time they choose the connectivity, it becomes secondary to them when they're using it for applications and content that seem to be the closest thing that they wanted to do. Reza Jafari, thank you very much indeed. Thank you for having me. Thank you.


Fermentation comes from a Latin word, purveyor, that means to boil. So the word fermentation refers to the physical state of boiling. Fermentation can be defined as the metabolic process of converting carbohydrates to alcohol or organic acids using microorganisms under anaerobic conditions. There are three types of fermentation on the basis of water content in the medium. First is solid state fermentation. Second, submerged fermentation. And the third one is surface fermentation. In this practical, we will demonstrate the production of enzyme alpha amylase by solid state fermentation. So what is a solid state fermentation? In solid state fermentation, the microorganisms grow on a moist solid surface with little free water or no water. But some of the capillary water may be present. The example of solid state fermentation is soya sauce, temp, bread making, etc. Solid state fermentation is also known as Koji fermentation. The materials required for solid state fermentation are the 250 ml Allen-Mare flask that is commonly known as a conical flask, a graduated cylinder, 1.5 milligram of zinc sulphate, 1.7 milligram of iron sulphate and 0.2 milligram of copper sulphate dissolved in 250 ml of distilled water. We have to add 10 gram of wheat bran to a conical flask. Away bought onto the balanced pan. Temperature?