 All right, we might get started. Thank you all for coming. I'll introduce myself first. I'm Kim Pepper, co-founder and technical director of Previous Next, where I dribble shop that's based in Sydney, Australia. I'm Boris Gordon. I work for Previous Next. I'm a senior developer there in Sydney. So just to make sure everyone's in the right room, this is a session for developers. We're not going to be looking at any Drupal 8 site building or any of the user interface changes. We don't actually even show any screenshots from the user interface of Drupal 8. And while we're going to try and give you an overview of all of the changes that are in Drupal 8, we won't be able to cover everything because there is quite a lot of things going on. Should add that there was an emerging pattern that emerged putting this session together. We kind of found that there was a theme, I guess, which is basically if you learn one of these, if you learn one of the concepts in Drupal 8, you can really apply it everywhere, even including things outside of Drupal. All right, so there are some major architectural changes going on in Drupal 8. There's a big move to object-oriented PHP. The minimum version requirement for Drupal 8 is PHP 5.4. With that, there's PSR4 was brought in. We brought in a whole bunch of external libraries, so we're using Symphony and others. And there's major changes to the routing, the entity APIs. We've got configuration in there. We've got plugins and even changes to the front-end with things like Tweet. But you don't need to be afraid. So what we're going to do is basically try to explain some of these changes from the perspective of Drupal 7 site development. So if you're a Drupal site developer wondering what the changes are going to, how they're going to impact you, then this is the session for you. So just a quick question out of the audience. Who's actually installed Drupal 8 already? Wow, okay, so about half of you. And have you looked at any of the kind of coding or module changes in that? Yeah, a few of you, okay. Has anyone in here actually come from working with another framework like Symphony or Zen Framework? Okay, great. So basically the message is that if you, Drupal 8 is basically going to teach you to be a better developer and participate in the wider PHP community. We're essentially shedding a lot of the Drupalisms that we have in Drupal 7. And we're embracing more of a standard way of working with PHP. And improve interoperability with other projects as well. So that's something you'll see later. And I think Drew has mentioned in his keynote, we're almost standardising on things like Symphony. And essentially learning Drupal 8 is going to make you a better developer generally. So first of all, we've embraced Composer. So we're low, and the idea that we're pulling in external libraries. So there's a bunch of them listed up here. That's just a sample of them. But the real change is this change in the whole PHP community. There's a PHP renaissance. I don't know if you've heard that term thrown around before. But it's essentially the first time that Drupal is actually truly leveraged using external and open source projects. So I think in Drupal 7, there was only jQuery. I think we might have had one other library that was kind of modified to be used in Drupal. Simple test was brought in, but we pretty much bought it and used it for our purposes. Now we're using at least 11 or 12 external projects, multiple libraries from those projects, from Symphony components alone, 13 or 14 components. And similarly, we're using a lot of JavaScript libraries now as well. We've embraced modern PHP. So essentially, we're using, my original slide said PSR0, but we're actually PSR4 now, which was only in last week, which is a namespace and convention for auto-loading PHP classes. And this is a part of that interoperability thing. So one of the motivations behind that is we can easily pull in these external libraries and just use them. So that's part of the motivation behind that standard. So for those of you who haven't seen Object Oriented Code before, it's pretty basic. Essentially what we've got is, we need to follow the PSR4 standard. So I'll just point up here. So essentially, we're putting our file under a source directory and we name our class, our file the same as our class name. We give it a namespace, which is basically just making sure we're isolating it from our other code. And we can actually tell PHP that we're using other classes. We just define a class with this class keyword and we can extend or implement interfaces. And essentially just our code is wrapped inside, inside these classes. So in Drupal 7 modules, you might remember, we have to essentially prepend the module name to each of our functions. And this is sort of achieving a similar goal, keeping it encapsulated. We can use whatever name we want and it doesn't, not gonna collide with other modules. Okay, so dependency injection might have been something that's new to you. Just gonna give you a brief overview of what that is. It's something that's a very common pattern in Drupal. It's an Object Oriented Design pattern, essentially. And essentially what it does is achieves inversion of control or swappability of the dependencies that we have inside our classes. It's basically a fancy way of saying, don't call out to some code, some reusable code library, but have isolated components calling, like calling framework code internally. This basically provides better modularity. And the way it's implemented in Drupal 8 is pretty easy to understand. It's just explicitly declaring the code that you're gonna call out to in a constructor. So, and we'll see an example of that. Yeah, so this is essentially what dependency injection is. All we're doing is we've got a class, and you can see in the constructor, we're just passing in the database connection. So when that class gets created, it passes that database connection in. We save it to a protected property of the class. Now we're using this keyword to signify that it's this class. And then when we're actually doing a database query, we use that database connection from the class itself, so the property on the class. So rather than, when we want to use that database code, rather than calling out to some global external thing, we always go through the dependency that's been injected to us. And so, and that's really all there is to it. And this gives us the ability to use things like test doubles, to test our class in isolation, because we can provide different versions of that dependency. And essentially what we're doing we're loosely coupling our code. So it means that it's easy to swap out different implementations, especially if we're using things like interfaces. Okay, so dependency injection container is essentially something that just wires all these of these classes together for you and instantiates them. So we're using the symphony two, dependency injection container in triple eight. And what that means is that essentially that takes care of creating all of our objects for us. So we're not having to call, you know, new my class. That you just assume that everything's there and all plugged in for you. Yeah, so this is to sort of address like some of the overhead of decoupling these components into little pieces. It makes the act of creating them and injecting the dependencies a little bit laborious. So we've got a way to deal with that. We can wire it together with some configuration and we'll see an example of that, I think. Yeah, so the steps to take are basically, first of all, you just write your class using the standard, the PSR4 standard. And then you just need to create a services YAML file in your module route. So you name it with the name of your module and then declare the service in that. So this would be an example of the services container. Essentially, we're just specifying a unique name for the service. So it's uniquely identified. We specify the class and then any arguments that we're passing in. So in our example, the only argument that we're taking in is the actual database connection. And that database connection is just a reference to another service definition that might live, say, in Drupal Core's services YAML file. So what's exciting about Drupal 8, I think, is that we've got a whole bunch of new ways to extend it. So if you are used to Drupal 7, the way that you would extend code in Drupal 7 was essentially just to write a module. That's the way that you did most things. But it's pretty exciting in Drupal 8. We've now got a number of different ways. We've got much more granular ways to extend Drupal functionality. And one of them is services. So you could see we could easily swap out what database we're using with something else. So we could replace a MySQL database service with maybe a MongoDB one. So we've got a lot more loosely coupled software. So we can actually swap out some of these services. Another way is plugins, which we'll get into a little bit later. So now we're gonna just look at some practical examples of code in Drupal 8. So we're gonna walk through some of the things that you would commonly do when writing code for Drupal 7. And the first one is basically routing pages and forms. So the first step is just to actually look at what does hook menu in Drupal 7 actually do. Essentially it does quite a lot. They all tend to get combined together. But essentially we're handling routes. So that means that when a request comes in at a particular URL, call some code and return the output of that. But we're also doing things like creating default menu items in there. We're also doing things like creating local actions. And so local actions are the sort of sub tabs that you see in the page. And local tasks, which are like the link at the top, which might be like plus add content or something like that, they're local tasks. So that was all handled in hook menu. So this is one of the more like immediately visible changes splitting those two concerns apart. So I think we'll look at our routing first. Yep. All right, so this would be a classic example in Drupal 7. And you've got hook menu there. You're returning a ray because Drupal loves rays. And essentially just defining a page call back there. That's the name of the function that we would call. And then our function would just return a string. Pretty simple example, but useful just to demonstrate what the difference is in Drupal 8. So creating a new page call back in Drupal 8. We're not using hook menu. We're essentially first creating a standard PHP class and then creating a route definition in a new file which is essentially in your module directory. And again, we prefix it with the module name and it's just routing.yaml. So this is our controller class. Essentially here, it's a pretty standard class. The main thing to note is that we're extending controller base. So this is our built-in helper class for creating route controllers. And then all we need is a simple public function that's just gonna return our content. And you can see I'm just returning a render array. So it's a standard render array like we saw in Drupal 7. Nothing too complicated. And then the route definition. So we actually, every route in Drupal 8 has a unique key. So this is the top part. We're no longer identifying all our routes in the system by path. We're using the key that we've defined in the yaml file. And then we've got some other configuration here. We specify under defaults that we've got a content callback that lives and we can actually specify just the class name and the function name that's gonna get called and that route gets called. We can also add some requirements and the simple one is just to add a permission requirement that you need to have some permission to access that route. So by splitting out or decoupling the route ID from the path, we can do things like actually change the path that keep all links that have been generated using that route ID, which is pretty cool. And then also we can respond to the same URL with say different request headers, a different context or even different HTTP methods. So get or post or accepting, taking, responding with JSON versus HTML all in the same path. So you can lock it down and say, okay, well, I'll only take get requests on this. So if someone tries to send a post, it'll just reject it. So essentially this is the core reason why the core reason why Symphony was added in the Symphony routing system was basically to support the web services initiative so that we could actually serve off the same routes. We could actually serve JSON or XML content without actually having to have different URLs. So there is a lot provided by that controller based class. So you might know that your old friends in Drupal 7 were all of the procedural global functions. So they're all listed on the left. So we've essentially, because we wanna be in Drupal 8, we've got object oriented equivalents of those. So essentially the T function is replaced by a function that's available from the base class called T. But all of the things that you would normally expect are there. And you notice that instead of doing things like creating URLs by using a path, we're always using the route name now internally. So that's one key change. And we've got access to some new things like the config and that kind of thing. So basically we've got mappings between the old and the new available for us. And I guess one of the main reasons around making sure that we're actually using these functions from the base class is that our code is now unitestable. We're not calling out to any kind of global procedural functions inside our code, which means that we can test that code in isolation of the rest of the system. Yes. No, you can create one controller class and then have multiple functions on that. So you'll have one class and one YAML file. And you map to the method in that class in the YAML file. Well, am I just... Yeah, that's correct. I might just say people, this session is getting recorded through the mic. So if you've got questions, we might leave it to the end and we'll speak through the mic and that way we can get your questions on. All right. So there is a pattern that we're gonna be using. So how do we actually inject dependencies into our controller? So we looked at dependency injection before. We had that services YAML file in the root of the module. But that's gonna be a lot, if you've got a lot of controller routes, that's gonna actually be a lot of services that you need to contain. So the way to get around this in DRIPLE-8 was what's called factory pattern. So instead of the container, sorry, the dependency injection container creating all our controllers, we just have this sort of self-creation mechanism. So there's a public static function called create that has the container in it and that gets called externally. And then essentially all it does is call like a new on itself. That's what that return new static means. So we still get the benefit of using dependency injection. We can still inject any of our dependencies that we need like database connection or whatever else it might be. And this is just a simple pattern that you need to know in order to have your controllers do that. All right, that's it for controllers. So forms are very similar. So if you're familiar with DRIPLE-7, you might be familiar with DRIPLE-8 form which you'd normally call from, I don't know, you put it into hook menu and have a call your form function from that. It's actually a lot cleaner in DRIPLE-8 now. We've got a class that you create where all of the form functions are self-contained. And essentially all we need to do is hook up a route definition in the same file that we're using for our controller and just specify that it's a form. So this is a more self-documenting approach actually and we can use things like IDE or other tools to give us an idea of where we're not overriding a method or there's a method to override as opposed to having to read through the API pages or comments. So it's more consistent and better developer experience. Yeah, so this is an example of a form in DRIPLE-8. So you might notice the first thing up the top is that we're extending again from a base class, so form base. This is a helper class that you would use in all of your forms. Form base actually implements an interface called form interface that says that anything that implements this interface must have these methods on it. So the first one is get form ID. So that's a unique name for your form. In DRIPLE-7 this was the name of your form builder function. So that's not a magical kind of mechanism anymore. We can explicitly define what the unique idea of our form is and then we've got the standard kind of functions that you would expect. They're not magical names in terms of putting, you know, like underscore submit or underscore validate on it. We've got one there for building the form. I should say that the form API hasn't really changed much in DRIPLE-8. It's still the same bunch of arrays. You still do exactly the same thing, except now it's inside, you're building that inside an object donated class, not PHP object. And we've got methods there for submitting the form. There's also a validate form, which is optional that you can implement, which is also part of the form base. Okay. And then to hook that up into our route, so we wanna have that form be visible through a URL. It's very similar to our controller example in the beginning. The main thing you might notice is that we've actually got a different key. So the other one said control content. This one actually says form. And that just makes sure that it goes through the usual form building functions when we're calling that route. But pretty much identical to the other example. Okay. So one of the big changes is that hook menu is actually completely removed now. So no hook menu in DRIPLE-8. So what's left over? We've still got a few things that weren't actually, that were all in hook menu. Well, thankfully they've all been split out. So they're all managed independently or separately now. So yeah, we've got default menu links, local tasks and local actions. So let's have a look at those. So they've all been moved to the YAML files. So this is consistent again. You can see there. Can you see? I can't see. So essentially, like all YAML files, we've got a unique key for our menu link. And you might notice that we're actually specifying the routes that we're actually using in there by their unique key as well. So we're not using the paths. Again, we've got a way to identify that. And again, so that just means that we've got one more level of abstraction around the actual URL. So if we change it once, it will get changed throughout the system. And you can see you've got keys in there for wake to be able to move things around and those sorts of things. So these create default menu links. Local actions are the same. That's like the plus add new content kind of thing. Again, unique keys there and we're actually specifying the root name and also what root they actually appear on. So that's the page that you want to see them on. And similarly, local tasks. They're the tabs that you see on the page. So you can see a consistent pattern there around how we're using routing. That's right. So basically, this is the ability of these routes. We can actually, we mentioned this earlier. So you can actually have the same route respond to or return different results based off some things like the accept header or the method that you're actually trying to get. There's some documentation there if you want to go and have a look and we'll provide links in the slides. All right. So next up's the configuration system. And this is going to effectively replace the variables table plus features or more accurately, C tools, exportables. It's kind of inspired by that but it's all being brought together into a consistent API and it's going to open up easy deployability and just consistency in general. So let's have a look at that. So in Drupal 7, we had pretty much just one way to configure things which was the variables table plus we could access that through settings PHP as well for overrides, but it was a pretty simple system and you had to kind of put serialized arrays into it and it was a bit ugly and... Yeah, it was getting used for a lot of different things. A lot of things are kind of being munged into one thing and that's actually been cleaned up a lot in Drupal 8 so we've separated some of those things into different APIs. So first up is kind of like the simple config stuff so that might be what you would normally use if you're writing a custom module, you may want to save your settings then you can use Drupal config. So the top example is your, I guess, if you're in procedural code but you could actually use dependency injection if it's in the controller to pass in a config factory so you don't actually have to call that slash Drupal config function at the top and essentially you've just got some pretty basic functions that are getting caught on that, so get and set on that. So that's for your classic kind of basic setting stuff. So the way it works is that there's other sessions I should mention on some of this stuff that you might have seen as videos available. We won't go into too deep dive on the config system here but essentially you've got an active store which is where all of your current config lives and a living system and the concept is that you've got a staging store as well. So if you're working locally and you're developing some changes, you can export that config, push it up to production server and load that config into your active store. So that is imported and exported using YAML and we've got things like, we've got the UI in Drupal 8 to be able to do that and tools like a diff to be able to see what has actually changed. So that's changed a couple of times. It is in the database at the moment but that actually doesn't matter. It was in files, the active store but it's definitely in the database but it's still the same process. There's an export and import system. And because it's all loosely coupled with services, there'll be a lot of people who might want to swap out the config active store with something like Redis or some other kind of key value store that they can use in a production environment that's gonna be more performant than a database. Okay, so what you typically do if you're building a module, you might use your module settings form that's not there anymore in Drupal 8. Instead, you would create your form class but instead of just extending form base, you can extend a class called config form base and that gives you a few helper functions. So this is just a simple example where you would essentially what you need to do is build your form and then just before you return just call parent build form. And what that does like the system settings form function in Drupal 7 just adds things like submit button to the form and what theme to use. It's just a few basic things. And then when you submit your form, again, you'd save your config before you return and then you'd call parent submit form and what that would do is basically do things like show you a message that says your form, your settings have been changed. It's not doing a hell of a lot but it's just gonna take out some of that stuff that you do every time. I should note that in Drupal 7, system settings form actually just copied all your form values and saved them as variables to the variables table. That isn't the case currently in Drupal 8, you kind of have to do the config stuff yourself. Yeah, so this is basically calling the parent build stuff. All right, complex config. All right, so this is where configuration entities come in. So these are things like views, rules, all the stuff that we would store in custom tables and then use things like C tools, exportables to help us deploy them. We have a core API now to handle that and it's consistent. We don't need per module workarounds. Everyone can use the same system and it has two interesting features. One is that we can treat them like entities when we're dealing with them. And then of course we can export them just like the simple config and deploy them. Yeah, and I should say that this is all shared all across core. So we're using the same API for everything. So things like fields, node types, block types, image styles, views, built formats, all of that is using the same API. They're all config entities. And we've actually got a unified entity API. So we've got a concept of content entities, which would be your nodes and those kinds of things, and config entities. And we've essentially got a unified API around that. So the same functions calling on those objects. So it's gonna actually be a huge developer experience improvement because it's just gonna be consistency there around how things work. And if you learn at once, you can apply that everywhere. Again, configuration docs are available. I suggest you go have a look. They're getting fleshed out at the moment. I should also add that the workflows for how you actually do deployments aren't really prescribed in Dripalate. Essentially that I think will evolve once people start building sites and finding new ways to do deployments. There has been some discussion about how this would work, such as committing your staging config to a repo and then doing a git push and then pulling it on the server. But Core doesn't really tell you what to do. It's just essentially providing the API. And I think all of those tools will evolve in contrary in the coming years. There's some videos online of people doing different versions of it. Or if you wanna check out the Drush 7 presentation by most fightsmen from this conference to see how it might be done with Drush. Also the config has actually got translate support or multilingual support. So I'm using schemers to define what all the keys in our config are so that we can actually provide translations for all of those so you can actually have multiple versions of config. So as I mentioned before, instead of just using the variables table for everything, we've tried to split out some of the core concepts. So if you're using the variables table just to store some temporary states, so an example might be a menu rebuild is needed. There's a new API for that, it's just called state. So you can just set that and it's meant for simple cases. And there's also a settings API. So that's essentially just calling a direct wrapper around the settings.php file. So if you ever previously were just using variable get and assuming that the settings php file was overriding what was in your config, now you can actually just access that directly with the settings API. And the confere is still there, so yeah. Okay, so plugins. So I think you should always, you can basically inject anything that I've got here where I'm calling static functions like Drupal, consider those that they can be dependency injected. There's still procedural code in Drupal 8. So anything that's in the dot module file is not PSR4 essentially. But if you're creating a controller or a form, then that is object oriented and you should be dependency injecting all of this stuff. So the answer I guess is that there's two ways of doing it. And you should choose one way. Use the right context. Okay, so plugins. There was a great session yesterday on plugins. If you're interested, we might go into too much depth now but just to give people who didn't see that just an idea about what plugins are all about. Essentially, we're not using hook info anymore for a whole bunch of things. So previously, we would be defining, providing some default settings for things using hook infos. It's all declarative stuff. And those are pretty much all being replaced by plugins. So anytime we wanted to have our module be extensible by other modules, our main core way to do it was things like registration hook. So hook something info. And that's what we're really replacing with the plugin system. If you've ever used Ctools plugins, it's a modernized version of that but definitely inspired by that. Yeah, so basically, previously we were using random hooks and now we're actually using real objects and interfaces. And again, this is spread throughout core. So plugins have been taken on and replaced a whole lot of inconsistent ways we were doing things all across Drupal 7. They're all in our nice consistent API. So the obvious place where this has improved is that you'd be familiar with as a Drupal 7 developer is registering a block. So you register a block in an info hook and then when you need to view that block, you only have one hook available in your module. So you need up a switch statement and then if you have five blocks, you have five ifs, elses or switches and so it's a bit unwieldy. So now we have a nice clean system. We can have one plugin per thing. So basically this is how a block would be done. In Drupal 7, hook, like info, view, block configure, that's a lot of things. So in Drupal 8, essentially all of a single blocks configure, the code is all in one class so it's nice and self-contained. And that basically means that it's just gonna be easier to work with. It supports, well it uses interfaces so again we've got good IDE support if you're using something like PHPStorm, something like that, you're gonna be able to make sure that your class is calling the right functions. And this is just a simple example but this is how you'd write a block now in Drupal 8. So you might notice that we're using PHP annotations. So we've got a block annotation type. We just need to provide an ID, an admin label and a category for it. And we're basically just extending block base. So the annotation, just get discovered by Drupal. It knows that it's a block. It can put it into the list of blocks that are available. And then because we're extending block base, we need to implement certain methods in order to work with that block. So block build, block save, block configure, all of those are defined in the interface. Block base gives us some nice helper methods in there to make it simpler, so you don't have to write boilerplate code for everything and that's it. Yes. You will always need to write build. So block base might give you some helper methods and it might give you some support for things that are optional. But you're always gonna wanna build a block because otherwise you wouldn't get anything back. So that would probably be one where it's in the interface but not in the base class. So the basic pattern is to satisfy the interface and then sometimes you'll have default, sensible defaults in the base class that you can override but optional. So I think form validation was one example. There's a validate form method in the interface but the base class provides just always passing validation, so. Okay, so again, the advantage is that we've got base classes, we're working with objects, we've got inheritance and we've got one file per plugin so we're not having to squeeze a whole bunch of logic into switch statements if you've got a single module that's got multiple block types. Okay, so as I said before, there's lots and lots of plugins. Plugins are being used for everything in Drupal 8 so things like image styles, widgets, formatters, views, heavily used as plugins, field types and essentially once you kind of understand plugins you'll be able to apply that throughout anything that you're doing. Okay, so we're gonna just briefly look at entities and fields. That's a field, entity, I don't know. I guess you didn't get it. So I mean, there's been a whole lot of cleanup in the entity API and the fields API and there was a great session by Fargo, I think it was on Tuesday. So I encourage you, if you're interested in looking deeper, go and have a look on YouTube and find that. They have a great session on the API changes and basically in Drupal 7, custom entities were pretty painful, they were quite difficult to, even though suddenly there was this API that you could use, you could go and build your own entities, there was still quite a lot of work you needed to do and most people would typically avoided them. No, basically half finished was the problem and you should definitely check out Fargo's presentation but finishing the entity API was a goal of Drupal 8 and seems to have gone very well. Yeah, so entities are first class objects now with interfaces instead of a bunch of hooks and classes can be swapped. We've got a common and a consistent API around that now. We've also got some new field types, so these ones are all in core now, so link, email, comment, or comment is still being worked on. It thinks like entity reference, so I mean that's hugely powerful if you're doing, you know, data modeling in Drupal to be able to use that. That's all built in, we're actually using entity reference for a load of things in Drupal core now. And part of the mobile initiative was to add things like telephone support so that you can have telephone fields. Here we go for time. So basically, we've got a new concept which is, you might have known that in Drupal 7 you've got things like display modes. Now you've actually got support for creating those directly in Drupal 8 and also additionally you've got form modes so you can actually have multiple forms for a single entity. So if you think of things like the registration form you might wanna have, when a user signs up you wanna only show a couple of fields but then when they go and edit their profile you can have a whole lot more. They're called form modes now so it's a nice clean way of doing that in Drupal 8. The properties are treated consistently as fields now as well so you can use widgets and formatters on them. Yeah. Okay, so these are all plugins so we're using those APIs and we've got first class objects so if anyone's familiar with the Drupal 7 way of doing it now you can do it in the Drupal 8 way down the bottom which is a hell of a lot cleaner. I never really, I always had to check what the actual syntax was when accessing that so it's a lot cleaner. The APIs cleaned up quite a lot. So. Yeah. Multi-value. Yeah, so if you don't use a multi-value it'll give you the first one if it is a multi-value or you can just use square brackets to access a particular one. Okay, just a few changes. We won't go too much into the front-end stuff but I think the significant changes are around that we've swapped out PHP templates for Twig. There's been a couple of sessions on Twig which you may have seen already but essentially it's just a simple name change if you've got your template file you just rename it to with the HTML.twig at the end and I think one of the big benefits is that we can actually enforce like a clean design around it so we're not actually calling PHP code from our template files anymore and it's a simpler syntax. So this. Go see Morton's session. Yeah. Is there a session? I think it did a lab. A lab. It's doing lab, yeah. So basically we've just got simple printing out variables. We've got some if-end-if statements which is basically, we've got some shortcuts, we've got loops, those kinds of things. We're not executing any PHP in there. And one of the big things for module developers is that the theme function's actually been deprecated or has been removed in Drupal 8. So if you were calling theme inside your module code in Drupal 7, essentially what you're doing is you're turning it into a string and then from then on, anything that kind of wants to access it afterwards can't really modify the data structure. It's too late, it's already turned into a string. So what was agreed is that just encourage using render arrays as much as possible. So now it's the only way you can do it. So instead of calling theme and then calling a theme function, you just return a render array and you can actually pass in what theme function you want to call. You can do this in Drupal 7 now. It's just enforced in Drupal 8. Another important thing is that Drupal Ad.js and Drupal Ad.css are gone. We actually have to declare the dependencies now with a library's API. So that again is in a YAML file. So basically there's two steps. First thing is you declare your dependencies and then the second step is on the page that you actually use it. So you use returning a form array or render array. You use the attach function in your render array to specify what library to include. And the main reason for that is basically performance improvement on the front end. So instead of loading jQuery on every single page load, you only load it now on the pages that actually need it. So there's gonna be a huge reduction in that. There's actually work still going on to integrate with ascetic, which is another way to try and optimize these files further. So this is an example of in your module you just create this libraries file and all you're saying is that your module depends on jQuery or core Drupal. So that's your library definition for your module. And then again when you're returning a form array you would just specify that you're gonna attach your library and specify the name of your library and that's it. So that will load your JavaScript in your CSS. Okay, so just a few final thoughts to wrap up. I think the main takeaways I want you to have if you're not familiar with Drupal 8 is that there's a lot of complexity now under the hood. So there's been a whole lot of code Adam we've got external libraries. There's a whole lot of functionality going on under there now. I mean they changed us to the routing, to how forms work. We were using plugins everywhere. Got a whole new configuration API and totally revamped entity and field APIs. But I think, and Dries did mention this in his keynote the other day. We do, even though we've got increased complexity under the hood I think we've actually got a much more simplified developer experience. The API is gonna be a lot easier to work with because there's less kind of magic going on. A lot more explicit declaration of what you actually need to do and consistency across everywhere. Yeah, so I guess we've got any time for questions? If you want to have questions just come up and use the mic. So we can record you. I was on my way back but it just worked out perfectly. When you were demonstrating, extending the controller base and the replacement hook menu there was a bit I didn't quite get. One of your functions took as an argument it said connection and then database. What was that about? What was that accomplishing? That was to show how dependency injection might work. So something rather than calling out to a database function you would actually inject the dependency into the object that's gonna make that call and that lets you do things like if I'm writing a test for that class that can control the class I can have a dummy object that gives me results that I want and I can test that class in isolation without actually having a database. That was meant to illustrate. So connection was the name of the class but it's just the way that it's named it's the database connection so it's a pretty common pattern in DRIPLE-8 just to call that connection database instead of connection. So yes that was type hinting actually which I think we didn't really explain is if you haven't seen OOP-PHP you can actually enforce a type of an object that you're accepting so that the variable that we're accepting was called database but the type was connection so we're only gonna accept connection or children of connection objects. Okay thank you. I have two questions. The first one, with the manual router or the new changes, what about wire cards? Are they working the same as DRIPLE-7? They work slightly differently. So in DRIPLE-8, you can have placeholders so you can do the same thing. It's got the same kinds of things there although there was something that was a little bit complicated which is we don't have the automatic path extensions when you can add extra parameters to the end of your URL and they get converted to arguments so I think for most of those situations you would use a query string instead now. So you could still do things like node slash and then put node ID or a node as a parameter and you can use curly braces to find that that's a parameter but it would only take arguments that have node and then a number. It's not gonna take node and number and then slash something else or something else. So that's just a limitation of what the symphony routing system supported and actually created a whole bunch of complexity the way that we were doing it before. And I think most of those symphony documentation is good for that topic as well so you could look that up there as well. Okay, and the second one is, is there any change or any new things related to performance and cache and I don't know, different kind of aggregation, the off cache, anything that was thought differently to make it easier for things to be cached? Yeah, there's been a lot of stuff added in terms of caching so I should say that at this stage in the Drupal 8 Cycle that's the kind of area that's been worked on still so there's still performance optimizations going and they'll probably continue to go until the final release but there is caching API in Drupal Core and mostly, yeah, so basically that's an extensible system as well so you can actually cache, you can call the Drupal cache or, and you can replace the caching subsystems with different cache pins and those kinds of things so you could kind of, you could do the same sort of thing in Drupal 7 but it's object oriented now, it's in a cleaner way, it's a nicer way to do it. Okay, thank you. So with the movement away from the hook system in a lot of places and definitions in YAML files, what happens to alter hooks? Alter hooks haven't gone away, they're still there so there was some talk about moving everything to symphony events, I think that was probably just a bridge too far in terms of the changes so we've still got hooks, we've still got alter hooks, they're still in there. I think it was the kinds of things that moved away from hooks were those kind of metadata type hooks so like hook block info was just really providing some definition of a block but hooks are still widely used and there's still a way that you can extend and use hook alter to modify forms and those kinds of things. You mentioned that theme was deprecated, the theme function, but in the render array you still have the theme parameter and so you're still defining theme underscore item list or theme underscore whatever, that still is how you create a theme. Templates only. Templates only, so if my module wants to provide two or three different themes I need to put the, I need to... Yeah, so you would still do it the way that you do in 777, so you've got your theme registry, so you define what your theme functions are. The difference is that you, and they're called theme hooks, so you basically say these are my theme hooks that I've got and you specify what template each theme hook uses and what variables it uses, that's pretty much the same. The difference is that you used to be able to write a function to render that as the theming function, you can't do that anymore, you need to have a template. So those template files then go in the module? Yeah, that's part of your module. Okay, great, thanks. I'm not trying to be mean in public, so this is coming from a good place. Your example for dependency injection, your database type hint should be, or your connection type hint should be an interface, right? Rather than, or that's your intention there, that's not actually a class. Correct, correct, correct, I misspoke, yeah. No, that's fine. So my real question is, do you know all these base classes that are abstract? Kind of inheritance is a really, really rubbish model of composition in certain circumstances. Is there plans to sort of move to using traits rather than base classes? We're actually using traits for a lot of things now that came fairly late. Only in the last six months have we started moving things over to using traits. So you might have seen the T function, moved to this T. So that's moved to traits now because a lot of the base classes are using that. So anything that's common, so anything that's in form base that is common is being moved over to traits, yep. Good point.