 Welcome, everybody. I hope that you're in here to learn about how to upgrade your modules to Drupal 8. If not, this is going to be a really boring talk. So about me, my name is Webchick, or Angie Byron, as I'm sometimes known in law offices and stuff. I work at AQUI in the Office of the CTO. Drees is my boss, which is really fun. I'm a board member for the Drupal Association. I wrote a book about Drupal, and I'm the engineering manager for the Spark team, who's working on making a Drupal authoring experience awesome. And if anybody here knows anyone from Brisbane who might think it was cool to work with really high-profile clients as a client advisory, please go to our booth outside, just outside this door, because AQUI would love to hire you and pay you money for that. So our agenda is we're going to do a little bit of a walk through the module that we're reporting. We'll cover some basics that apply to every type of module. We'll also cover some of the main thrust in Drupal 8 as you're coming to it from Drupal 7. So there's this funny thing called PSR0 and also PHP namespaces, which might be new to you. The configuration system is new in Drupal 8. Blocks and plugins are also very different in Drupal 8 than they were in Drupal 7. The router system is also very different. And then finally, twig, which now that Jen Lampton's in the audience, I'm really nervous about, but I hope that I converted it properly. But twig is a new theme system in Drupal 8. So lots of new stuff to cover. So the first thing is that we will not be able to port this entire module in an hour. That's just not going to work. But if you're the type of person who likes to take homework home with them, this page on Drupal.org has a list, like all my notes, of every step that I took through the whole process. And they're also git commits for every single step. So if you wanted to kind of take time and analyze how this works on a one-to-one basis, that's out there for you. And I'll make sure these slides are up on the website shortly so you can get that too. The second disclaimer is that all of this stuff is heavily under construction. So I'm going to tell you something today, and it's true right now. But next week it could not be true anymore, because that's how fast Drupal 8 is changing right now. But it's still really good, particularly right now, where there's a lot of backwards compatibility layers still in place to sort of get your feet wet with Drupal 8 because there's still time to change it. And you can have a lot of influence on the direction of Drupal 8 still. So the module that we're going to port is the pants module. Woo! Pants module is actually a blast in the past. So this was a presentation that James Walker gave in 2006. So this was a Drupal 4.7 module that I ported to Drupal 7 and then had to port it again to Drupal 8. So it was a bit of a process. But it's great because this little module has everything. It's got permissions. It has a settings page. It has form changes. So it goes in there and monkeys around with forms. It has a user profile change. It has blocks. It has automated tests. Everything that you could need to know. So it's a really good example module to kind of expose you to a lot of the different APIs in Drupal. So let's go ahead and see this in action and see how it works. By the way, did you know that you can Google for literally any noun you can think of plus pants and someone has done that? I mean, it's amazing. All right. That was action pants, by the way. All right. So I've got a few too many windows. This is the pants module project page, by the way. So if you want to, my resolution is terrible. Anyway, so if you wanted to get to that documentation page, you can just click read documentation. Or if you go to the repository viewer down here, this is where I have these all broken out into steps. So you can start with Drupal 7. You can go to date.x, want to do basics, test, config, blocks, router, twig, and all the steps along. So if there's anything I like doing, it's over-engineering something very much. But anyway, hopefully it's helpful to somebody. All right, so let's look at our Drupal 7 site, sporting the non-responsive toolbar. That's always really, really sweet. So we'll just walk through the pants module really quick. So how the pants module works is if you go on your user profile and you click edit, there's a little checkbox here to ask you, are you wearing pants? OK. And of course, I'm not wearing pants. That's why I'm standing behind a podium. And so I'm going to take that off. And then it'll tell me my pant status is currently off. I also have a nice little Ajax block where I can go woo, and turn it on, and then I reload, and now it's on. Oh, right, that I didn't even show you yet. This is cool. So if you go to configuration, pants, you can specify what pants type. So there's MC Hammer Pants. Yeah, yeah, OK, let's do that. And then this Pants API key doesn't actually do anything, but I need an example for later. But say you were integrating with the Pants API, which I'm sure someone will invent by the end of this presentation, then you could use that. So if I choose MC Hammer Pants, now I have awesome, gold MC Hammer Pants. So, this module is great. And then there's a recent pants block that tells me all the times I took off and on my pants. OK, so it's kind of a dumb little thing, but it's a lot of fun. And so the other thing that it has is automated tests. How many people have written automated tests before? Oh, good. It's a really good idea, actually, to write automated tests before you start porting stuff because it's a really great way to tell if you've actually got it yet or not. So, I'm gonna run the Pants tests. I, of course, have two different versions, CRUD on your pants and UI on your pants. So I split them into two. I'm gonna run those and just let that go for a while. So I'm assuming if you're in this room, you are a module developer. Can I get a show of hands for modules? OK, great, because I can't really spend time explaining what hook menu is and things like that, but we'll cover through a lot of this stuff pretty quickly. But anyway, so the automated tests are running. La da da da da. And then finally, eventually, someday, hopefully, it'll say, dude, seriously. So one thing that's cool is in Drupal 8, we have a testing profile, which makes this all much, much faster. So there we go. 70, excuse me, 75 passes, zero fails, zero exceptions. Wonderful. So this is our lovely working Drupal 7 module. So let's go ahead and look at how we would do this in Drupal 8. So the basics. Underwear pants, OK. First, you grab a copy of Drupal 8. You're gonna wanna do that from Git because we change it 50 times a day and you're gonna wanna always be on the latest version. You wanna copy the module. So in Drupal 7 and below, you know how we had that thing was like, if you're gonna put your module somewhere, you put in sites, all modules, because only an idiot puts things in the core modules right here because that would just be stupid, right? And you like mock people who don't do that, right? So in Drupal 8, we created a core directory where the core modules go, and now you actually do put your modules in the root modules directory. Wah, wah. So it's like the opposite of what you're used to, basically, but yay, the drop is always moving. But this is actually kind of a nice change because people wanted to do that anyway. So now it's just sort of natural in terms of what people are gonna do anyway. So you take your module and you stick it in the root modules directory for Drupal 8. Then the next thing you do is you change the core version. So on the info file, there's a core equals 7.x, you just switch that to an 8.x, and until you do that, you get this little x that won't let you turn the module on. And then you turn it on and see what happens. I lied, I do have a cat. Yeah, a cat. And then you find your errors, you search for them, and then you repeat over and over and over again until your module's working. That's pretty much it. This page is amazing. Drupal.org slash list hyphen changes. This is where every single time we make an API change in Drupal, we create a critical task that people have to fix to make sure that it's documented in this list. And I went through this whole thing with all these different APIs and honestly, I think I maybe made three pages that weren't in here and there was like 50 of them that were. So that was actually really, really cool. So yeah, so we'll go ahead and walk through that and see that. By the way, if you get stuck, like for example, Drupal's barfing out horrible errors at you, probably what happened is we changed the APIs on you. So you need to just reinstall your site from scratch because we don't have an upgrade path yet, sorry. And when you do that, there's a special thing you have to do in Drupal 8, which is you have to not only get rid of your settings.php, that's normal, but you also need to remove everything under your files directory. Because in Drupal 8, the files directory contains both a symphony compiled PHP thing or thing. I don't know, ask Larry Garfield. And the configuration files for your site. And if you keep those around, they can get stale and can cause problems. You'll do this a lot, by the way. All right, so let's go ahead and see this in action. So let's go over to our handy dandy command line. All right, where am I? Right. So I'm gonna go to my sites, Pants 8 folder. Are y'all command lines savvy? I'm hearing nods. I'm hearing nods. I'm very tired, okay. All right, so we're gonna go into our modules directory, our pants directory. And here's just the Drupal 7 version of our modules. You can see there's a pants.info, a pants.install, JavaScript, module, test, et cetera. So let's start, actually, by seeing what happens if we go on our Drupal 8 site. By the way, this is the new responsive swishy toolbar. Woo, it goes like this, and it's all fancy with the icons. Okay, sorry. We worked really hard on that, and so, right. So let's go to extend. By the way, that's what we renamed the modules page, much too, that was a little contentious, anyway. But people couldn't figure out what modules were, so you know whatever. So right now it's telling me you can't turn the module on Bozo because you just put a 7 module on your Drupal 8 site. How stupid are you? And I say, very stupid, but I'll show you. All right, so I go into pants.info, and I just do what the presentation said, which I turn this to 8. Okay, everybody got that. So core equals 7, now it's core equals 8. And then just like that, the magic of text editing. Ta-da, there's a checkbox now. What do you think is gonna happen when I do this? Hammer pants, maybe not yet. White screen, yeah, check this out. Nothing happened. It worked, okay, maybe not there. Okay, so that's great, it didn't blow up. Usually it does blow up, so that was a really good guess. But it did in this time, so that's awesome. And in fact, there's actually a surprising amount of this module that works even right now. So if I go under the, say if I go under the permissions page, you know, I scroll down to my pants. That could be taken out of context so badly. All right, so pants, I still have my, you know, I still have my permissions, that's pretty cool. You know, if I go to my configuration page, this is temporary by the way, but I see that my administration page is still there with my form. So there is some stuff in Drupal 8 that didn't change. There's a couple of things. The form APIs stay the same, the database APIs stay the same, the permissions APIs stay the same, a lot of this stuff. So it's not like you have to rewrite your entire module from scratch. But there are a lot of changes that you have to make, so we'll start walking through this. All right, so then you're like, yeah, yeah, yeah, but that wasn't what the module actually did. What the module actually did is it, like, lets you go in your user profile and do some stuff. So let's go ahead and, you know, check that out. So I'm gonna go to my profile and close that. So I get this weird off, just in the middle of the page somewhere. That's a little odd. So it looks like it's missing the label for my pant status, okay? So that's kind of the first indication something might be up here. So let's go into the module code. And I'm gonna, spoiler alert, that happens in hook user view. So there's this thing, you know, like this renderable array or whatever that's like, okay, you've got a content of pants. It's a user profile item, pant status, and then you theme your pant status. So the pant status is ending up there okay, but what's not ending up there okay is the actual title. So what I might start doing is I might start going, well, hmm, I wonder what's going on here. So I might start looking for hook user view. That might be a good thing to do. So I'll go over to. It's probably as hideous for people's status. What's that? That's not. Oh really? Sorry. Well, that's all fancy. You know, I'm just a simple gal, but yes, okay, fair enough. So most the render API maintainer has informed me that my pant status is douchey, and I should not be doing pound markup at all, and I should be doing a renderable array there. So bear that in mind. But in the meantime, I searched for hook user view and I got a couple of things. One is that type user profile item is now type item. So that would do it right. If I'm using a type that no longer exists, that might cause a problem. So let me try. Oh, I lost my place. So let me try leading that and replacing it with that and see what happens. Okay, so just a little one line change. Let's go back to here. Reload. Wow, we have a label now. Pointing to Drupal 8 is easy. Yay, okay. So cool. Now let's take a look at our form. So we're gonna edit that. Oh God, errors, geez, what is that? All right, so undefined index, user category, blah, blah, blah. So the first thing I might do is say what the heck is user category? So I go back to that magical Drupal.org list changes page that I mentioned. Now I'm gonna search for user category. And it says the category system is removed from user edit and view. So I click that. And it has a nice couple of examples. So in Drupal 7, you might have this form alter that would check if a form user category is a count and blah, blah, blah. But instead it's saying, oh, you know, like, don't do that. Just take it out all together. So what we used to do if form user category is a count because the user profile forms used to be like, there was a main profile form and then a bunch of other sub forms was very silly. I think most, did you, were you the one who got rid of that? Yeah, good job. So now, so now it's way easier. And if all these changes are really cool because it'll link you back to the description. So if you wanna read the whole discussion that happened, like why did they remove the user category system? That was pretty great. They'll give you all the reasons for that. If you have a lot of time on your hands, I wanna learn a lot. So I'm going to see, where is that user? What? That's not gonna work. Thanks. So I'm gonna look for user category. All right, and I'm just gonna basically take out any, whoa, not that bad. But I'm gonna take out any reference to that user category thing. So now this just becomes if user access is pants or whatever. I'm not gonna do this for the whole presentation, but at the beginning, I think it's important so that you can kind of see how this iterates. All right, so I did that. I'm gonna reload. By the way, what does the form look like right now? Basically, it doesn't look like anything. Our pants thing is completely not here. So if I reload, now I see my pants thing showing up. Great, although it looks a little funny, like see how these all have little dropdown thingies and this one doesn't? That's a little weird. So what I might say is that's odd. Why did my field set end up like that? So I'd search for a field set. And then I would see, oh, all collapsible field sets have been replaced with the HTML5 details elements. So this was another initiative in Drupal 8, was the HTML5 initiative, which introduced all these new crazy HTML functions. So we have, I don't know, we have all kinds of things. We have rate, like not rate, but we have email fields and number fields and crazy stuff like that. So basically all I have to do here is change it from a field set to a details. So let me do that real quick, field set. But you notice everything else about hook form altar is working fine. Like it found the form, it replaced the thing, it's all fine. So it's not too bad. Not yet, anyway. All right, there we go. Now it's all swishy and spanky and lovely. So I'm gonna say, yes, I am wearing pants and let's save that and see what happens. Oh, more errors. So now it's saying parameter one to pants for user presave expected to be a reference, blah, blah, blah. Okay, I don't know what that means, but I know what that is. So I'm going to search for this. Pants user presave. Oh crap. Oh no, that's not gonna work. That would be cool if that worked. Hook user presave. It's linking me again to that thing that I, oh wait, no, this one. The edit argument was removed from hook user update and such and such and such. So hook user presave used to do edit account category and now it just does account. So this is another fallout from the removing the user category system. So okay. Let's look for edit under presave. So what I'm gonna do here, and again, I encourage you to look at all these pages in more depth. I'm just trying to make sure we can get through our agenda today. Oops, there's all my private email. Gonna remove my edit and it's recorded. Someone can still screen that, yeah. All right, don't get any bright ideas people. All right, so I'm just going to take account in there, but then the problem I have is that I'm still referring to things in edit, which is gone now. So these just end up changing to properties on the object. And I believe that's in that page somewhere or else I frigged around with it long enough that I figured this out, but anyway. So you do this. Looks good. Should we try it and see what happens? Dun, dun, dun. All right, let's go back here and turn my pants on, save. Oh, that looks promising. Should we see if it worked? So I should have my pants on and I do. Yay, and let's make sure I can turn them off again because of course we love having our pants off more than they have it on. Yay, it's working, yay. Oh, that was a great session, huh? So, you know, feeling pretty good, right? Getting the hang of this. It's tedious, but it's like you go around, you find an error, you google or google, you list changes for it and you find the thing, you read up on what the change was and why it happened and then you use the code examples to change the code. It's pretty straightforward. But don't worry, it's about to get a lot worse. Those are worse pants, by the way, that's the Google term. All right. Oh, is that what I can? Yeah, it's pretty terrible. All right, so one problem that we have is our tests aren't showing up. Like, if I were to turn on the testing module and go to the testing page, I wouldn't actually see pants. Well, I can just do that, I don't have to tell you about it. So if I go here and I go to extend, and I turn on the testing module and I save it. There we go. If I go under configuration development testing, then what I'm gonna find is that nowhere in my list of alphabetical things is pants. It goes right from pager to param converter. And so it's not finding my classes for some reason, so something's up. So let's talk about that. So in the olden days in Drupal 7, we had a class loader that was like this. You'd have your example.test, and then you might have a few different classes in there. And that would just be right in the base of your module directory, you could put in another directory, whatever you wanted to do. And then you would also have this info file where you'd add a little files entry to example.test. People familiar with this construct? It's called the registry in Drupal 7. So the problem with this is it's a Drupalism. You don't do that in any other software that you've ever used in your entire life, probably. It was very, Schicks invented that. It was very unique. Unique. So in the rest of the PHP world, they use this construct called PSR0. So PSR0 is basically an auto loading standard that was developed by the PHP Framework Interoperability, I can't say that word, group, which basically takes PHP people from all over different projects and brings them together and tries to decide on standards that would allow for better reuse between projects. Great idea. Horrible execution sometimes, but whatever. So this particular standard PSR0 is the auto loading standard. So they basically developed a standard way of structuring your directories and file names and things like that so that you can develop these auto loaders that work seamlessly between projects. So it's a good idea. Here's what it looks like in practice. So you have your modules example. Ready for this? Boom! And then you have a lib Drupal example test and then you have to split your two tests out into two separate files because every single class can only have one, or every single file can only have a class in it. But you don't have an info file, so yay, it's probably found elsewhere. So this really screwed me up the first time I was doing, but there's a lot of things that get stored into this directory so it's a good thing to know. So the naming convention is lib and then Drupal because that's the name of our application and then your module name, lowercase, like your module is, and then whatever after that. And there is different types of PSR classes. I'll get into that in a second. So there, oh, I don't wanna do that slide yet. There's different types of classes, plugins, tests, lots of different things go in there and we'll get into a few of them in this presentation. So then namespaces is another thing which is a PHP 5.3 feature. So what this is trying to do is by default, everything in PHP is in the global namespace so what that means is you do find a function anywhere. You can't ever define another function name the same or you blow up with fatal errors. Anybody ever done that already defined? Yeah, I do that on a minute basis in PHP it seems like. So what namespaces let you do is they say, this file is only in this particular context. So it's very similar to what other languages do. We have to import like say the Python math libraries before you actually use the math libraries so that way you can name a function called add in your application doesn't blow up with something else. But the disadvantages is a little bit weird in terms of what you have to do. So you have to put at the top of your file any dependencies that you have on anything that's object oriented in Drupal. So here are some examples. So if you're calling any kind of specific library in Drupal like the cache system or the database system you have to put a little use statement at the top to point to it. If you're dealing with entities, if you're dealing with blocks, if you're dealing with different types of components like the testing stuff, components, libraries, all these kinds of things, more and more Drupal 8 is heading in a very object oriented direction which is a good news for a lot of people but it's also a big adjustment if you're very used to Drupal 7 works. So let's see what that looks like in action. And this one I'm not gonna do step by step but I'm gonna cheat. I'll show you how you can cheat at home. So if you do a git branch you can see a list of all of the branches that are available in this git repository. So I'm just going to git, check out 8.x02 tests just so we can skip ahead. Oh, shut up. Okay. So the first thing that you'll notice that's different from here is we now have this lib directory. So we have lib, Drupal, pants, tests and then in that directory there's now two different files. There's pantscrud.test and pantsui.test. And the reason I had to do that is because before those were two different classes in the same file but psr0 doesn't allow for that. It only allows for one class per file. Does that make sense? Okay. Then inside one of these, like let's take pantsui.test. Oh, come on dude. Oh, yeah it helps when I type the whole. Okay. And that's not what I meant. Okay. So in here I've declared a namespace at the top which is saying everything in this file is scoped to only the namespace module tests. So that allows me to freely name my functions whatever they want. They won't conflict with anyone else's as long as they haven't pulled in my namespace. But I'm using the simple test web test base library from elsewhere in contrib. Okay. Think of this as like an include once statement. Like you've all used those includes or requires or stuff like that. It's very similar to that except instead of like specifying the file name you'd specify the namespace which is a little bit better because then the file can move around wherever it needs to go but you can always refer to it by the same name. So that's actually kind of nice. And then otherwise not a lot changed here. It's now web test base instead of Drupal web test case. You can now specify the profile that it should use. So the standard profile. When you enable modules in your test you now do it through this kind of weird static modules array and a couple of other things. But more or less other than that this is just the same test code as it ever was. So it's pretty straightforward. Any questions on PSR zero or namespaces before we move on? You'll see them a lot and it just kind of takes some getting used to. Yeah. I know. Doesn't that kind of just make you go. Yeah. It's true. So he's saying the only part of this path that's in lowercase well in lib here is pants. Yeah. It's also cause it's dumb but you know. But yeah. But you know this is the same things you know other projects that people use they're coming from this and they understand that that's how it works. Yeah. Switch the windows and it doesn't matter. Yeah. Yeah would you have a comment? That's a wonderful question. And I don't remember because we argued about it for a long time and then we were like leave it and we'll discuss it later. Yeah. The key thing like he was saying is the lib folder that tell that informs the auto loader that there's classes in here. So it finds all of those and then this is just a way of name spacing it so that your tests don't conflict with anyone else's tests. That's debatable. It's supposed to. Yes. Yeah. Then yeah. That's true. The nice thing about this is that because it's directory and file base you don't have to go to the database in order to look things up or use you do with the registry. You have to check the table for what file is this in and then you come back to it. I learned about make der pee and that changed my life. Because if you're trying to like make der lib CD make der blah blah blah it takes a really long time. Anyway. So that's cool. I'm going to keep rolling because we do have a lot of stuff to cover. So great. We run the things. We find it has fails. That's not entirely unexpected because there's big chunks of the module not working yet. So let's talk about the configuration system in Drupal 8. So the configuration system is intended to get around some of these problems. So what we're trying to do is we're trying to kill the variable system in Drupal 7 and we're actually just about done. It's pretty pretty awesome. But why? Why? Oh are we going to clap for that? All right, let's do that. But why, Regic? Why do we want to kill the poor variable system? Well the huge problem with the variable table is that you're combining configuration and content in the same database. And so it's really, really difficult to say I want this part of the database changes but not that part of the database changes because I care about that setting I just changed but I don't want to destroy all the comments that have been posted in the last two hours. There's also a problem where the entire contents of the variable tables loaded into memory on every single page load so that's really expensive. And the API is limited which causes all these other modules and contribute to invent their own way of doing things. So there's features, there's C tools, exportables, there's all of these different things and a lot of times they're incompatible or they're very complicated. So the idea was like let's scrap that new configuration system bake in a decor so it works. So there's two APIs as part of the new system. There may be three by the end of next week, literally. But for now there's configuration API which is for most things. So most settings forms that you develop, you want to use the configuration API and I'll show you an example of that. What that will do is when you save the contents of that form it writes it out to a YAML file on the disk. And that's great because YAML files are just files and they can be moved around with FTP if you're lame or they can be moved around with Git or something like that if you're awesome. You can keep track of what you've changed and why you changed it and you can roll back if you don't like the way the configuration is. The state API is a little bit different. So the state API is for keeping track of various environment specific stuff. So say for example the API key for Amazon Web Services. You don't necessarily want that in the files directory in your Git repository. It's also for things like the last time Cron ran. You wouldn't want to deploy that and then the production server thinks Cron ran later than it did. So those kinds of things we put into the state API. So the config API looks like this. Let's config contact.settings and then you have a set command so you can set a different option and then you save it at the end when you're done setting all your things. And what that will do is it will save a file called contact.settings.yaml which is based off that key up there and it just puts the contents of it in YAML format. Which is, it's a lot like an info file really. It's got a couple of other quirks but that's essentially what it is. And there's two of these directories. There's an active directory which is what it actively reads configuration from and there's a staging directory. So when you're moving your configuration from your dev to your production environment you take it out of the active directory, the files, chuck them over into the staging directory and then there's a UI to actually import those. Kind of similar to the features UI. So state API, that's for stuff like update last check and that will actually store it in the equivalent of a variables table although it's swappable so it could be stored in memcache or anything else. But the key thing is that's storing way less information than it used to and these things are lazy loaded only when needed. So you're not loading the entire contents of that database every single time. So if you wanna see that in action it's pretty straightforward. Oops. Ugh, typing. There we go. So now there's a config directory in my module and a pants.settings.yaml file. And here I just have a pants type and by default it's nothing. And then it could be MC Hammer, it could be anything else but for right now it's nothing. And if I had any other settings on that form they would go like that. The API key setting on that form I didn't put into this. I put that into the state system because it's possible that you want your development server to be talking to a sandbox somewhere whereas you want your production server to be talking to actual Amazon web servers because a lot of these APIs are sometimes like rate limited and you don't want your site that you're doing a data migration practice run on to sort of run that up. So if I go to pants module and I look up that settings form there's a couple of things that have changed here. So in the past what you'd do is you'd name your elements like form pants type and form pants key and then you would call this system settings form at the bottom and then automatically everyone thing would be taken care of for you. You'd save the form, you'd save it to the variables table it would automatically read it out as a default value. It was beautiful. In Drupal 8 we make you do a little bit more work. So there's still system config form which wraps the button so at least that's consistent but you actually have to define your own submit handler for that form that will actually write the config and state parameters to it. So just something to be aware of if you're used to kind of having that magic for you in Drupal 7 we took that out in Drupal 8. The thinking there was that it's more explicit you know it causes people because a lot of people are confused by the magic of system settings form so now it's a little bit more explicit. Yep, too easy to get yourself in a lot of trouble. The worst abuse of the variables table I ever saw was a legal module back in the day because what it would do is it would take your entire terms of service so for some modules or some sites that might be 70,000 words long and it would sort every single revision of that terms of service in your variables table. So on every single page load you could be loading like eight megs of text. So this will stop that from happening so that's good. Questions on the configuration API? Yeah, yes, that doesn't work with the config API if you want a default value, hold on. Then you just have to do like a turn area operator and say if it's set then do this otherwise do that. Try it and see and report back to the class that would be a wonderful thing. It might be not that's actually a good question because it would be the question of how to differentiate real null and a fake null. So I don't actually know the answer to that question. That's a good one. Yeah. Yeah, that's true. So the default will be defined there but you can get yourself into a weird situation where like for the state API particularly there isn't anything in the table yet because you haven't saved the form and it still needs to initialize the default value. But yes, where the defaults will come from normally that's a good point is from that YAML file you put in your module directory. Oh and this is a hot tip. If you're lazy and you don't like writing YAML by hand if you make your form, or sorry, if you write your form submit function like this that will automatically write a YAML file for you and then you can just copy and paste it into your module directory. So yay, laziness, woo, okay. Efficiency, yes, that's a much better word. All right, so I'm gonna clip along here. So blocks and plugins is another big thing. The plugin system is this crazy thing that is basically a unified object oriented API for anything that's pluggable. So in Drupal 7 we had a bunch of different ways to make something pluggable. You could have info hooks that had alter hooks on them. You could have, I don't know, you could have like the, for the caching backend for example it was a variable in the variables table and it would swap it out based on memcache or whatever that variable is set to and there's a bunch of different things. So like all good over architecting software engineers we said there ought to be a way to invent one thing that solves 75 problems in a really abstract way. So that's what we did with the plugin manager. So basically there's a few different elements of this. There's a discovery mechanism where you teach the plugin system how to find your things. So that might be an info hook, it might be annotations which we'll talk about in a second or something like that which says show me all of this stuff that there is. So examples of systems that are using plugins are like blocks, entities, field formatters. A lot of different things are starting to move to the plugin system. So for example on the discovery mechanism it's like how do I find out what blocks there are in the system? And then you can decorate those finder things and you can say I want this thing to be cacheable, I want it to be alterable, I want derivatives on it which is a whole fancy thing that I don't really understand but I have a really great graphic for it on the next slide. And then a factory which says now that I've found all of those things and what they are and they've been defined, let's go ahead and create instances of them. So here's your system powered by block, here's your recent user's block, that sort of stuff. There's actually really great documentation on this at that URL. There's like seven or eight pages of the plugin system that kind of walks through everything there. This is the funny graphic. So it says your dog, I heard you like plugability so we put derivatives in your plugin so you can have plugins inside your plugins. That pretty much sums up the plugin system. It is very flexible for anything you might need but it's a little complicated to get started with it. Then annotations is an interesting little thing. We added in Drupal 8. So in Drupal 7, when you define blocks you typically use like a hook block info or hook formatter info or whatever, there's all these info hooks all around. In Drupal 8, we've moved away from defining arrays of arrays of arrays of things to defining classes and then the way that we register classes is through the annotations which is really strange to get your head around if you're like a traditional PHP developer because what it is is essentially like codifying this array in comments in PHP. And there's no syntax checking for this by the way so it's a lot of fun trying to figure out that you forgot a comma somewhere. But how it works is essentially the same information so you give it an ID which is sort of like a machine name. You give it a subject and then there's a little at translation function as opposed to the t function because apparently we just can't be consistent. And then you also tell what module it belongs to so that when the module's uninstalled it knows what to clear out. So a lot of things are moving to the annotation system because it's a much nicer syntax than having to define arrays all over the place. The other thing that they like about it is that because those are parsable they can be lazy loaded as well. So with info hooks, every time you load a module file you have to load this huge array of gunk even if you never actually need it on the page load but annotations on classes they can be loaded whenever they're needed. So let's see that in action. These are block pants by the way. Let's see. How am I doing for time? I'm not doing great for time. I might need to blow through a couple of days. Blocks, kit, and let's see what we got in here. So one thing we have is under lib, drupal. Oh, I should include you guys. Where is it? Lib, lib drupal, then what? Pants and then plug in, very good. And then, and then block again in case you forgot. Two blocks, and then finally, pantschangeblock.php, yeah. We have some work to do with this. Yeah, it's like, no, I can't, not one more block. I can't take it. So here's how that, this is the change pants block. I didn't bother doing the recent pants block because what would I turn that to in drupal 8? A view, yes. If you go into the 8.x branch of pants there's bleeding edge code that has a view but I couldn't get it cleaned up in time for this presentation, so sorry. So here's more namespaces. That's my pants plugin, block, block, block, block, block. And then it's telling me I'm deriving from block base so I need to pull that in. I'm also using the plugin system so I pull that in and the annotation system, or sorry, the translation of the annotation. So here's my ID, subject, module, pretty straightforward. And then instead of a hook block view what I have instead is a build function which essentially has everything that used to be in the old view function but now it's just called build. And you can add your JS there and stuff. Most, did I do this one right at least? Is that the proper way to define a block in the red? All right, don't ever use this presentation for anything. But the point is that you return a render array from this block and then it gets rendered out on the screen later on. And the other plugins are, they don't all use the build function but they all have the same sort of annotations describing the info file type of thing and then they all have other namespaces that they use and then they all define functions and you just implement them, stuff like that. Are people generally a fan of object orientation, object oriented code? Not many, wow. Okay, we're gonna have a fight later, this is gonna be great. It was a little weird to get used to but one thing that's really nice is unlike info files or sorry, info arrays which requires you to look on API to Drupalware and copy and paste them and sit there and twiddle with them. The nice thing about classes is that properties and methods and things that you can do are all nicely auto-completed by your IDE. They're easy to search for, this kind of thing. So the actual working of this stuff is actually a lot nicer once you get used to it. I'm still not a fan of the directory structure though. All right, so that's blocks, let's talk about routing. So symphony in Drupal, in a tree, K-I-S-S-I-N-D, no. So the routing system in Drupal, so this is the thing that takes a incoming URL request and maps it to what page callback that you go to so we use hook menu for this. So we're using symphony now. So symphony is now embedded in Drupal's bootstrap process. We're using a few different components of symphony. There's more than this actually but it relates to routing, these are the main ones I hope I got right. HTTP foundation, what that does is essentially turns every single page into, or page run through as an incoming request that gets transferred and returns a response. And just with regular HTTP standard stuff that you maybe played around with in Curl or whatever. The HTTP kernel can help manage those requests and then route them to wherever they need to go and then the routing component actually takes the URL and maps it over to some sort of code that returns some sort of output to that people who do it. Here's a nice graph that I blatantly shamelessly ripped off from the symphony site. But so requests come in at different URLs just like in Drupal, you define whatever URL that you want. Those go into a controller that sort of sorts them out. It passes them off to the symphony two kernel which in Drupal is the Drupal kernel but it's derived from the symphony kernel. And think of that as just like the lower line guts that sort of run the framework. And then what it does is it says, oh, this is an incoming request URL. Let me pass that off to the routing system. And just like in Drupal, the routing system will look it up and say, oh, that URL maps to this function except in symphony it's a class, or a method, sorry, on a class. It passes it back to the controller, back to the kernel and then it will call whatever function it is that defines the output for that page. So in the case of contact, that might be contact action. And then what it will return at the very end of that is a symphony response that then people can act on and do whatever they want to. So in symphony, how your route definition goes is like this. You have a blog underscore show, some sort of a machine name there. You define a pattern, which is the equivalent of our path. And then you give it a controller, which is sort of like a page callback in Drupal. And then you define what's called a controller class. And then you create a function that just returns some output somewhere. So to show this side by side from Drupal seven to Drupal eight. So here's an example from book module. So here's all the book stuff in a hook menu. And as we like to have arrays of arrays of arrays, it looks like this. In Drupal eight, how you define those is in a book.routing.yaml file, okay? So parts of hook menu become yamlific. I just coined that by the way. And so things like percent, percent, what that used to be those wild cards, you now name them in symphony, which is actually kind of nice. And those name things like type in NID in this case, it's very smart and will automatically map them to function arguments in those functions. So if you have a function called export that takes two parameters type in NID, it will take the values from the URL and automatically send them down to the function using the right names. It's very smart. Do you have a question, Donna? Oh, in the controller? Because those are namespaces. The namespaces go in the opposite direction. I guess because they don't want them to be confused by the ones. The other thing that the pattern to point out is that it has a leading slash, which they did in in Drupal seven. The rest of the stuff in hook menu is sort of an open question right now as far as what's gonna happen with that. They've talked about splitting apart into multiple things like a hook tabs and a hook action tabs or stuff like that or leaving it in hook menu or whatever we're gonna do. This is still sort of being fleshed out, but the actual routing components stuff that gets passed to Symphony now. So we'll go ahead and see this in action. Everyone got really quiet right here. I'm sorry. It's Symphony, it's all cool and stuff, right? I know, I shoulda. Right here they're gonna need a cat. I just know it. All right, so now what's new is I have this pants.routing.yaml file. So I had two things defined in my, well let's look at that first actually. Let's go back to the module. So here was our old hook menu. So it defined two URLs. One was just an Ajax callback for that little change link to let me change my pants. And the other one was a configuration page, the form that we saw. And so one thing that's interesting about this is like my Ajax callback, if I go and look at that function, wherever the heck it is, it's apparently a horrible thing too. I have to do this janky thing which is where I print a theme something and then I exit out of the request because in Drupal 7 that's the only way to stop the system from theming the entire page as though it's a regular desktop sort of request. So that's one nice thing about Symphony is it eliminates that default assumption. So that's pants change. And then the settings form we already looked at, that's just a separate form at the admin config blah, blah, blah URL. So if I go to the new symphony eyes way, pants routing.yaml. So the URLs pretty much stayed the same. The difference is pants changed. I now pass account because that's the name of the argument. I'm gonna have to walk through this step by step because this is really strange. All right, so content is saying this is where the content for this page is being generated. So this is going to be a class called pants controller and it's gonna have a function in there called settings. And what settings is gonna do is it's gonna return the output of that page. And I'll show you that in a second. That one isn't pretty, that isn't very scary. And the requirements is sort of like what access callback used to be, right? So I'm saying the requirements is a permission called administer pants. Everyone cool with that one, at least in concept. We'll take a look at pants controller in a second and that will make a little bit more sense. Okay, so what about this weird thing? All right, so this one, we have a wild card because we don't know whose pants were changing. So that comes in as a variable so we put the little squiggly brackets around it. And then I'm giving in a converter. So we have this thing called a converter so I can take that account and I can say that account is a user. So when an account comes in as a one, transmogrify that into a user object for user ID one. So it's very similar to the way in Drupal 7 if you name an argument percent user, it knows to call user load on it. Have you guys used that before? Yeah, so it's the same thing in symphony. Just what it's called as a converter, which is a little bit more straightforward honestly because I've tried to explain that weird percent user, like it magically calls a function called thing underscore load and that's very confusing to people. So at least this way, not only can you name this whatever you want, but you can be very explicit about what that maps to. Yeah, yeah, well anything that there is a conversion for. So I think right now there's only converters for entities. There might be some for views and some other things. I'm not really sure. Right, like this patch literally just went in last week. So I've been very busy trying to keep this up with the bleeding edge. But yeah, it's an API and you can define additional converters. So say you and your module had a need to convert to a web services call or something silly like that. You could define your own converter then just reference it here. This one uses a controller as opposed to a content because this is an Ajax callback and it's not actually returning like HTML content. It's instead returning a JSON response. And then instead of this being done by a permission, it's actually done by a function because we want to check a couple of different things. Does that kind of make sense? Just a scarier version of hook menu. But honestly, like I actually like this a lot better because it's a lot more straightforward. I think once you know what all the parts are. Yeah. Right now, I believe YAML is the only thing we support. But that seems like something that would be pretty easy. It's really important in core that we pick one way to do it because otherwise it's gonna be a mess and contrib. But I don't believe we've removed any particular functionality there. So it should be possible to override it to do whatever Symphony can do. So that's one part of it. The other part is this magical controller thing that we talked about. So that one doesn't go in a funny directory. That's just here. So we call it a namespace DrupalPants so that we can name it whatever we want or name the functions whatever we want. We're pulling in the user entity because remember that was an argument coming into the function with the account. You wanna change it to a user so we pull the user entity in. And then we're using the JSON response because that's how we output JSON from one of these. So the settings form is actually really straightforward. All you do is return DrupalGitFormPantsSettings. That's it. And that's pretty much exactly what you would do if you had a page callback that returned a form. So this actually isn't that scary. I don't find anyway. The scary part is that it's in a lib blah blah blah blah and then you have the thing in a class but once you get there it's actually pretty straightforward. This one is a little bit funky but it's still pretty much the same. You have an incoming thing. It's a user. The entity system in Drupal is all object oriented and that's really nice too. I'm gonna get their status and then I'm gonna set it and switch it to the whatever it was before and then what I'm gonna do from here is return a response, a JSON response from Symphony. And so I just wrap my theme, pant status in there in a thing called new JSON response. I set a header to tell it that it's a type application JSON and then I just return it. Which is actually quite a bit better than just like killing the entire request after the theme function runs. But unfortunately making a hello world application is a little bit more complicated than it used to be. So I have five minutes so I'm going to close this real quick and talk about twig for a millisecond. So twig is a templating language and I can sum it up in one slide. Basically this is the new node.actualties.html.twig now as of last week again. With all these different funny characters. We're trying to get rid of a whole bunch of problems with the PHP template system including the fact that like you don't know if that's attributes arrow class or attributes brackety class or what the hell is going on there so in twig it's all just attributes dot class. It figures that out for you. It can automatically do sanitization of variables so you don't need to take care of that yourself. And all of this stuff isn't executable so it's nice if you're running some kind of software as a service platform with Drupal. You can give people a lot more control over their themes because they can't actually embed executable code. So there's basically three things. If you put things in double brackets like food dot bar that means print it. If you use little percent signs that means it's PHP-ish stuff. So do this logic. And then finally if you put little hashtags around it it's comments. And then pretty much you can look through any of these and there's a huge movement going on. And Jen is there a sprint going on tomorrow around this? Awesome. So if you want to clean up Drupal's markup if it drives you nuts every single day you should totally go to that. And they're basically going through and converting all of the templates to this new twig system. So I can show you that real quickly. I have a new templates directory. And it has two things in there. One is pantschangeblock.ishml.twig and the other one is pantsstatus.ishml.twig. And where these used to come from is in my hook theme. I had these defined as just regular functions that I would pass whatever to. But I just added a little template index to hook theme to say go look in a template file instead. Cause with the transition to twig we do away with theme functions ideally and everything becomes a template that can be easily modified by people. And so let's take a look at one of them just to show you what it looks like. Pants status is actually really simple. It's just if the person has pants say on otherwise say off. That's it. But you can see a little bit of like the PHP logic thing happening in there. The change block is a little bit different. It has this div around it called pants status and then I'm just printing pants status and then I'm printing a link. But where did those things come from? It's magic, I'm just kidding. Where do variables come from in Drupal 7? Yeah, they're passing the theme function. We can use something called a preprocess function to say before you render this thing out I wanna actually see what's in it. So that's how I did this particular one. So if I go to preprocess, I defined a variable called pants status which is calling theme pants status and I defined it a link that's calling the L function. And the reason I did that here and not in the template is cause I can't execute PHP in the template. So I prepare the variables in preprocess and then I just print them out when I'm actually in my twig file. And I hope I did that right. That's what Fabian told me to do. So I hope that it's okay. That'll change the amount before. Yeah, well this'll all change before, but yeah. All right. Twig, yay? Ooh, bracketies. Let's hear it for bracketies. Yay, all right. Bracketies, okay. So finally to wrap this up. The diff between 7.x and twig is 11 files changed, 318 insertions and 182 deletions. If this sounds scary to you or if this sounds awesome to you, now is exactly the right time to jump in and help because we still have time before July to fix all this stuff and change it up and try and reach a balance between flexibility and developer experience is particularly for new people coming in. So it'd be great to see you go through this process with your own modules and give usability feedback on how Drupal is to work with you because we still have a lot of leeway to be able to change it right now. And now that you're all Drupal 8 experts cause you've been exposed to all the major APIs, you should totally come to the sprint tomorrow which is here in this room if you want a community tools workshop which you probably don't cause I think you're a little beyond that or the code sprint itself is having Centennial which is just over that way. So that's all I've got. Thank you so much everybody for coming and I can take, I think I'm off the stage now but I can go ahead and take questions in the hallway. All right, thank you.