We'll be talking about Drupal 8 plug-in system. People here, how many have actually worked in Drupal 8? Like, dabbled with the code, and maybe updated their modules. Awesome. So hopefully a lot of this will be familiar with you, and I'll be exposing some internal information that might help you out. And if not, maybe it'll be too much information, and you'll confuse a lot of it. Like, this is so awkward. I have to lean forward. I'll do my best. Cool. So this is me. I'm Hellyer. You guys haven't met me before. I have been working in Drupal for maybe about five or six years. I currently work at MEC Universal. And my handler is pretty easy at Hellyer, at most social media sites in Drupal as well. I haven't actually contributed anything meaningful to Drupal 8. I just kind of dabbled in it maybe a couple of months ago. And am I finding those some pretty cool stuff to share with you. But it is fairly technical, I guess, just by its nature. Plugins are itself just PHP classes. And so there's a lot of dry, technical information involved in that. So just a fair bit of warning. When I prepared these slides, I had in mind that everyone here is very nerdy and can handle a lot of the PHP talk. So if anything, that is the disclaimer here. And the prerequisite that hopefully you guys understand at least the basics of object-oriented PHP and PHP 5. So yeah, just dropped in a quick overview so you guys know what to expect here. I'll explain what plugins are at least in the scope of Drupal 8. And I'll talk about why it's so important to discuss the conversation of why creating plugins as opposed to just creating custom hooks or just going to town with whatever kind of mechanism. Why it's all important and what the benefits are. And also, I'll drop in and talk about some critical Drupal 8 concepts that are in itself requirements to understand the plugin system. A quick preview to that is I'll be talking about PSR4, annotations, service containers, and dependency injection. And after we get through with that, I'll do a quick little demo of what it is to actually write some plugins. And I'll dabble in with a few different plugin systems and show you some other concepts that are baked into what it is to define plugins and then create derivations of them, et cetera, et cetera. And then the most important part. Well, if you don't intend on creating your own plugin system, maybe you can drop off at that point after step 4. But step 5 here in this case is going to be talking about the internals of the plugin system, how it actually works internally, what are the classes that are used to bake together the discoverability of plugins, what we're using to map certain instances to this or that, and how to basically set up your own thing from the ground up. And I'll do another demo of creating your own plugin type. Now, I think with creating plugin types, you see a lot of them in Drupal. And they're usually wrapped around user interfaces. And those are baked in with configuration entities. And it's very similar to config bags and then also just having plugins on the side. So it's kind of confusing. The lines are pretty thin. So I try my best to avoid talking about configuration entities, because they will get confusing. And they're basically a talk within themselves. But I'll create a plugin type. And it's going to be basically headless. And you'll see a few lines of code there of how to define your plugin type, where to discover other plugins that are implemented, and then how to actually use it. But the business logic that you decided to do with them, I guess the business logic system itself, that would be an exercise for you guys to do on your end. So moving on, what is a plugin? The way I define plugins, at least within the scope of Drupal 8, is a discrete class that executes an operation within the context of a given scope as a means to extend Drupal's functionality. So we think of extending Drupal's functionality in many ways with, hey, I'm going to invoke a hook, or I'm going to implement a hook. Sorry. Sorry. So yeah, a plugin is a discrete class that executes an operation within the context of a given scope. When I say within a given scope, there's always the evils of within Drupal. There's anything you can do in almost any place. And that can have some confusion with developers that are not really sure with where to put in their code. So oftentimes, you put in some crazy stuff inside of hook and it, or a hook page build, or whatnot. But the idea with the plugin is that it kind of enforces the best practice of only doing a thing within a small scope, maybe within a method. And you're only given a certain amount of parameters to work with. And if there's anything else that's outside of that, a global, for instance, you might start to feel a little uncomfortable with doing that, because now you're pulling in objects out of thin air, and you start to feel kind of a strange, cringy feeling. But within plugins, just the whole good behavior here or the best practice is that you have a limited scope and limited to what you can actually do. And moving on to that, plugins themselves, they should really only do one thing and do it well. Kind of like a UNIX philosophy where you have one utility that just does this one operation, gets a simple input, sends out a simple output, and that's it. And it sends it out to the next thing that does its job really well. You should kind of treat plugins in such a way as well, where you're not trying to achieve too much within some sort of an implementation, or you have all your logic within a method as if it was a controller that has a lot of application specific stuff. Plugin should be abstracted. Plugin should be something that can take in configuration and then do stuff with it, but not too much. And then also, I mean, since you can pass in plugins, so you can pass in configurations within plugins, you have this idea of every instance could have different config. It could have different states. And regardless of what the states are, the plugin can handle the operations within them. And so you have a sense of reusability. And you can have a single class that you've created, a single plugin. And you reuse it across different places on a site, or even better, reuse it across different sites within all of your projects. Because you're just passing in different configurations to do things with it. Yeah. I'm kind of a visual guy. So I like to see what plugins are, at least in a practical sense, where you've seen them. So I'll show you a few screenshots of a Drupal 8 interface to kind of get you familiar with what plugins are and how you could identify them. And keep in mind those three principles about plugins, that they're instantiable, configurable, reusable. They do one thing, one thing well, and that they're limited within scope. So here you see the blocks UI, where everything on the right well is essentially an instance of a plugin, search forum, user login. Each one of these are implementing a block type, or just a block in itself. In Drupal 8, you can configure these and instantiate them. It's not like Drupal 7 where you can only use one block per region. You can pull these in and add state to them, basically adding configurations to it. And they're very narrow in scope. You're not supposed to have content within a single block. Another example of plugins are field types themselves. Field types prior to Drupal 8 were implemented by several different hooks, but still conceptually, it's supposed to be a single thing. You're describing a schema, validation, et cetera, et cetera. And each one of these plugins or field types can be used across different sites. It's not like it's application specific. Likewise, with field widgets and field formatters, actions themselves. So take for account a limited scope. Each one of these actions are supposed to be expecting just a single user or just a single node. It's only supposed to operate one single thing. So again, it's small in scope. It does one thing and one thing well, and can be used across different projects. And here we have image effects, also implemented as plugins. Input filters. They process text, and they do a very specific thing. And they pass it on to the next input filter. And this is kind of similar to input formats. However, input formats are configuration bags, configuration entity, which basically houses all the configuration that you would pass into input filters. So that itself is kind of like a container. But the input filter itself is the plugin in which it uses to process some text. And now in Drupal 8, we have a CKE Editor, or CKE Editor buttons. So each one of those are implemented as plugins. And entity types, et cetera, et cetera. So you see that plugins are everywhere. And if you can see this with your binoculars, you can see that there's a lot of plugins in Drupal 8. And you have a little bubble off into the top left. Those are actually view plugins. So since they're baked in as classes, your plugin types can be extended and build other sub-plugin types with them. So you'd be familiar with all the different views plugins that are available. That's essentially it. And almost everything here that you see in Drupal 8 interfaces are baked in as plugins. And you might be thinking to yourself, all this seems really, really familiar to me. And rightly so. A lot of these in the past have been implemented before with some sort of an info hook, whatever info. But now essentially that has been deprecated for the most part in Drupal 8. And we have different means of discovering these different instances, discovering these different plugins. And that's all things to the plugin system. So yeah. So before we move on to the actual how to create plugins, I'll basically talk about the benefits of them. One thing I really like about Drupal 8 is that the definition of a plugin and the implementation are all baked in together.  And all these different procedural functions describe this one thing. And it gets kind of hairy. And it's a little more difficult to work with, especially if you're providing more blocks within those hooks. Because then you have to do switch cases, and it gets pretty ugly. But in Drupal 8, since every plugin is defined as a class, we can use actually annotations to describe and declare what each one of our plugin types do without having to have a mess of code all over the place. So I'll talk more about annotations than why they're so cool. Secondly, plugins are lazy loaded. And this is one thing I never really liked is that if I had to do some sort of operation or needed to have some globally accessible service or whatnot, I would have to include it inside of the module file. And that made me feel uncomfortable because that's a lot of PHP code that gets cached in and has to get loaded up. But as far as Drupal 8 is concerned, your plugins won't exist. They'll know about them as far as where the definitions are and where to find it, but won't actually load the code until it actually uses it.  And the more plugins you add in, there's no performance costs at all because they're just dormant in your code, which is really cool. And also code is unified. I mentioned already the hook block info and hook block, whatever. Fields were also a huge pain in that sense whenever you wanted to create a field type or a field widget or a field formatter, you'd have to write seven or eight different plugins to describe just this one thing. And again, if your module provided multiple types of these, you'd have to mess with cases, switch cases, and so that gets kind of hairy as well. But in this case, all the code is unified inside PHP class methods. So you don't have that separation and you don't have to do weird stuff to pass in state across all of these different methods or all these different hooks that you would apply. And just by the fact that plugins are implemented as classes, you get the object oriented aspect of it where all your plugins are extendable. I like some of the widgets and the field types that are provided by Drupal Core. But it's really difficult to say, I like this image type or this image widget, but I would like to add just one little thing to it. It's not a thing to just extend it and apply your own button to it or apply an extra validation to it. You literally have to re-implement the entire field type or re-implement the entire widget and pass in all the different validation and all the different hooks, and it's just god-awful. But with Drupal 8, you could extend that class and just provide in your own extra things with it and still get the benefit of all the existing validation and all the existing formatters that exist for it. So there's a big one there with the reusability. Because of course, they are classes. And also because they're PHP classes, we can now leverage interfaces where we can say, hey, this plugin type that's provided is supposed to implement said number of methods and that's a contract essentially. So if you have any kind of plugin that are implementing a plugin type, you can rest assured that they're gonna have the methods that are promised within the interfaces. So there's no guessing of like, hey, does this plugin support this operation? Do I have to check for this if method exists? It's going to be there. So a little bit of developer love there. That's a great thing. And because everything is using similar interfaces, this implies the fact that you can actually swap these classes around because they all, basically provide the same inputs and they give out the same outputs. They have the unified interface. So what's to keep us from actually swapping out these operations? So yeah, plugins are now swappable and you can move them around interchangeably. So that's a great thing. And reusable across different projects. This is very true because of course, all of this logic is baked into plugins and shouldn't necessarily be tied into application logic. You can use them within different sites. It doesn't have application logic baked into them. If anything, you'd be passing in configurations to them. And I feel that the plugin system kind of enforces or encourages that kind of pattern. So kudos to you. But you could have always done this in Drupal 7 and in some cases in Drupal 6 as well using T-Tools. Actually, I was very involved with T-Tools and just its mechanics with having plugins and having classes as ways of implementing these plugins. And of course, if you're careful with the way you're implementing these things, you could always capture these plugin types into your own custom module that can be reused across different sites in your team or even within just different projects and basically passing in the configuration state into these plugins to do different stuff. So moving on, core concepts that are baked into Drupal 8 that are kind of a necessity to understand when we're looking into how to implement these plugins. So we're talking about dependency injection, service containers, annotations, and PSR4. I was in an assumption at first that I had to learn symphony in order to understand Drupal 8. And so I spent some time in there for a while and realized there's a lot of stuff in here that's not necessarily applicable. It's really good stuff to know, but it boils down to really these four concepts that are required. And then everything else just kind of becomes Drupalisms that are using these concepts as helpers. So the first one we'll talk about is PSR4, which is an auto-loading standard. If you're not already familiar with what PSR is, it's a PHP specification request. Essentially, representatives of all the PHP frameworks get together and they discuss what are some patterns that we can use across the board where we can work interoperably and foster these standards. PSR0 was the first auto-loading standard. And up to maybe a week ago, I think Drupal 8 converted at least all the module code into using PSR4. What that is is basically a way for auto-loaders to know where to find your classes. So there has to be some sort of a structure in which everything follows. Part one of this is having a fully qualified namespace. And it should be in the format of your vendor namespace and then a sub namespace and then finally the class name. And secondly, your directory structure is supposed to match at least the sub namespace for this plugin. So given an example, say we have a class called my block and the fully qualified namespace for this is Drupal my module, plugin block my block. And within this class name, it's just called my block, but it's encapsulated within the namespace of Drupal my module, plugin block. Previously in the Drupal 7 and below, we had to prefix all of our classes and all of our modules with the module name. And that worked out pretty well. It prevented namespace clashes, but this is a much more elegant way of achieving the same thing. So given this class, how can the auto-loader find it? It depends on where you put it. So here would be the directory structure that's baked into it. Within your modules directory here, my module exists. And you have a source directory. And in there, that's where the sub namespace is kind of mapped with the directory structure there. So we have plugin, block, and finally, myblock.php. There's different variants of this, and of course there's a lot more explanation to this. I have a couple links at the bottom for phpfig.org. And you can see all the different PSRs. That's specifically this PSR4, which describes it. And more germane to Drupal actually is another link that talks about how Drupal uses it. All the pros and cons, and possibly links to other issues where there's a lot of drama and why we should or shouldn't use it at all. And also as a reminder, we have Sprint on Friday. So there's a lot of issues in the plugin system, about two pages full. So if you wanna jump in, a follow Drupal Mentoring on Twitter, check out Austin2014.drupal.org slash Sprints and see what you can do to help out. Make this all possible for everyone. Anyway, annotations. So annotations is essentially just metadata inside of doc blocks. And a lot of people call it doc blocks, just multi-line comments. But actually they're not. A regular comment is in a sense a single line comment so you have your double slashes in front. And so that's cool. And that's actually ignored by opt-code cache. And we could also have multi-line comments with the forward slash and the splat. But again, that's still ignored by opt-code cache. But sometime around, I think PHP 5.1, a reflector class had the ability to actually introspect and read its own doc blocks, which is what we have to describe a lot of our functions. And so that kind of opens up the ability to have something that's parsable inside of the doc blocks and pull things in. And you've seen this a lot before, these markers where you have an at symbol. So like at deprecated, at to do, at param, at return. Those are all markers. And now with the PHP 5.1, with the reflector class, we can actually read those in and parse them. And essentially that's what annotations are. Not necessarily code. It is just basically declaring certain values so you're parameterizing your markers. And this is a custom marker, so at my plugin name. And I can pass an arbitrary list of values and keys. And so yeah, the annotations can find that within the code. And this is essentially how a lot of the classes can define themselves. You don't have to have a separate info hook. You can just have that all baked into the comments. So very easy, very simple. There's a very interesting slide deck. Have a link at the bottom on slideshare.net that describes the history of annotations, all the different annotation engines that exist in PHP. And why they're so cool. So yeah, that's it, annotations. Moving on to dependency injection. People describe this as an inversion of control and I really didn't get what that meant for a long time. So here's an example. And this is actually a problem that I struggled with for a while with some of my own previous projects. Say I have a class named sum class. And inside of the constructor, I'm using another class to kind of help me do some stuff. And so inside of the constructor, I initialize a handler. So this handler is a new handler. And so there you go. I instantiate my sum class and then inside of it it does some stuff with this handler. But say for whatever reason, someone else needs to use this sum class and extend it and do some other stuff. And within extending it, they need to modify the handler that's instantiated. But the problem is that this handler is actually instantiated in a lot of different places within this class. And so now in order for them to do a simple extension, they have to look for all the different methods that are instantiating these classes, override those and implement their own or instantiate their own handler. And this gets very frustrating and very difficult to basically manage. The inversion of control here is basically described that the calling user is instead defining what the dependencies are. So in my sum class, if I had written in such way where in the constructor, I'm just accepting the handler object and then I just simply assign it within, then that means that the calling user can just invoke their own or instantiate their own handler and pass that into my sum class. So now who has control? It's not my class anymore, it's the developer. So that's all of what dependency injection is in and out. There's nothing more to it. And there's a link posted at the bottom that kind of describes this with using better examples. But yeah, that's essentially what dependency injection is if this ever confused you. Now you know. Moving on to this though, there's something called service containers. Service containers, they do something pretty cool where they auto instantiate these classes for you, but they have to be service oriented, implying that they don't have states, they don't have configuration baked in. They're just classes that do things and they do things in a global scope. And the thing with service containers is that you can register all the dependent classes within them. So for instance, the example that we had with the handler and the sum class, you would basically set up like this, handler equals new handler, instance equals sum class of whatever passing in the handler into that. But instead of having to provide all the classes that are dependents, because keep in mind, new handler probably had dependencies of its own. And those classes that it depends on probably had dependencies of its own. So you could imagine you would have to instantiate a lot of classes and pass them all in until you could actually have the instance that you want. So the idea here is that within service containers, we can define what those dependencies are. So in my case with the sum class, inside of my module.services.yaml file is where I can basically describe my service. And I'm providing a machine name, mymodule.sumclass, and I'm defining where the class can be found, what the namespace is, and I'm passing in the arguments. And my arguments are pointing to something called at handler, which is the machine name of the dependent service container. And the thing with this is that somewhere out there, there is a handler service that's being described that it will in turn describe its own dependencies. And it's just like daisy chaining across the board. And when I want to instantiate a sum class, all I have to do now is say, Drupal, give me the service, mymodule.sumclass, and it will go ahead and do the instantiation for me. In fact, reading off the services files, Drupal will generate PHP code that has all these instantiators inside of an array. So it's pretty tricky how it does it. It's pretty cool, actually. And there's a link at the bottom, basically talking about Pimple, which is a library of PHP that does the service container stuff, and it kind of talks about how the mechanisms are, like what it's actually doing internally. But yeah, so instead of you having to instantiate all your classes on your own, you can just register them and then call it in at the very end using Drupal.services. And this is okay because defining what classes you're going to depend on isn't necessarily a runtime decision. It's something that you can have baked in and registered. And if you ever had to have the same class but have different dependencies, you can just register another service itself. So yeah, that's how you can instantiate things with service containers. Very cool. So, quick review. Talk about what plugins are, basically what their benefits of using them, and what the use cases are for having the different instances, configurations, and whatnot. Brief through some of the core concepts using Drupal 8, and now it's time for some demos. So we've been looking at some source code. Let me mirror this real quick. Oh, that's cool, awesome. Alrighty, so here I have a demo module called Pilot. And as we mentioned before, per PSR4, we have all of our plugin implementations or all of our classes, so basically the auto-loaders can find them inside of the source directory. You notice inside of the module, I don't have any info hooks at all, and everything is just found within source, plugin directory, and then all the different plugin types that are out there. So, what differentiates a class from a plugin? Essentially, it's a class that's within a certain namespace, and that implements a specific interface. So I'll start off with the image effects plugin type. So this is what's desaturating or resizing your images. And we have something called pixelize. So, first off, it's inside of the directory, source, plugin, image effect, and then my plugin name is called pixelize, so therefore there's my class. It's extending the image effect base, which is implementing configurable image effect interface, which just means that, hey, I have this image effect, but I also have a way of basically defining configurations for it. So that means I can implement stuff like default configuration and get form and validate form, or et cetera, et cetera. What's very important is that I'm defining this class within a certain namespace. Is that large enough, by the way? Uh-huh, it's on GitHub. Postaling to it, in the comments of the talk. So yeah, the namespace is Drupal pilot, so that's the vendor namespace. The sub namespace would be plugin image effect, because that's what the image module defined it to be. For every class that I use, I have to go ahead and say, hey, use this one, so that way I can basically shortcut. So again, I'm assuming PHP experience with you guys. And the info hook that would have been is actually now within an annotation. Sure I have my description, but the most important part is I have an at image effect marker that describes, hey, this is my identifier, this is my ID, pilot pixelize, and this is the label that I want. And we're even using a translation marker that says this string right here is translatable, so pass it through the t function, do your thing. So ID, label, description, bam. And just with this, I should have it available in the UI. Of course, the thing is with the contract that I'm implementing a specific interface, I have to provide the apply effect. And I could have extended something like desaturate or resize and do some additional stuff to it. But this is just extending off the image effect base, which essentially does nothing. In here, I'm just going to be pixelizing an image. And I'm saying, how much do I want to pixelize it by? And do I want to use advanced controls for this pixelization? And here is a quick form API insertation, so we have get form. So that's essentially it. And I will show you what that looks like in the UI. So we have the image style. Let's add a style. Call that blah. Because I have this information inside of the annotation, I should be able to see it here, pixelize. Awesome, so let's add this. Since I am implementing the configurable, what was it, configurable image effect interface, I have the opportunity to add in a form. So say pixel size 40 would be fine. I don't want to use advanced pixelization effects. Go ahead and add it, boom. So that's saved into a config entity. And let's go over to the article display image and say we're going to use that image effect. Blah is in there, go ahead and update that. And then say, and it does some content, some article content. Stuff's adding an image, Super Mario. So this Super Mario image is actually a very realistic rendition of Mario where Yoshi is a dinosaur and Mario's a pudgy fat guy. Let's go ahead and save and publish this and see what it looks like through our pixelization. Hey, it's what we're used to. Pixelize Mario. Pretty cool, huh? And all I had to do is apply effect method, essentially. And this is all contained within a single file. So no hooks elsewhere. It's not cluttering up any of the module file. It's just by fiat, just because it exists inside this name space, it would be picked up. So this is essentially a simple plugin that just does this one thing. However, if you guys are familiar with C-tools, there was an opportunity to create child's plugins. For instance, there was one class or one plugin type that handled all of the blocks. Or there was one plugin type that handled all of the relationships between entities. But it had a mechanism to basically look through everything inside of the schema, find relationships between things, and it can create spawn child plugins based on what it found through some sort of a traversable set of data.  However, it's still using one single class to do all the operation. Injurably, we call that derivations or derivatives. So I have another image effect called Colorize. And this is super simple. Basically just applying a tint based off a list of colors that I had to find prior. So, say for instance, and I'll jump into the module file, here's an array of colors. So I have lime and hot pink. Imagine if this was a configuration that you built yourself, where you can just add another, add another color.  So the thing that defines this plugin from being a derivative is that we have a derivative right here, a parameter, in which we're defining where our class is to do the derivatives itself. And that can be found inside a plugin derivative. And this is what's basically, it's a glorified for each. And for each one of the data that we have stored in the database, or as you can see, I just had it as an array, it's going to derive the annotation data that we would have had inside of each one of these classes and auto-generated for us. And all we're really doing is passing in an ID, a label, and then the color, and going ahead and returning that is here are all my derivatives. And going back to the original plugin, it's just reading that data in through the plugin definition. So my derivative class is providing the values for the plugin definition of all these child plugins. So just with this one class, I'm able to do multiple things. I'll hop back over to the image style blah and add in a colorized to hot pink. So here, again, we have colorized to lime, colorized to hot pink. And this is coming through the derivatives, which is, again, a glorified for each loop. And I'll say, I want this hot pink. And there we have now a hot pink pixelized image. So I'll take styles, come back over here. Now I have a pinkish pixelized Mario. Cool. So jumping into something simpler, something very common, is how to define a block. And many of you have defined blocks before with hook block info, hook block view, and hook block, et cetera, et cetera. This is all the code that's necessary to define a block. And again, following the same patterns. It uses annotations to discover where all these plugins are and what they do. All it needs is an ID, an admin label. And then, again, really just extending the block base and then whatever it is that you're doing, your, I guess, your custom logic, you can just override the methods that are necessary. In this case, in the method build, I'm just providing a little snowman in the markup. And so if we jump into the block layout and say, I'm going to drop the, where is the snowman? There you go. Add in an instance of the snowman. If I had implemented some configuration, I can go ahead and drop that in. I did not. I'll go ahead and save this and put it inside of the contents of the page. So save that, and there's my block. Think I saved, not sure. If I come back over here, boom. We have an indifference snowman on the page now. So very, very easy to implement a block. Cool stuff. So yeah, those are some examples of how you can implement plugins. We did this already. Yes, so now for the even drier section of that. Plug-in system internals. Okay, so if you are a developer who wants you to find some new systems, this would be important to you. Basically everything that is managing a plugin system is a plugin manager. And the responsibilities of this plugin manager are basically it's a twofold. First off, you want to find where all your plugins exist, where all the other modules are providing these plugins and then you want to instantiate them. So essentially the discovery phase and the factory phase. And then there's also an optional phase called the mapper, which would be if for whatever reason at runtime, you don't know what you want to call. So you need some sort of mechanism that says, hey, dynamic data, come here. Let me figure out what you wanna do. And then I can find what class I'm supposed to be instantiating and go ahead and pass that to you. And that is what the mapper does. So first off, the discovery classes that are provided in Drupal for the plugin manager. All it's really implementing is get definition and get definitions. So in a sense, this is finding all of the plugins that exist and it has very different mechanisms to do this. And I'll talk about each one of those. Again, the factory is just, it's a way of instantiating. So the only method that it implements is the create instance where we provide what the plugin ID is and then we can provide a state as well, the configuration. And then the mapper is get instance, whereas I don't know what the instance is. But here's some configuration, here's some options. You figure it out. And then come back to me and give it to the factory so then I could create the instance and go to town with it. So the plugin manager, all encompassing, is really just implementing each one of these interfaces. So now you have to just deal with one class, not necessarily three different classes.  The plugin manager itself doesn't have to re-implements what get definitions means. Instead you can just assign the discovery property within it to a discovery class and just kind of proxy the get definitions itself. So when I say manager get definitions, really what it's doing is calling the discovery class to get the definitions for it and just passing that along. The discovery classes that are available are static discovery, which is, hey, I'm just gonna give you straight up all the different plugins that I want you to have and this is kind of cool for testing. So you don't have to implement plugins, just say here's an array of data, go to town. YAML discovery, which is what you often see with basically every YAML file that is in Drupal. Menu links, menu routers, contextual menus, services themselves, et cetera, et cetera. Those are essentially providing data for plugins and the way the systems will find them is by looking through all the YAML files. And hook discovery, which is what we're all used to, is something hook info. And at this point, I'm not even sure if that's available anymore. Haven't checked. That might have been deprecated, not sure, but hey. But the most common one is the annotation discovery, which is where we put in these annotations baked into our classes and that's what most people are doing and it looks really cool. So maybe that's the method that you wanna try. So what does it look like when you're actually pulling in this data? Inside of the constructor for your plugin manager, you can do this. Say the discovery property, it's going to be an annotated class discovery. How do I find this stuff? Well, the first parameter is here's the sub directory that you should be looking in for the namespace and here's a list of all the namespaces you should be looking at. Essentially this is all the modules that are enabled. And then how do I know which marker I should be looking for? Well, that's where you would have to implement an annotation class and you just specify what the namespace is for that. So Drupal core annotations actions in this case will be looking for anything with an at action marker inside of the dock blocks and assuming it's within a certain namespace, bam, it finds all the plugins. So again, this is what differentiates the standard class as being a standard class or a plugin that can be used. Hook discovery, this is basically invoking a module invoke. So if I'm saying, hey, here are all the modules that exist and I'm invoking element info, it's basically calling out hook element info or looking for everything that implements that. So that's something that you're very familiar with. YAML discovery, this is the file name that you want to look for and again, these are all the modules that are enabled. So look through all those directories and grab all the stuff. And then static directory, static discovery which is again just passing in an array, only really useful for testing. And on top of the existing discovery classes, there's something called decorators which is a lot like alter hooks. We'll jump into each one of these. So derivative discovery decorator which is supposed to be trying to remember. For every plugin type that you define, if your plugins are providing a derivative class within the annotations, I'll go ahead and pull in those classes and find all the sub or child plugins that exist for that plugin. So if you needed that or wanted to provide that functionality inside the constructor of the plugin manager, you would pass this in. Alter decorator, again, this is invoking something that's very familiar to most of us which is calling out hook action info alter or whatever hook that you pass in for the discovery. And then a process decorator would be something like, hey, I have all the plugins that I want even through the discovery decorators.  This is where you would provide that. And then a cache decorator which is a kind of interesting way of thinking of this. If we're passing in all the plugins that have been discovered, how do we cache them? We can patch that in through this discovery or decorator, which is a cache. And instead of pulling in plugins directly from Drupal source code, it would just pull it in directly from cache. So here you define what your cache key is and it would be in charge of just caching that on the fly as it's discovering it. So all of these, I guess, processes to find plugins or even to find things that are defined in info hooks. Something that you've all been familiar with but now we have classes that basically walk us through the process without us having to do much. So that's the discovery phase. Now the factory classes, what we have available are just the default factory, container factory, reflection and widget factory. And in a sense, what this looks like when you're implementing it is you call the plugin manager and say, hey, create the instance. Here's the plugin ID that I want because now that I've discovered all the plugins, I have machine names and I'm gonna pass this plugin ID and pass in some states based on whatever my application is doing. I look at it in terms of this. When you instantiate a class, it kind of, it's broken down into two pieces. How you instantiate something and then the arguments they pass into it. Given that kind of context, now all the plugin factories that exist or factory plugins that exist kind of make more sense. For instance, the default factory, this is literally just calling new whatever the class name is. So that's a pretty straightforward operation and passing in the fixed arguments that you require in your plugin type. So that's very simple. But if you wanna do something different like instantiate your plugins with the container factory, just like we talked about with the service containers, there's a class for that. And internally, this is what it would be calling in. The plugin class create method and just pulling in the Drupal container object in which we can then grab in the ID that we want and passing some state into that. So yet again, a different way of instantiating this plugin. The widget factory is something that's used with the field widgets in a sense. If you ever needed to have an instantiator with custom parameters, this would be I guess a nice way to follow suit. Where in this case, it's not just pulling in the config plugin and the plugin definition. Instead, it's passing in the field definitions and then the config settings. So it's doing its own thing here. Not necessarily useful, probably for your own custom code to extend upon it. But it is a good example to see how you can, I guess, have a different way of instantiating with the custom parameters. And the reflection factory, which is actually pretty interesting. The dynamic part here is that instead of having a fixed set of arguments, it's a dynamic set. So a reflection class would basically pull in the class and find out what arguments exist for it in the function signature. And based on what you pass in as configuration, it would go ahead and pull in these IDs into the parameter or into the plugin itself dynamically. And this is kind of helpful for any kind of plugin that you have an X number of parameters that can be coming in. This is especially used in something like autocomplete where you can have N number of parameters being passed in or even in, I think, entity relations where you can have, again, different parameters to define what these relationships are. So reflection factory is really good for that, dynamic arguments. And then the mapper class, which is the optional part, getting the instance. The way this works is that you're not really defining which class you're instantiating, nor are you defining what arguments to pass in, but you do have a set of options based on, I don't know, the state of your application. What it would do is it'll grab in some options and it'll go through some logic phase that say, hey, figure out what class would be most appropriate to do the process that I wanna do. One example would be the archiver where there's many different mechanisms to archive something, ZIP or TARGZ. How do we know which one to use? Based on configurations that we're passing in, it would decide what class is most appropriate to handle such thing. So for instance, looking at the extension of a file, then it would know, oh, this is a .zip file, so I'm gonna use the ZIP on archiver. Another example of this would be, say for instance, you have a REST server and you wanna process basically the response of a request. At runtime, you don't know what class is most appropriate, but you can look at the content type that the requester is accepting and you can say, hey, this guy wants to have JSON format, so let's pull in the JSON class and this will happen on runtime, so you don't necessarily have to have strange if else conditions inside your application. The mapper class should be able to handle that instead. So once it has the logic and figures out what it needs, it figures out what the plugin ID is and then you can just pass that into the factory. So this create instance, now I have that ID and again, you can pass in the options to define whatever configurations you need thereafter.  Okay, that is all plugin manager is. But again, keep in mind this is headless. You're basically pulling in plugin data, so once you have that data, it's up to you if you wanted to have some sort of interface that goes along with it and again, that's the fancy part that you can decide what you want to do with. And then of course the instantiation, which is a very boring and simple thing, but again, there's different mechanisms of doing it based on certain use cases and whatever's part of a Drupal, pretty much helps you get there, at least half of the way. So I'll go ahead and create a demo of doing a plugin manager. In a sense, this is what the relationships look like. We have a person plugin manager, which is the fictional plugin type that I've created, which is a really lame example. It's extending the default plugin manager and that itself is implementing a lot of interfaces in which you can see in the green dotted lines. It implements the mapper interface, factory interface and discovery interface, of course. And then it also implements the plugin manager base itself. So it has now a contract in which there's a certain number of methods that the plugin manager is supposed to implement. Luckily the default plugin manager handles almost all of them and the person plugin manager really only needs to add in additional things that the default plugin manager does not provide, such as a cache backend if I wanted to or alter hooks if that's what I wanted to do as well. So when you define your own plugin types, there's really not a whole lot of custom code you have to write, but there is a bit of boilerplate stuff that you'll need to do. So let's drop into code again and we'll talk about each one of these. So it starts off with a person plugin manager. Actually let's take a step back. I'm defining a system in which I have a plugin type that's supposed to do certain operations. In this case, it's just something simple like get a person and there's really only three parameters in which I play with. A person's name, their age, and then how they do their greeting, assuming they're like multilingual or whatever. So this is the interface in which all the plugins would basically extend. I will provide a person base, which is a class. And again, these classes don't necessarily have to exist in any specific place. You define what these namespaces are. But in here in this case, I'm just using Drupal pilot plugin because that's a bit intuitive. My class person base is extending the plugin base, which again provides a lot of other stuff for us, but I'm implementing the person interface. So again, this is what differentiates a class from a plugin type is that it's implementing a specific interface. And here I'm just providing the defaults. Get name, it's just gonna grab the definition and grab the name property. Get age, I'm grabbing it from the definition, grabbing the age property. And then the greeting, simple. Hello, my name is this and I am this many years old. So very, very straightforward. So that defines, I guess, the skeleton of what my plugins would look like. Now I need to define a manager to basically handle doing the discoverability of these plugins and all the instantiating of these plugins. So now I jump into the person plugin manager PHP file. So this is now three files that we're working with. Again, I'm providing the namespace Drupal pilot plugin because that's intuitive. All of this used stuff is just as a shortcut for not having to define the classes over and over again. But in my person plugin manager, I'm extending the default plugin manager, which itself is in charge of really pulling in or implementing a lot of the methods that are necessary since we are extending or implementing a certain interface. So that handles a lot of it. I'll go ahead and move this over so we can see more of the code as possible. Normally, all you wouldn't want to do is just call the parent constructor, which is a default plugin manager, which does a lot of stuff to it. We passed in what sub namespace we are expecting our plugins to exist in. So in this case, plugin person. The namespace that's passed in, which is all the different modules that are enabled at the time, where all the different places where I can find plugins. Module handler, which is just a bullet plate, describes all the different modules that exist. And in this case, something that is special. I am using annotations to find all my plugin types. So I'm saying, hey, where's my annotation classes? Internally, so it's not so opaque as to what's happening, the default plugin manager is doing this. It's defining a discovery property and it's setting that to the annotation discovery. And so this is where the sub namespace and the annotation path actually goes to work. Go find all of the markers that have at person under this directory using that class. And then I'm again, reassigning discovery, but this time passing it through a derivative discovery decorator. In this case, it's a container derivative discovery decorator and which if I had any person classes that defined a derivative class in itself, it can go ahead and spawn child plugins. And then I'm defining the factory, which is just a default container factory. You don't have to do anything special. And then also just providing the module handler. But this is what the default plugin manager does just for visibility. But in a sense, this is all I really had to do. The only custom parts that I wanted for myself is I wanted to provide an ability to have a hook pilot person info to be invoked. So I can go ahead and change up the info if I had another module that wanted to do that. So this is where I would invoke that. And since I wanted this stuff cached in the backend, I'll go ahead and implement this set cache backend and provide a cache key in there itself. So that is a plugin type that is a manager and that's essentially on all I need to do. All the heavy lifting is really provided through the default plugin manager to get all the definitions to instantiate the definitions or instantiate the plugins rather. But I did mention something about annotations, a custom annotation. So there's one extra thing that we have to do. Inside of our source directory, we have annotations and then a person.php class. And this is very, very simple. Where we're extending the plugin annotation. And this is where we define what our default parameters would be for I guess the hook info, what we're all used to. And in this case, I'm just looking for an ID, a name, and an age. And providing some defaults also in here. And with this, now I can use doctrine to basically find all of the classes or all my plugins looking for that app person marker inside of the code. And one last thing is that since we've provided a plugin manager and this is itself a global service in which we can use globally, we basically register it as a service. So I give it the machine name of plugin.manager.pilot.person, right? I say where the class is and I define basically what my arguments are, but I don't necessarily have to redefine what my arguments are. I can just reference the parents, which is the default plugin manager. And so we'll use whatever it defined as its arguments. So I don't have to do anything other than just say, hey, here's my parents. And whatever arguments you pass to it, I want you to pass it to me. So those are all the four components that we need to actually generate this. In this module, I'm providing person plugins. So this is what other modules would be doing. Essentially, the annotation portion of this at person. I'm defining the ID, the name and the age, and I'm not necessarily doing anything within the class itself because the defaults are fine. The defaults that I'm putting in the person base are just completely fine, for Bob at least. For Dave, Dave is gonna say something a little different. Say, hey, my name is this. But again, the whole idea of having your plugins parameterized and having all your info baked in together is all right here through the annotations. So we have those two plugins. Other modules can provide their own plugins as well. And to actually pull this in, we'll look at form that I have, which does the collection of these things. So we'll get this stuff out of the way. All right, so given that now we have the class for the plugin manager and all the additional boilerplate stuff that was necessary, we can now actually use the plugin manager using a service container. So I'm saying, hey, I want the manager and grab that from the Drupal service container. Here's the machine name that I defined within the services.yaml file. With that, it would figure out all the different classes that it needs to instantiate and do its whole dependency injection thing, and in which case it would basically instantiate the class for me. So now this is a manager class, the plugin manager that I've created. I want to collect all of the plugins, so I say, hey, manager, get all the definitions, and here I'm just printing R all of these onto the page. And I want to pull in an instance specifically. So in this case, you would probably want to do something fancy, like a UI, where a user can click through things or whatnot, and you have a list of all these plugins in which you could probably attach configurations to them or whatever. But once your logic defines which plugin you want to load in, you can go ahead and just create the instance and pass in the machine name that you want. And now that we have the instance, the actual plugin type with optional configurations within it, we can do stuff with it. In this case, I'm just calling out the greeting, so it's gonna say, hello, my name is whatever. And that is all. So let's navigate to the page that's providing that. And that is, all right. So in this second, I was able to discover where all my plugins are through annotations. I was also given the opportunity to have derivatives, child plugins for everything that's instantiated or everything that's defined as a plugin of person. And in the end, I'm really just collecting it and caching it, and now I'm just displaying it right here. And which I've only found two plugins, Bob and Dave. And you have all the plugin definitions in here. Secondly, if you remember, I pulled in an instance, a specific instance, Bob, and I'm just saying, get the greeting from Bob. So you come back over here and I'm printing that out itself. Hello, my name is Bob and I'm 26 years old. And I pulled in that data from the annotations that I defined. So again, this is very, very simple and boiled down to its simplicity in which now you can define what your UI would look like or what your business logic or what the purpose of your system is to pull in this data. But now you're pulling in these classes, figuring out a way of which to pull in which specific plugin ID and then doing stuff with it.  So very simple stuff, three lines. And I was able to have a plugin system or at least actually working with it. So yeah, cool way. So my final thoughts. There's a lot of implication that comes in with plugin types or just building plugins in general. And a lot of it is, at least through my eyes, a way of segmenting out operations, functionalities into their own little silos in which they belong. It's really easy to have any different opportunity to drop in code and do stuff with. For instance, hook page, preprocess page or hook page alter or whatnot. And it gets pretty crazy in which all the opportunities you have to do some really wild stuff. And it becomes unmanageable and becomes very far away from, I guess, the metaphor of life and how we think of things. When you think of how certain operations in life can be separated out into smaller segments into their own little silos, you can swap out actual mechanisms to do things. And your code should actually follow suit as much as possible to real life metaphors. I think that would keep you more aligned with the reality of writing code and doing things that are more, I guess, friendly for the product owners or just the way a system works. And again, plugins just kind of follow a certain best practice that encourage you to do better code and not necessarily just like match things together. I envision a lot of the development moving forward to be not just using like a big blob of custom code in your site, but really just abstracting as much as possible very specific operations into plugin types in which then you can nurture in which you can then extend upon because you'll have these different instances, the same code used over and over again. And now you have more eyes and more use cases on it in which you can discover bugs and really put more care into the code that you put in. So I feel this is a good kind of segue into a happy way of coding or at least a better work-life balance in the sense when you think about it. So anyway, that was me. Please evaluate the session. There's a link at the very bottom for you to do so. And if there's any time, I'll go ahead and take in questions now. Thank you. This might be a little rudimentary given the depth that you just covered in this subject. I'm honestly not, I'm still not sure I get quite what an interface is or what it's meant to accomplish. Yeah, so in Drupal 7, it's all functional, which means that there's no contract in which a certain function has to do something. There's no guarantee is what the input or what the output is other than the arguments that are passed in. But with an interface, a PHP class interface, you define what are required methods that a class needs to implement. So anything that is implementing an interface, if you don't have those methods within it, PHP will fail and it'll say, no, there's an error. We cannot process because the method that is supposed to be implementing this interface is not doing its contractual agreements. So this would include the parameters that you pass in, the type of parameters you pass in, and then also just the existence of the methods. So that is how a method or a class can implement an interface by providing the methods and also ensuring that the arguments that it's accepting are the same that the interface had to find. Thank you. Thanks for this wonderful talk. It was really great to get a in-depth discussion of plugins and see how they operate. Thank you so much for that. I feel like I'm still trying to wrap my head around what the architectural reason for using annotations is. It seems like we're taking comments and now using them almost like properties on objects or like static variables. I'm just trying to understand why we would start using comments in what seemed to be almost like we're doing the programming in the comments. Yes. So if you could elaborate on that, I appreciate it. Yes, so it's not code inside of the annotation. It's kind of like saying, oh, we have YAML files now and we have code inside of YAML files, which is not necessarily the case. It's all declarative. Basically provide a value and a key and that's all annotations they're doing. Why use those? Because it's baked into the class. It's a convenience, but maybe it does make it harder to debug because where are these values coming from and I have to dig deep into like what doctrine is doing to grab that data. But you don't have to use annotations. It's completely optional. You could continue using info hooks. Hopefully they're not deprecated at this point. I haven't checked. But there are different mechanisms of discovery. Annotations is just one of them and one of the more popular ones. The slide link or the link that's in that slide in particular has another slide deck that describes why annotations are useful and kind of defends both sides of the argument. So looking into that would probably lighten things up a bit. Thank you. Hello, Helior. Thank you for giving us talk. I watched a YouTube video. You've given a talk at a different camp and this is a much better version of the presentation. That was great. I was gonna use the word talking actually. I'm conflicted though. I could see plugins as a solution being a great solution for plugging into an existing bit of architecture. Some things like file for field for matters and blocks and things like that. What I'm not getting is the cross section between using a plugin for the solution and using an entity for that same kind, solving that same kind of problem. Can you explain where it conflicts with entities and how to resolve that problem? There's a lot of overlap actually with config entities. And entities in a sense are basically a collection of configuration and it would use plugins to do things with it. So think of plugins as being the operational part of things to do singular actions, to process data, to do stuff but doesn't actually hold data. If anything these plugins could have configuration that modify how it does things but doesn't necessarily store a node. It doesn't persist any kind of entity. And you can think of entities as being basically like if it has a table record, right? If there's a row inside the database then it would be an entity. But plugins don't necessarily operate that way. So for me that is the distinction between where plugins work, processing data and entities would be basically persisting data and having like load functions and the whole crud stack that's baked into that and everything else that goes along with it. Yeah, that helped a bit but that makes blocks more confusing. Yes it does. I can kind of help clarify that if that helps a little bit with an example. Is that okay? So think about views. In the views UI, you assemble, you take a bunch of different filters in a bunch of different fields and you have several displays in the view and you put them all together to make one thing, right? So each of those individual little things, each kind of filter that you add is defined by a plugin. The plugin contains the metadata about it, a definition of what the thing is and then an API for how to do the thing. But what it doesn't contain is what you just configured in your view. And so what happens when you configure a view is that the specific instances, the specific configuration data for many different plugins is saved in one configuration entity. So the entity is essentially just providing the storage for the thing that you just configured. Similarly with blocks. If I have like a, you know, his snowman block, I thought that was a very cute example by the way. If I have a snowman block, that doesn't actually create a block on my site. What that does is it says, hey block API, I have this block available, use it how you see fit as the block API. And then where the entity part of that comes in is when you are configuring a site and you place an instance of that block somewhere. So you're not actually, that the instance of the block is, you can have many of them right in triple light. That's one of the new pieces of functionality that's available. So you can take your snowman block and you can put it in the header and you can put it in the footer and you can put five of them in the sidebar if you want to and configure specific things with each of those. Then those block instances would be stored as configuration entities and the configuration system to be deployed to other sites or whatever. So that's where the distinction is entities are about data, whereas the plugin is about defining an API for something in the way in which you can create things. It's not necessarily coupled, but that's how the two interact frequently in core. Does that help? So would it be fair to say that the only responsibility a plugin has in regards to entities is creating their instances? And then however that entity stores its configuration, if it's a content entity or a configuration entity, it does what it does. We need to take this conversation outside so we can go ahead. Okay, okay, go ahead. Yeah, that's why specifically I didn't want to talk about configuration entities. Hi, thank you for your talk. I had a question about when you are instantiating plugin type, the annotation, is there a, does something tell you if your syntax isn't correct or does it just fail silently? Specifically where? Like when your annotation is incorrect, like with the curly braces or within the comments about it. Instead of like a HookedBotGambo, you have your annotation. Yeah, because a doctrine does its own processing. It's parsing the string and it does its own thing. So in there it has its own validators and you'll get errors saying, hey, this is not formatted correctly. You're missing a comma or maybe you have this other thing that's not closed out. So it will do that for you through all the errors. Okay, thank you. Yeah. Cool, thank you guys.


The Saint Cloud Tech tennis team has dominated the Central Lakes Conference this decade. They haven't lost a conference matchup since 2011, going 55-0. But the last team to beat them, the Brainerd Warriors. Coming into today's matchup, they were undefeated looking to knock off tech. In first doubles, Taya Person, working it up front, keeping the Tigers on their toes. Person was dominating in this point until Tech finally hits one out. The Warriors win that matchup 6-1, 6-1. They dominated doubles all day long in the second pairing. Lily Jones up front with the quick reactions, puts it just out of the reach. And they would secure the victory from Brainerd. But the singles were controlled by Tech in the second singles. Katie Inderiden keeps Brainerd on the run until she puts down a drop shot to win the point as Tech takes second singles and straight sets. Tech wins all the singles matchups. Brainer takes all the doubles, but Tech gets to win 4-3. You'll expect to see that in sectionals. If you enjoyed this segment of Lakeland News, please consider making a tax-deductible contribution to Lakeland PBS.


What's up, YouTube? It's James from Smoke Cartel, and we've got another product review for you. Today we're checking out the straight case. This thing is virtually indestructible. It's made from high-impact polypropylene, which means it's chemical and corrosive-resistant. Let's take a look inside. On top you've got your eggshell design, and inside you've got one, two, three layers of foam, completely customizable, any shape or size you want to fit in here. We've got 10-inch cases. We've got 8-inch cases. We've got yellow, black, teal, gray, more colors to come. You want to throw this thing down a flight of stairs? Go for it. You want to try to hit it with your car? Be my guest. You are not going to break this thing. A straight case is so confident that you're not going to break it. They want to give you a 30-year warranty, and that's pretty awesome. If you want to take this thing to Antarctica, you've got down to negative 40 degrees. If you want to go to Death Valley and back, you've got up to 176. That's Fahrenheit ladies and gentlemen, because these things are made right here in the USA. All those hard-working folks at Straight Case up in Michigan. What's up guys? These things are stackable, waterproof, dust-proof, airtight. They've got two sturdy clips and a really sturdy handle. So that's the Straight Case guys, and if you like products like this, check out Smokartel.com, and if you like these review videos, don't forget to subscribe. Thanks guys.


Hello and let's talk about the Energy Amendment Bill 2020. India is going through a pandemic but the centre seems to have introduced a bill that will drastically overhaul the power and energy sector. And the states as well as the employees are not happy. This pandemic has shown, among other things, that public services are essential for the country to run smoothly. But here we have a proposal that will actually strengthen the private sector. This proposal will also actually strengthen the centre whereas the states suffer. To talk more about this, we talk to energy expert Tejal Kanitkar. Here is what she had to say. Tejal, thank you so much for joining us. Now this is the fourth version of this electricity amendment bill that has been introduced by the Modi government. And this is being introduced at a time when the COVID-19 pandemic is on. There are a lot of issues being faced by the country. The COVID-19 pandemic has shown that state services and public services are really essential as far as the people are concerned. But this bill seems to be moving in a completely different direction. So could you tell us about the kind of structural changes that this bill seeks to break or amendment seeks to break? You're absolutely right. One is it's an absolutely bad time for them to be pushing this bill. Even otherwise, the bill is pretty bad. But this, in particularly because states have been fighting the COVID-19 fight, there is no time for people to be able to respond to this. Thankfully, they have now extended the deadline for when you could respond to the bill. But there are four major things about the bill that I think are important. And this is sort of carrying forward from the Electricity Act 2003 itself, which first introduced major changes in the way in which we thought about the electricity sector. Since then, and since the 19 structural changes that were implemented in the sector since 1991, there has been a continuous encroachment of the center on what is a subject on the concurrent list. You can see this in pushing off renewable energy targets from the center on to the states and many other things. But one of the things that this new bill I think does is like never before, it increases central control of the central government in the electricity sector where states simply have to bear the burden and be onlookers. They have very little wiggle room in terms of making policy and even regulating. They push even more aggressively the model of privatization, which despite many, many attempts for the last 30 years since the reforms were introduced in the sector have failed. There is a refusal to learn from history on this count. There is a much more aggressive move to eliminate cross subsidies and replace them with this direct benefit transfer of subsidies from the state governments directly to the beneficiaries, not even to the utilities in question. How the states which are already dealing with extremely empty coffers are going to manage this is another story. And there is an even bigger push for renewable energy again in all of this while centralizing the policy making on renewable energy. This, of course, we know the prime minister, he wants to make this his sort of legacy, the renewable energy target. So there's a push for this and it is not fairly very clear why at this point on because all indications are that even without COVID-19, we were in pretty bad shape in terms of where our electricity demand was heading. We were much lower than what we had anticipated. With COVID-19, we have already back down a lot of our generation, quite considerably, thermal more than 25%. And so we are in a situation of power surplus. Why push for more renewable energy at this point of time is a serious question. Right. So one of the key aspects you mentioned is the privatization element of this. So how would you explain a bit more how this amendment actually takes it forward in terms of how the distribution and is going to take place? So the act itself in 2003 said that we should privatize especially two segments. One is the generation segment of the power sector and the other is a distribution segment. Broadly, the sector is divided into three segments. It's power generation, transmission and distribution. Transmission is like the high voltage transmission of electricity from the generation stations to the distribution companies. Distribution is what takes it from the high voltage transformers to end users. So the first and the last segment were sought to be privatized. What has happened in the last 30 years is that generation, they have been fairly successful in privatizing. We've had a lot of investments in generation and that's part of the problems that ails the sector currently and we'll talk about this a little bit more. The distribution segment has not been, they have not been successful in privatizing it. What they have tried to do, another version of this bill came up in 2018, where they had argued for what is known as carriage and content separation. This was directly lifted, even the terminology was lifted from the World Bank report of 2014, where they say okay what happens is that the state government or the state distribution utility is in charge of the wires and the infrastructure of supply and the actual supply of electricity will be done by private distributors. This of course was opposed by many people. Now what they say is the same thing in a different language. They say that you will, what should be done is introduction of distribution sub-licenses or franchises. The difference between sub-licency and franchisee whether it is a difference in scale or something like that is not clear from the bill at all. But what these sub-licenses will do is they won't require a new license. All they would require is the current distribution utility will hand out a portion of their region to these sub-licenses and in this region, the sub-licency will then buy power from somebody and sell it to the end users. This according to them will reduce the, is supposed to have two benefits. One is it will reduce the cost of power procurement. The other is it will reduce the cost of operation of the grid by reducing the TND losses. This has been tried before and has failed quite miserably in both cases even when there has been cherry picking, meaning only the urban clusters, urban agglomerations have been sought to be privatized. Nobody is interested in no private distribution licensee is interested in supplying power to rural areas because these are not profit-making consumers. They are not consumers that can pay the full cost of electricity. So they are interested in urban areas and even in these urban areas, this has not been, even in a place like Mumbai for example, where electricity distribution is privatized. Earlier reliance now Adani in the suburban part except for some part of South Mumbai, the rest of it is privatized. There have been protests, there have been continuous tariff hikes and cost to consumers has not been able to reduce. In Delhi, the only way in which this has been possible where we also have privatized supply is where the distribution by creating what are known as regulatory assets. So because there has been an increase in prices that has been allowed, but because you couldn't transfer those prices to the consumers, you create an asset which can then be paid for at some point of time later. One last thing is that Orissa is the only place where there was a non-urban consumers as well that were included. There were three attempts at privatization for the last 25 years and they have failed, the distribution sector is back with the government now in worse shape than when it was handed over to the private distribution company. And these are privatization of TISCOM models. There were franchisee models in Bhivandi, Amdabad, Agra, etc. Even here the franchisees have been unable to break even, even though they have stuck to only urban agglomeration. Thank you so much for talking to us. Thank you for having me. That's all we have time for today. Keep watching NewsClick. For our next segment, we bring you a bit of a conversation between NewsClick's Prabir Purka Eshta and P. Sainath, the founder of the People's Archive of rural India. They discuss the way the Indian media is functioning, how it is sunk to its lowest during the coverage of the COVID-19 pandemic as well as the threats and assaults against those journalists who dare to go against the government and its official version. Take a look. How would you look at the whole issue of what is the reporting that media can do under various additional constraints which have been put under COVID-19 now, Epidemic Act, fake news, all these things are now being used against the media in different ways? Well, one is that some of those constraints have been self-imposed. At a time when you really need to be telling the public what's going on, you've laid off hundreds of excellent journalists, reporters who are pretty good and partly because they are independent-minded. They're the ones who get the shaft when something like this happens. So we don't know how many journalists have been laid off, but we know it's in hundreds. This, by the way, has precedence. You've done it after 2008, the Wall Street collapse. You've done it as media marches towards its digital Shangri-La. And you've done it in the best of years at high profits. When the COVID thing came along, it gave them an excuse to say, look, we are helpless. We have to throw these guys to the sharks. That's it. Yes, some of them have done so because of being seriously in financial trouble. But many of those layoffs were planned anyway and were being routinely conducted. The second thing is about government. See, you know, even on corporate mainstream media, you've had the acceptance of this term and people keep using it. Crony capitalism. My thing is that we all know what capitalism is, I assume. Have you ever wondered who's the crony? We are, the media. They're the cronies. Please know that in crony capitalism, the cronies are the media. The most important thing about Indian billionaires, the 121 of them listed a year ago and maybe now 106 or something, is that they are what some progressive economists call red thick billionaires, frontier incomes. They capture huge public resources as a favor from government, like I get the oil and natural gas, the fields, etc. Then I subcontract to thousands of people and do little myself, right? And I just keep the most core profitable business a part of it myself and outsource everything else. It also helps when you come to layoffs and everything else that we don't know who these people are. It's not our job. They're not our employees. Now, the thing with this approach is that it makes your billionaire class, which is a very important, very important segment of Indian, of the Indian ruling elite. Do not underestimate them in 2018-19, their individual, their cumulative wealth of those 121 individuals was equivalent to 22% of your gross domestic product, giving an entirely different emphasis to the word gross. Because of their rent-thick wealth, because of their dependence on public resources, they are never, ever going to seriously conflict with government. It's their government. Second, who owns these enterprises? They're all gigantic corporations. Now, the richest man in the country is the biggest media owner, Mukesh Bhai, is the biggest media owner. So I'm saying the relationship between government and media has to be understood in this sense. I also put it in another sense because of the present government. I've been saying for several years, your country is ruled by an alliance. It's ruled by an alliance of socio-religious fundamentalists and economic market fundamentalists. And this happy marriage, I mean, the bed they cohabit is called the corporate media. And there are many people who are part of all three, all these three forces. There are, I mean, our prime minister and our home minister are very much part of both camps, socio-religious fundamentalists and economic market fundamentalists. Now you have economic market fundamentalists who are also the very clever, clever young guys who came out of Harvard and Wharton, etc. We know who are still saying the same things that, you know, they've been taught around to tell us what went wrong when they have never got it right in their lives. In 2017, your chief economic advisor and another important man of Neethi Aayog, Vivek Debroy and Mr. Arvind Subramaniam went head-to-head with Thomas Piketty on television in Nidhi Rastancho and declared inequality is not an issue. Those words, go and look at the clip. And flaunting wealth is not an issue. Now the kind of corporate owners of the media are people who have benefited enormously from that growing inequality. So there are many people in both camps and the media have really been the cheerleaders, the canvas for this. Let's come to COVID and let's look at how there are five things that stand out in how the media has functioned on this. The first is the incredible surprise, you know, the injured innocent surprise of the existence of a species called migrant labor. They were shell shocked by that on March 25th, hours after he made that, the prime minister made the announcement, you know, old gentleman ex-IS officer, Deva Sahayam, said it so nicely. He said, even a small infantry brigade asked to go into a major action is given more than four hours notice. A nation of 1.3 billion was given a four hour notice to shut down their lives. So we, and I am arguing that though it may not be in their interest, that's debatable, the action of migrant laborers was entirely rational. You know, Saira, I would interrupt you at one point because this brings up something you have been talking about for a long time, that media does not cover certain things because they're not consumers, they do not consume for the advertisers and therefore there are no interests to the media owners or the media itself. So migrant workers, agriculture, poorer sections do not figure in the pages because they know they are not people who will consume and bring in advertisements. Praveen, in 2006-07, when I was in the Hindu and a Chennai-based newspaper was covering Vidarbha more than any newspaper in Maharashtra. Young journalists in the times dying to cover it, wanting to go there, pleaded with their management and asked them, look, this is a Chennai-based newspaper. The Marathi newspapers are reproducing them. We should be covering this. They got a memo which told them, dying farmers in Vidarbha do not buy the times of Vidya, the elites of Sobo, South Bombay do. Okay, this is what they were told by them management. Look, Praveen, when you don't have a single correspondent full-time to cover labor of all kinds, farm labor, industrial labor, when you don't have a single correspondent and crafts persons, when you don't have a single correspondent to cover farming full-time from the perspective of the farmer, you are saying 75% of the population do not make news.  And dying farmers don't give me revenue.  I make money out of covering volume, I cover volume. It's as simple and rational as that. The other part of the media which I wanted you to talk about, explain to us that all these acts which are now in play from the Epidemic Act to the Disaster Management Act, they also have clauses, don't spread panic and therefore that becomes a provision under which criminal action can be taken, FIRs can be filed. Now we see a whole bunch of FIRs and criminal action against a certain set of people and the well-known ones, those who are critical of the government or those who are actually also targets of communal propaganda, which a certain section of the Sangh Parivar indulges in all of this time. We also see selective use of this and also see no use of this against obvious hate speech and hate propaganda being unleashed by what you call the Hindu fundamentalist right or I will call really the Hindu sectarian right at the moment. I think there isn't any doubt, I mean there's no doubt in my mind that between what we'd like to see come out of the lessons of the pandemic and what is going to happen, I think there is going to be a huge rise in authoritarian power and its use, the consolidation. Praveen it's much bigger than just a couple of laws, you are looking at the dismantling of the parliamentary democratic system. Let me tell you this, no elections matter, no governments matter, no opposition matters, the cabinet doesn't matter, one gentleman addresses the nation and tells it what to do. You are actually seeing governance by one person who never holds a press, open press conference in his entire six years of has never held a press conference, open press conference where people can ask him questions. In the US you have government officials fearing that every morning press conference of Trump wondering how he's going to screw them up by the next absurdity he states. He can't stay away from talking to the media and there are questions asked of him. Here no, this is the one democracy in the world where the leader does not feel obliged to be accountable, asked questions by the media nothing.


Music and sound effects in Godot. Let's go. Most games have music and sound effects. They are instrumental to making your game feel good. If you take a game without sound effects and add sound effects and then you add a little background track, you're going from pretty boring to a lot better. And Godot makes it real easy. So I've got a blank game, a main scene, no 2D. We'll just do it in 2D. Talk a little bit about positional audio. But for right now, we'll go ahead and just focus on simplistic sound effect playing and music playing. I want to start from nothing. So here's a great website SFXR.me SFXR.me. It's a website called JSFixer. How do you even say that? But it lets you generate sound effects. It's based on an old tool called SFXR from 2007. This tool ruled. It was made with a flash, I want to say. But this person made it in JavaScript and that way it's a lot more accessible. And you can click what you want to make. So like that's a jump sound, power up, explosion, pick up coin. You can keep clicking it and you get different ones. You can even modify the different settings yourself. You can even mutate it, which takes it and changes it just slightly. I like that one. All you do then is you click this permalink. You can say save link as and I'm gonna go find my game which is in game dev screencast sound demo. I'm gonna actually no sorry. You just click this wait file. Open it in downloads. So you've got your file on your computer. Take that and drag it in and you've got this music file. It's read only. You can hear that play. You can see some details about it.  You'll see some other ones like audio stream player 2D that you can like put something in your game world that plays a sound effect and then the closer you are the louder it is. That's super cool. But beyond what we're doing here. And we'll just call this pick up SFX. And then over here in your stream you've got all these options. I almost always just do quick load and it shows all your audio files. Click open and now you'll see you can play that and you've got it. And then you've got this audio stream player node and it has a finished signal which is cool. You can say auto play or is it playing all that stuff but let's just add a button that plays our sound effect. We'll say call play sound effect. We'll say play SFX. We'll just drag it to the middle and we'll say on button pressed. Well we need a script. Put that in main. Clear out this stuff. We don't need it. Okay here we go. Click the signal when the buttons press will play our sound effect. And all you have to do then is to pick up sound effect to play. Run our game. You hear that. There you go. Pretty nice right. Really really dig that. So that's all you have to do the sound effect. And some cases some some examples of this would be like maybe you have a spaceship that has a weapon. In your spaceship script you can or in your spaceship node like you might have a scene for your spaceship for your player spaceship. You can then just create your audio stream player. Associate the stream file and then every time it's fired you just press you just call the play function. And that's you know the basics of sound effects. It's pretty intuitive and simplistic. And music is not too different. So I've got this song I made called Circus. Got some platformer vibes. I've got an org file because it's a little smaller than a wave. Godot plays org files. I'll just drag that into my project. Now we have Circus Og. And let's see. We can double click it and play it again. That's great. And here's something different from the sound effect which is I want this to loop. So all you do is you double click it. Check the loop. Click re-import. And now when that finishes playing it will play again. So let's drag it to the end. Ooh it started again. Because you usually want your background music to loop. So that's that. We'll go ahead and we'll duplicate that button. I pressed command D. You can do control D if you're on Windows or Linux. And we're gonna call this playing music. And we'll just move this over here. And who cares if it doesn't look good. We'll do the same thing. Connect the button. It has our old signal connection. We're gonna connect it here. I just want to make sure that that's not connected double connected. It is. So when you duplicate something it duplicates the signal. So you can just right click and click disconnect. Now that isn't connected. We'll go ahead and we'll just have music. I'm actually gonna call it. Yeah. We'll just call it music. We don't have that yet. Again. Audio stream player in here. You'll go to the inspector. Quick load circus.org. You can verify it's there. Can't play it though can I. Well that's okay. And you'll see here though loop is set to on so you can just verify that. And you can right go ahead and run this. I think it should work. No it won't because I didn't name it properly. So we'll just name this music. Click play. Hmm. Got an issue. Let's see what happened. Error calling from signal signal press to error calling the signal press to callable on play music press method not found. So let's go back into play music. Make sure I did it right. I'm just gonna disconnect and we'll go ahead and connect it here. Oh there's some funky junk going on there. Okay we should be good now. So we got the music playing. Play the sound effect to kind of nice. And we can even change the volume because that's pretty common. Sometimes things come in a little hot. You can do negative five decibels that'll make it less loud. And we're running again and you can even change those while it's playing so you can get a sense of what feels right. Okay that's negative five. Just change it to negative 20. That's barely coming through. We'll set it to two. Quite a bit louder. Negative five. That sounds pretty good with my audio but I don't know what my volume is at. So might be kind of a little odd. But okay great you say. What happens if we keep pressing play music? Just keeps restarting. What if we make it pause music and play music? We can check the current property. We can check the properties of audio stream players and react accordingly. So music has... I'm gonna stop that because wow that's I think I designed it to be annoying and it sure is annoying. Oh nice we've got clapping. Okay you can then check here and let's do a couple things actually. You can say on ready var. We can say pick up SFX. I want to make it so that we have some typing because that will make life a little bit easier when we're making our game. So we're gonna say pick up SFX is of type audio stream playback and we're gonna set it on ready to pick up SFX. So now that we know it's an audio stream player. Okay see you gotta get it right. It's audio stream player and then we can change this to be pick up SFX and then for music we'll do the same thing. Audio stream player and we'll set it to music. This not only lets us more easily rename our nodes in the scene but gives us nicer type printing I think. Let's see. So now we have music yes. Did that not work before? Sorry let me just verify. No see that's that's why we do these things. I sometimes wonder why and that's why. So music audio stream players have properties and let's look at the docs. This will be a good learning opportunity. If you command click or control click on that we go to audio stream player and please audios non-conditionally. Let's check a couple things. So we've got auto play defaults to false. That's like when it's added to the scene should it play automatically and I kind of think sometimes you might want to like when you add music but you can check if it's playing. That's what we care about and there's some other options here to like the volume which you could change dynamically in your code but let's go back to here and go ahead and go to main gd and so we'll do music. We're back we're back where we were sorry sometimes go from the weasel. That works. Let's go ahead instead of restarting it on its playing we'll say if music dot playing then play it else music dot. Now there's I want to say there's a way to pause it. Let's just see if stop pauses it. So oops got these wrong. That happens a lot. Getting the logic right is very important. It's playing. We're at the very beginning of the track. Let's get to a part in the track where it's different so we can check if stop pauses or goes back to zero. Okay click it again. Okay it restarts it. So that's fine that's interesting right. I want to make it to see if we can pause it but instead for now let's just go ahead and we'll say we have our button. Let me punch out of here and we've got to play music. So we'll say play music. If it's playing we'll stop it so we'll say play music dot text is equal to play music because we're saying okay the music has been stopped we want to play it again and now we'll make it stop music. Run it. Now change the stop music. Click it. Place it again. That's cool. Let's see if we can figure out how to pause an audio string. Playing. True. False. What if we just call what if we just change that property value. So instead of saying pause music we'll say resume music and then what if we say music dot playing is false and here we'll say music dot play. Does that work? Okay we're just waiting. That doesn't work. Is it because play restarts from zero? I bet you it is. Okay play from position zero. So we could keep track of the position when we start and stop and do that but I think we can instead just say it playing is true instead of calling that function. Thanks for bearing with me through this. Gosh we've got to wait to get to the good part. Okay. Restarts it. Alright let's um I don't know how to figure that out so we're gonna go ahead and we'll code it our own way. We'll say music dot stop. We'll say music dot position. There's got to be a way to get playback position. We'll say music pause is that and then here we'll say music pause. We'll say music dot play. Music pause. Pause is short for position. So we stop it. We keep track of the variable then we play it and then whenever we stop it it will be updated. So okay that worked. Interesting stuff. Always learning. This whole section is way off in the weeds but hopefully this helps you with just like basic audio playing and what you do there. I use a program called One Bit Dragon to make my music when making games but you could just find free and public domain games. You can make music the way you want to. One Bit Dragon is pretty neat. It's pretty simplistic and works well. That's audio and g'dow. The basics. Alright thanks. See ya. Bye.


Hello, this is Andrew Friskup. I am the North Dakota State University Serial Extension plant pathologist and today I am going to show you an example of how to use the NSU pest management app. In this case, I'm going to say I'm a corn farmer in North Dakota and have an issue with common cockabur. So using the pest management app, the way I would get to information for common cockabur control corn would be select the whole crop corn, select the pest, in this case it's a weed, and then look at common cockabur itself. However, if I'm not quite sure if it is common cockabur, notice you can click on the picture and it gives you a cotyledon type of picture. Notice use this as a tool. It's just more of a supplemental resource. So once I'm positive it's common cockabur, I'm looking at the type of application I want to make. Well, in this case I want to make a post-application, a post-emergent application. Notice I have a variety of options that I can use for this, but for this case I'm going to say I'm going to use Banville or Dicamba on this. Note I have the active ingredient, the type of mode of action that it may have, no other than this one, the specific site is unknown. The target weed is any broadleaf weeds. When to apply and any other remarks that can go through this. So following these information you can give you a relatively good idea of how well Banville would work on common cockabur. For any kind of other general info, perhaps you want to look at an ad event or any other supplemental information, you can always go through that way too and to any other further information. So I hope you enjoyed this quick video on how to use this test management app when you have a weed control problem in your field.