 It's really exciting to see, you never know who's going to show up to these things and if you're really in like a sad room with two people, so I'm really happy that everyone is here to learn about porting your modules. How many people have tried Drupal 8 already? Almost everyone. Awesome. Great. Some people try it twice. Okay, cool. So we'll get started in another couple of minutes here. I just want to leave time for anyone else to filter in. I got 12.58 here, which I think is the proper time. And then, so we'll wait about two more minutes and then we'll go ahead and get started. Along the back row, I think. If you are here because you work in Drupal 8 and you're really good at solving people's problems and you're here to kind of be a floater to help people, can you go ahead and raise your hand? Great. Actually, maybe we should have you come up on stage so people have seen you. So could you guys come up here? Especially if you're landlocked in a seat, you'd need to be mobile and stuff. Alright, so if you guys, when we get to the module porting part, which if you did miss my little intro thing, we're going to do for the second half unless you already know all the intro stuff at Drupal 8 and then feel free to sit towards the back. Any of these fine folks can help you out. Just raise your hand. If you have a problem you hit when you're porting your module, they should be able to point you at resources or existing issues you already know about or these kinds of things. It'll be fun. It'll be a big adventure. And then for the last hour, we'll have some more people filtering in as well. So feel free to ask any of these fine folks for help and they'd be happy to come and see you. So once again, for the first hour of this lab, what we're planning to do, you guys can sit down now. Sorry, I didn't make you feel awkward. For the first hour, what we're planning to do is sort of an intro to module porting for those who haven't done it before. And then we're also going to offer, and that'll take like maybe 15 minutes. And then for the second half of the first hour or whatever, the remainder, Alex will be walking through a seven to eight port of a module we've already done so you can kind of get an idea of the changes. So the configuration management system changes, the entity and field API changes, the plugin system changes, Alex will be walking you through that so you can kind of see it in action first. And then for the second half of the hour, the plan is that everybody grabs laptops and just grabs their module and starts banging on it. And again, if you already know all this stuff, we're going to talk about it at the beginning. Feel free to kind of listen, but you can feel free to start porting your module right now if you'd like and just hold up your hand if you have any questions. And then we were going to break for 15 minutes in the middle there, probably to kind of figure out how we're going to possibly port modules hands on with a room set up like this. And then I wanted to also point out that if you are super into the entity and field API stuff, we're going to cover it as like basically an intro level. But if you want the deep dive and want to learn everything about that, there is a session on that after the first hour of this lab, which you may want to check out. Not to ask people to leave our awesome lab, but just in case that's your thing. All right. So we're going to go ahead and get started. This session is on upgrading your module to Drupal 8. Could be someone else's module. But the point is to have a module that you walk out of here with having some sort of thing ported on it. And ideally, have it on Drupal.org as well. This is about us. Unfortunately, Jess XGM couldn't make it. But that's Eflgencia Alex. I'm WebChick Angie. And we all work for the Acquia Office of the CTO. I am obliged to tell you that Acquia is always hiring. So if you and you are looking for jobs and you like working with big customers, you like solving really tough problems, those kinds of things, please come to our booth and talk to our folks. We'd be happy to speak to you. And if you know someone who is and you're not interested yourself, we also offer referral bonuses. All right. Enough of that crap. Now, introduction. So what we're going to do, as I mentioned, is I'm just going to do a brief overview of the process. I'm going to show actually a hands-on demo of something called Drupal Module Upgrader. Who here has heard of Drupal Module Upgrader? Awesome. I'm going to blow your minds. This is going to be great. Okay. So some tools, anyway, to help you get started in your module porting process, then Alex will take it away with a Drupal 7 versus Drupal 8 code walkthrough, which will help get you oriented to all the major API changes. There's many API changes, but that will cover the big ones. And then for the second hour, as well as the first hour, if you already know all this stuff, we're going to be doing a three-to-one upgrade type of thing. And then you just grab your laptop, start hacking on things, raise your hands if you have questions, try and help each other. It'll be a really fun sort of interactive process. So the goal is to get something working and in Drupal 8 and on Drupal.org before you leave, and you met the helpers already, so we don't need to make them do that again. So prerequisites, boy, this didn't export well. Let's run it from here instead. That's what I'm looking for. So prerequisites, it's a module like the port, either yourself or someone else's, a development environment with Drupal 8 installed, Git, and Drush and Drupal Module Upgrader are also handy, too. If you've been using Drush, note that you need the Drush 7 version for Drupal 8, because we love to confuse the crap out of people. And Drush 7 is the master branch of Drush. So you'll need that in order for it to work. I also want to give a fair warning that Drupal 8 is in beta, so we're going to do a bunch of work today. And not all of that work will necessarily still work when we actually ship Drupal 8. You'll probably have to adjust some things. And there's also no upgrade path between beta releases yet. So you should not be building production sites on Drupal 8, but you should absolutely be doing exactly what you're doing here, which is porting your modules. So first steps, this is something new in Drupal 8 that you don't do in Drupal 7, so I wanted to call it out. Drupal 8 by default ships, it ships in its default configuration fast by default. And what we mean about that is we turn on CSS and JS aggregation, we turn on page caching, we eliminate things like errors printing out to the screen, because that's a security problem in production environments who basically ship Drupal 8 with the default configuration settings to be fast and production ready. When you're a developer, though, that is not what you want. You want to be able to turn off caching, you want to be able to see errors and all these kinds of things. So this will save you a lot of headache and frustration. So in your sites folder, you will see two files, example.settings.local.php and default.services.yaml. What you're going to want to do is copy those into your site's default directory and rename them to settings.local.services.yaml. And then these essentially become things that you can override Drupal's default settings and services, which we'll get into later. It's just another type of setting, really, so that you can actually have local changes specific to your environment on those. So you definitely want to do that, because if you don't do that, you'll get a lot of white screens of death. They're nicely formatted, though. But a nicely formatted white screen death would really no information. It just says the website encountered an error. And that's really frustrating when you're trying to figure out what's going on. So try and do that. Then the second thing that you're going to want to do after that is edit. Do they already have this? Are we good? There's resources and stuff we can cover it later. Then you want to edit your settings.php file. And in your settings.php file in Drupal 8, there will be a few lines talking about this settings.local file. And you want to comment those out. Uncomment them, I'm sorry. But if you do that before you install your golden, if you do it after you install, you're going to get something like this. And if you get something like that, what you're going to want to do is go to the rebuild.php script. This is a new thing in Drupal 8. Like in Drupal 7, it was like clear cache. Clear cache, clear cache. In Drupal 8, it's going to be hit rebuild all the time. And if you have that settings.local.devire example thing, that's already enabled for you. And you can just hit it. In a production website, you actually can't hit that URL without adjusting some settings. So sorry, it's a lot of information, but it's going to save you a ton of time. So in summary, take the two files out of the sites folder. Example.local.settings.php and default services yaml. Copy them into your site's default and rename them to services.yaml and settings.local.php. And then the third thing is edit your settings.php in order to uncomment the references to there. And then now you've got control over your environment. It's default developer settings. It'll be very friendly for you. Questions on that? Yes? Is it developed? OK, that might be a typo on my slide. OK, is it beta one? OK, sorry. That might have been me not paying attention enough. But yes, there's one services.yaml in your site's folder. That's the one you need to move. So I'm sorry. I think it's called development settings. You're right. All right. So after that, we made a big deal in Drupal 7 about how you never know Joke or ever puts their modules in the modules directory. Ha, ha, ha. Well, in Drupal 8, that's exactly what you do. So you used to put them in sites, all modules, et cetera, et cetera, et cetera. In Drupal 8, we've moved all of the core files into a core directory. So the core modules are under that. So you actually do use the top-level modules folder, in most cases, to just stick your module in. So whatever your module is, stick it in that top-level modules folder. Then you go to the modules page, and you see what happens. And what's going to happen, spoiler alert, is your module's not going to show up. And why is your module not going to show up? Because it's still marked Drupal 7. So the first thing you're going to do, you're like, I know what to do. I'm going to change that info version line, and I'm going to make it 8.x. And it's still not going to show up. And you're going to cry. And you're going to think, why does the world hate me? And so the reason the world hates you is because Drupal 8 has changed. And so any time that you hit a problem like this, any problem, it doesn't matter what it is. Something's not working the way you expect. You should go and meet your very special friend, which is the API change records list at Drupal.org slash list changes. And what this is is every time we've made any kind of change in Drupal 8, an API change, a functionality change, this kind of thing, we've made one of these change records to explain what is the change. What did you do in Drupal 7? What do you need to do in Drupal 8? And why did we do that? So it has a reference back to the old issue to explain it. So if you were to go to this page, I didn't know what the internet would be like here. So I have it all here. But if you were to go to this page and type .info, for example, which would be something related to your problem, you would see in the list that Info files are now Info YAML files. And then that is what your problem is. So it won't pick it up because one of the things that we've done in Drupal 8 is move away from these sort of Drupal-specific things, like our Info file syntax is sort of kind of I and I, but not really syntax. We've now moved that over to YAML, which is a standard metadata language that other things use. And it's actually pretty simple to do this. You basically just turn all your equal signs into colons. And then in the case of arrays, you have to indent them with a dash. And then there's a couple other things, like you don't need that files line anymore, because we now use a standard auto-loading procedure, not that custom registry table stuff. Alex will get a lot more into that. And then thirdly, you have to rename your file from Info to Info YAML. What could possibly go wrong? You could get a problem where your module still isn't showing up, and usually that's because you forgot to rename the file. I've done that 1,500 times. There's also a new key called type module, and you have to add that in. If you don't add that, it won't show up either. You might get a horrible red error of death. If you get that, probably you have a syntax error. Like, you forgot to change one of the equal signs to a colon. So just read the error message. It should show you how to fix that. Questions on Info files, Info YAML files. I know I'm going pretty fast, but I figure this stuff is pretty basic. You could do it at the beginning of the module port. I just want to give you a heads up on this stuff. I hit errors so you don't have to. All right, so I'm going to move on. Then the fifth step is you turn on your module, and you see what happens. And most of the time, what happens is that. Because we've renamed functions, we've completely removed things, all kinds of stuff is going to happen. So here are a few debugging techniques that you can use to port your module. One is actually read the error message, because many times that will actually, it's going to sound scary, because it's going to talk about symphony or whatever. Don't worry about it. Just read the error message. Where is it coming from? And often that can be your best clue. If you're not getting an error message, you can look in the PHP error log. So this would be like a white screen of death situation. One of the best tips, actually, to try and get your module enabled is just to comment out your hook install and hook uninstall. Because oftentimes, if they're calling out to the field API to create a field, or they're doing some other kind of a thing, they might just totally break. And you can just comment them out and then proceed. If things go really wrong, you can rebuild your cache with that rebuild.php script I talked about. You can also clear your cache. The command for that in Drush is DrushCR for cache rebuild. It does both. You can try uninstalling and reinstalling your module. And in the worst case scenario, just destroy your site and rebuild it. And when you destroy your site and rebuild it, one new thing you have to be aware of in Drupal 8 is it's not enough to just blank out settings at PHP and recreate the installer. You actually also have to clear out your site's default files directory. And there's going to be compiled PHP in there. You have to remove as well. So the easy way to do it is just delete the entire directory and start over. And then you're golden. That sounds really frigging tedious, doesn't it? Yes, it does. All right. So we're going to talk about the Drupal module upgrade, which is going to help a lot. So what Drupal module upgrade does is it attempts to auto-convert your code from Drupal 7 to Drupal 8. It has two commands. One is an analyze command, which will actually print you out a report that says, for your module, here are the 30 of the 75,000 change records you need to care about. And actually, for people who are really new to Drupal 8, I actually recommend running it in that mode first and pretty much solely. Because that way, you actually learn the API changes and why they were made. And you can internalize that. But once you've done this a few times, it just is going to be really annoying to rename the info file for the 50th time. Then DMU upgrade is the thing you want to do because it will actually automate a lot of things for you. So it's a Drush script. You install it just like you would install any other Drush script other than there's this composer install command you have to run here, which you have to be aware of. And then you just enable it, because it's a module. So let me show you how that works. So let's make this big. Sorry. The Drush command. Yep, yep. So in your Drupal 8 site, once it's installed, you run DrushDLDrupalModuleUpgrader. We should pick a shorter name, because it's this much typing. But yep. And then you just have to composer install after you've downloaded it. And then you enable it. And then it works. So I'm going to do, I have this module, this kind of silly module called Pants. And it doesn't matter what Pants is. Alex will get into it more. But it's a module that defines some pages and blocks and stuff. That's all we really need to know for this purpose. So we're going to say Drush DMU Analyze Pants. And what, that's really hard to see. Can I do anything better without, let me see, about grass. Why are you not doing the thing I want you to do? Let's try that. Is that easier to see? All right. So I run Drush DMU Analyze Pants. And it tells me it generated a report in modules, Pants, and upgrade info. So if I open that, what I'll get is I'll get this nicely formatted HTML report, which will talk to you about all the various things that have happened. So user save is now entity interface save. User access is now account interface has permission, et cetera. And if you expand any of these, what you'll get is you'll get a link to the documentation that talks more about that. So it's like, oh, the variable API has been removed. What does that mean? And you can click. It'll take you directly to that change records. You don't have to use the search. And the change record has all the information about which issues. Yeah, I like this one, eh? We killed the variable system. And then it talks about the various things that happen and these kinds of stuff. It'll also tell you what file, what line, which plugin sort of did it. If you know Drupal 8 already, you should definitely dig into the code of Drupal Module Upgrader, because it's all Drupal 8 plugins. It's all very nice. It's using a library by Cameron, who I saw, but right over there. Cameron called Farberist, which instead of using horrible regex expressing horror of things, actually is a library that takes your PHP source code and parses it into a tree, so you can effectively traverse it like the DOM and do things like append arguments or add method calls and stuff. So it's an area we'd love to have more help with, because we're only going to be able to cover probably the 10 big APIs and not many of the smaller changes. So this is really useful, so you get a big list of all the things and you just keep changing things and improving your module until it's fixed. But the really sci-fi thing that you're going to want to do is you're going to want to Drush DMU Upgrade Pants. And so that will run a bunch of different commands. It goes pretty fast. If I go into my modules Pants directory and I show you what that's doing, you can see it's actually covering quite a bit of changes already. So for example, one of the changes in Drupal 8 is the variable get stuff is booms to the new configuration system. It automatically takes any variables that were mentioned in the module and then puts them into a settings.yaml in a schema yaml file. Going down here, you also see it does a lot of things to the new configuration API. So it converts variable get to Drupal config. Anywhere it's like kind of throwing up its hands and like I don't know what to do with Ctools, plug-in and whatever thing, it will comment it out and it will add an app fix me and point you off to the docs on how to do that. So in your IDE, you'll get a list of all the things that you need to fix. A couple other things it does. The new menu system in Drupal 8, instead of a hook menu, we now use a series of yaml files and classes. It covers that. So here's a links menu that will create a menu link. Here's several other things that it's doing. My favorite thing about it, oh, here's the rest of that. So here's a routing yaml file that sets out the mapping between the URL and stuff. My favorite thing that it does, though, is it actually ports your tests. So if you have automated tests in Drupal 7, sorry, I'm trying to find one of these. Well, I'll talk about that in a second here, I guess. The other thing it's doing here is it's converting page callbacks. Here's your access callback, your page callback. It also does forms. So here's a configuration form. It handles that. Submit form, build form, and actually copy the code from your old module into the right places in Drupal 8. So anyway, this is saving you a lot, a lot of time. And by porting the automated tests, if you have written those in Drupal 7, which I really recommend because it's a baseline to show your module is working, then you can actually use that as basically like a to-do list of what you need to fix in your Drupal 8 site until it's functioning properly. Converts blocks, it does all of the songs, it dances, all that things. Yes? Which version? Which version of Drupal module upgrade should you use? 0.4. Yeah, that's the one I tagged before Drupal Con to make sure it worked. So use that one. We tag it every couple of weeks or so. So always follow the latest stable on that. So a lot of you are like, oh yeah, cool, whatever. It changed a bunch of code. What does that actually do? So I'll show you what that does. So if I go to beta1.local, that's my little site running on dev desktop, I'm going to go to the Extend page. I'm going to go and find the Pants module. Actually, I got to show you something awesome in Drupal 8. So I can just do this. I can do Pants. Wow. And it just shows up right there. I know, right? That alone is a reason to upgrade. Yes. It's hard to hear you said, in the report that it generates, is there an audit trail? Yes, good question. OK, so his question is there an audit trail? Because there's a lot of, basically, it's leaving old, crafty code around as it's making new ones. One of the next features we want for the new version is to be able to clean out the old code. Like, have a mode where it's like, I know what I'm doing, delete the stuff kind of thing. We didn't do that yet because we're not overly confident in it. But yes, that would totally be so. But in terms of an audit trail, no. You just keep rerunning the report. You could personally save different copies of the report and diff them or something like that if you wanted to. But it's not that sophisticated. It's just running through all the analyze commands and then compiling the stuff together. Yeah, I see what you mean. File an issue that's like a feature request for allowing you to specify the directory where those should go. That's all we need is like a command line flag. So yes, that's a great idea. All the things you're going to find lots of problems with this thing, please go to Drupal Project Issues, Drupal Module Upgrader. Adam, the Acquia intern we have working on this is very active. He's very enthusiastic. Would love to get people using this and giving feedback and ideally helping you to write patches for it. Yes. It doesn't work with NAD and Field API yet because you all didn't finish it until last week. So yeah, that's next on the list, though. And we're going to see if we can get to twig. That would be the other big one to hit. But yeah, it was enough people helping. That would be amazing. We would love to have more stuff like that. So anyway, there's lots of stuff in here that we're working on. But the thing I wanted to show you was the, where does it go? Start closing tabs until I find that there we go. That's what I'm looking for. I'm also going to enable the testing module I'm here. So one thing that happened is I enabled the module and I didn't get an error, so that's pretty cool. That's more than you usually get when you enable a module. So that alone is worth the price of admission, which is free. But it even does things like if I go to the configuration section, I'll actually see the pants link show up. I can click it. And although I don't have all the options I should see here, the form actually saves and it works, which is pretty big. If I go to structure and I go to blocks, I'll actually see the pants, oh sorry, don't turn that off. I'll see the block here. I can actually place the block into site, say the left side of our region or something like that. And it's not going to look quite right, but it is going to allow me to place it, which is a big deal. So if I go back to my site, I'll actually see, and it's got some errors. You'll see errors too. But you'll see the block actually showing up on my site, which is pretty awesome. And then the most awesome thing is if I go back to configuration, development, and I go to testing, I can actually run the automated test that I wrote for this module, and it will give me essentially a to-do list of what's left to fix in my module before it's working again. And that is going to save tons and tons of time. So if I check this off, and this is going to take a minute, so I just want to do this quick before I get one last round of questions. That is going to be a huge time saver for people who invest the time to write automated tests. So that's my song and dance about Drupal Module Upgrader. Any other questions knowing that we do still want to get to a 45-minute intro to Drupal 8 APIs? Yes. Yes, there is a dependency for Drupal Module Upgrader, which is the Farberus library, which Cameron from previous Next has largely built himself. And it's awesome. It's that syntax parsing thing. But if you run Composer Install, after downloading the module, it will get that stuff for you. So effectively, no, as long as you run Composer Install. No Drupal Module dependencies, no. We're trying to get off the island and use other people's stuff. So any other questions? Pretty cool, right? Yeah, all right. So that is what I've been spending the better part of my time lately on. And it's really fun. But we definitely need more people to help with it because it's not perfect. It never will be perfect. I have actually a slide about this, the fact that it's going to be a good kick in the pants. It will save you a lot of really tedious stuff. But you're never, ever going to be in a situation where you run this thing and you're done porting your module. But if there's modules you want to see ported, one thing you could do is run it on the module you want to see ported and post a patch. And it's at least getting them at least 50% of the way there, which is really helpful. So I won't get into a lot of this. But just to show you, it's showing test results. It's giving you errors. And then you can gradually over time fix those until this is all returning green. And then as long as your test coverage was good enough, you should be good to go. So I'll flip back to the presentation for a moment. Yeah, so kick in the butt. Not going to port. It also can't deal with logic in hooks. So if you have a hook menu that does an if statement or something like that, it just has to go, I have no idea. Because it's not going to eval code. We don't know anything about on somebody's local machine, because that would not be nice. So if you find a bug and you see an API that's missing, go to Drupal module upgrade. And then the developer we have working on this is called Fenup Proxima. His name's Adam, and he's awesome. Please feel free to ping him anytime in IRC and Drupal contribute. Okay, so that's my intro. Some tips and tricks to get you guys started and get you on the right foot. Drupal 8 APIs is the next section. So there's several major API changes that happen in Drupal 8, object-oriented code, routing pages and forms and so on and so on. And we're going to use Pants as an example of this, which is a very silly module, but it happens to exercise all of these APIs to kind of show you how that is. So I am going to hand it over to Alex, who can talk to you more about that. Just going to take a minute to set this up. So while that's happening, let's see. Can I ask you all? Let's see. How many people have started porting a Drupal 8 module already? Few people. So most of you have not yet. It's fun. There's a lot of things that have changed, but we're waiting to the beta. We're waiting to the beta. That's the feedback I heard from most people, yeah. It's like, why am I going to port my module when literally every day something moves or got renamed or, yeah. What do you need to do to get this to show up? Uh-oh. It's on the screen. All you might need to do is go to display preferences. Is that here? Yeah, system preferences, displays, and then turn on display mirroring, which is arrangement, I think. Yeah, mirror displays. All right, thank you. Yay. How do you get this thing out of the way? You can't get it to flip forward vertical because you've got a prune, but you can hit manage and it will go up soon. All right, hi guys. Okay, so let's see. How much time do we have? Okay, we'll have half an hour, I think. Or, okay, or not. Okay, so I just, yeah, I did want to cover some of the APIs that you'll find and going from Drupal 7 to Drupal 8. So what I did is I actually, there's the pants module. Let's see, it's hard with these small displays, okay. So if you go to drupal.org slash project slash pants, then in there there's a, you can go to the repository viewer. If you want to view the repository online, which is how I'll show it here, or you can download it through Git and use all your favorite Git tools to look at it. And what you'll see is there's a branch there. That's 8.x-amsterdam or AMS. And that is the, and what I did here is basically just did kind of a commit by commit step that you can look at sort of on your own if it's helpful. So it's about, I don't know, 20 or 30 commits since branching from the 7.x version. And so you'll notice the first looks like about eight or so commits is what DMU generated. So I just ran DMU update and then just sort of committed them in steps. And then after that did a little bit of cleanup, like Angie mentioned, there's DMU sort of currently and its current version leaves behind some dead code. So this just sort of removes that. And then I think also that Angie mentioned is one of the things that DMU doesn't do yet is stuff around the entity and field API. So then there's a few commits here specifically around that. And then some miscellaneous stuff, frontend stuff, some plugin stuff, a little bit on caching in views and then finally getting it all working. So yeah, I think I'll go through a couple of the commits here, just at a very high level. And again, if you're, I think one of the APIs I'm particularly excited about in Drupal 8 is the new entity and field API. And if you want more than just a little tiny introduction on that, then the next session that starts in, I don't know how many minutes, half an hour or so. There's a session in the Emerald Room, I think, if you wanna get like a full deep dive into just the entity and field API. So looking at the DMU stuff, so DMU generates the info YAML file. So the other thing that DMU does is it comments out, I don't know if it's everything or some things that are in hook install and uninstall because if you have a bug in hook install, because you haven't converted something from Drupal 7 to Drupal 8, then you won't even be able to install your module, you'll get errors. So it's kind of nice to just be able to comment that stuff out and then come back to it later. What's really nice about DMU is that it does convert, like Angie said, convert things like tests and move files around, so that's nice. And then, okay, so another change that it makes is permissions. So one of the things in Drupal 8 is instead of hook permissions, we have a permissions.yaml file. So it creates the permissions.yaml without deleting the old hook permissions. Again, that's the whole thing about DMU not deleting dead code yet. Okay, and then we get to something a little bit more interesting, which is the configuration system. How many of you here have already seen presentations on the configuration system? About half, okay. So yeah, so basically everything that in Drupal 7 was done as a variable get or a variable set is managed through the configuration system, which is, and so what that means is that a module can provide default configuration. So this is what like modules code used to do is they would call variable get and then like the variable name it wants to get and then like the second parameter to variable get would be a default. So those defaults are now stored in the modules config install and then some kind of settings.yaml file. So in this case the default for the pants type variable is an empty string and then there's also something in the configuration system which is the schema, which basically defines what the structure of the configuration file is and this is very useful for configuration translation because one of the really awesome features in Drupal 8 is that all configuration is translatable. So the way that the configuration translation UI knows about what things are translatable as it sort of looks at the schema is to look for things that have been flagged as being of a translatable type. I think we also use the config schema to do some nice validation and other nice things. So okay, so then we get into the hook menu. So in Drupal 7 you implement hook menu and sort of a lot of stuff is sort of thrown into Drupal 7's hook menu. You define the page callback, you define the link title, you define permissions, all sorts of stuff. So that's basically been split out into different concerns and in particular it's a separation between links and routing. So routing is the equivalent of page callback. It's what happens when you visit a URL regardless of how you got to that URL, like you could just type the URL in the address bar and then how does then the Drupal know what to do with that URL? That's routing, it routes it to some function, in this case it, so you define the path and then this underscore content key basically tells you the, this is the equivalent of the page callback, it's just instead of being a global function, it's a method in a class name that's namespaced. And then that's separate from links, right? So just visiting a URL and having a URL do something is one thing, but then there's actually showing that link in some kind of menu and so that's in this links.menu.yaml file. And then DMU also generates the controller, so basically it took what in the Drupal 7 version of the module was implemented as the page callback of the hook menu entry and moved it into the appropriate class and the right directory and the appropriate method for it. So that's a way to just sort of look through what DMU does. Another API, is this an okay pace to cover this stuff? Because I wanna get through several APIs, is this okay? Am I talking about stuff you already know and should I sort of skip? Or no? Okay, I'll just, okay. Yeah, so if you want to get into more detail on any of this, you can either look through the pants, commits and kind of study it in more detail. All of these commits also link to the change record. Not the DMU ones, but DMU has its report that links the change records but then in the pants history the commits that weren't auto-generated by DMU link to the corresponding change record, so you can kind of follow it that way. So the other thing in Drupal 7, there's blocks. So you implement hook block info, hook block view. That moved into the Drupal 8 plugin system. So basically hook block info or all info hooks moved into annotations of a class. Or sorry, not all info hooks, but 90% of info hooks, including blocks. So things that you used to do inside of hook block info, now there's a class that corresponds to that block and the info stuff you can put into an annotation. In this case, add block. If it was a different info hook in Drupal 7 then the add annotation would be appropriate to that particular concept. And then the view method of the block that moved into a build method of the block class because there's always this dilemma in Drupal 7 between when are you viewing something versus when are you building a render array because building a render array is kind of like viewing something. Now that we have views module in Drupal 8 that gets even more confusing. But yeah, so build in the sense of building the render array. Which you can see what DMU did in this case is instead of actually moving the implementation of what was hook block view, it added it as just calling it and having it fix me here to sort of move the stuff in here as you will. And the reason for that is because I think currently Farberist doesn't completely solve the problem of in the case of hook block view you have a giant switch case statement, right? Because if you're in Drupal 7, if you're defining multiple blocks then your hook block view would have a switch for which block delta you're dealing with and I don't know if Farberist supports moving things from a particular case of a switch statement into a new place. Not yet, okay. But when it does, then the version of DMU will actually move that code into here. Okay, and then, I'll skip over a few. And yeah, and so then you can also go through and once you've committed the things from DMU you might wanna clean up some stuff. So for example, one thing that DMU currently does is for some reason it converts web tests. It moves web tests into the right place but things that it didn't recognize as web tests like basically things that were extending some base test class that wasn't web test base. It doesn't know what it puts into a different place. So far I think maybe even the next version of DMU I think will fix that but for now that was a limitation. So since I had an Ajax test case in this module I needed to move it from where DMU put it to the actual test directory which is where it needs to be for the testing framework to pick it up. And then there's a bunch of, and then I'll show some of the dead code here. So this is like the, so the pants underscore settings function which was the configuration form since DMU moved that into an actual form class. The old function for it is dead so just remove that. Similarly since DMU moved info, the info to info YAML but left behind the info, remove that and then like I mentioned before, the hook permission is gone so it can remove that. The old access callback and the old hook menu. So I think a future version of and the C tools. So this module, the pants module I wrote with using C tools plugins for the Drupal 7 version but since Drupal 8 has a plugin system in core, we don't need some of the plugin, the C tools ways of registering where to find plugins. So yeah and I think a future version of DMU will sort of have a flag for automatically removing dead code. Okay so now we get into maybe something a little bit more interesting which is at this point DMU doesn't deal with the changes to the entity system. So let's look at a couple of the changes to the entity system that have happened. So one is maybe not so much a change to the entity system but it affects this module. Oh sorry, before I get into that. So what pants module does is it adds a, I'll actually go through and demo it real quick, is it basically gives you a, so it provides a configuration form where it gives you an options for what kinds of pants you want on the website. So either none or Bell Bottoms or MC Hammer, it's a silly module. And then what it does is it makes it so that on a user profile page, it adds a check box that basically says, what's this user's pants status? Basically wearing pants or not. And then based on the value of that, it will show that on the view page of the profile. And then it also has a block and then it also maintains a history of when it's changed. So here's a block where I can toggle the pants status. And then if I refresh this page, now the pants are on. If I go to edit, the checkbox is on. And every time that a change occurs, it saves that to a history table and then there's views integration. So if you wanna get a views output of every time someone took off their pants or put pants on, you can do that. As you do. So since that's, so the main functionality of the module is to add a field, in this case just a Boolean field to user entities. So as part of that, there's a few things that happen in Drupal 8 regarding user entities, which is the meaning of the local variables, dollar user and dollar account kind of changed meanings. So in Drupal 7, you have global dollar user, which represents sort of you know, it's a light object that just has, that doesn't have like a full user entity, it just has light information so that you can know who's logged in. And then because we don't want to conf in Drupal 7 because we didn't want the possibility for a local variable that's undeclared to conflict with a global variable. We had a convention of when you have an actual user entity that you've loaded to name that I think most of the time dollar account. So in Drupal 8, we switched to convention because now we don't have a global dollar user object. So now dollar user is always a local variable and it's the user entity. And then dollar account represents like a light object that just represents who is logged in which doesn't necessarily contain all of the fields of the user entity. So if you look at the commit of that, oh and this is what I meant by, so every commit message that's past the DMU portion sends you off to the change record. So you can kind of look what that looks like, mostly it's just a bunch of global search and replace between everything that used to say dollar account, now says dollar user and everything that said dollar user, now says dollar account. It'll be nice when DMU does that for us. Yes. Okay, so the more exciting thing that happened is that entities are classed objects. So before in Drupal 7, something like a dollar user or what was dollar account or dollar user would be just an object of standard class, just PHP's sort of object that's not a class. And so if you wanted to access properties of it, you would just access the actual property. So like for example, users have a UID, so you would do arrow UID. And in Drupal 8, these are classed objects that have an interface. So you can type in to the interface and then you can call methods on it. So for example, entities have an ID method. And so that allows you to, for example, if you had an idea that you wanna actually come up with some alternate implementation of user interface that implemented the ID method with something other than just looking at the UID property, you could do that. And I think it makes the code nicer as well. So yeah, so that's what a lot of this does is just sort of changes user to a classed object. So another thing as part of that is in Drupal 7, we have all these different entity types. So we have users, nodes, files, taxonomy terms, and they all have a set of very similar hooks. So there's hook node load, hook node view, hook node pre-save, hook node insert, and then the same set for users and the same set for comments. And they were all slightly different. They all had slightly different signatures. So for example, hook user pre-save in Drupal 7 had like a dollar category parameter and got prefixed with a dollar edit, but hook node pre-save didn't. So one of the things in Drupal 8 is we wanted to make it more unified. So all of the entity type hooks have the same signature. Hook user pre-save and hook node pre-save have the same signature other than the type hint of the actual entity that they get. So this adjusts for some of those signature changes. Okay, and another aspect of the entity field API is that everything is now a field. So in Drupal 7, we had this idea of properties which were not using field API and fields which were. So for example, the node's title was a property that was sort of that the node module managed and wasn't the field. And so the way you accessed it is like in your code, you would just say dollar node arrow title and that was equal to the string value of the title but like the node's body was a field. So dollar node arrow body was this like three-dimensional array where it would be like the first index I think was language and then the second index was like a delta. So like if you wanted to know the node body, your code would be like dollar node arrow body, language none, zero value. And so there were several problems with that. One is for the ones that were fields, you always have to specify a language as that first parameter and most people just put in language none which made their modules not multilingual friendly because what you actually wanna pass in there is the language that the person wants. So there were a lot of contrib modules that didn't play well with the ability to have a multilingual site. And then things like, and then things that weren't fields like node title just couldn't be translated at all unless you had some really hacky workaround module that either made titles into a field or somehow found a way to make it translatable and some really clever workaround. So in your blade, we wanted multilingual out of the box. So everything got everything as a field both so like both node title and node body as a field or in this case, pants status as a field. And because all fields can potentially be multi-columned so for example, like the node body field that has a value and a format that you access them through arrow value. So you can access, so if you add a field to an object then you can just do it looks like this. It's like dollar user arrow pants status that's the name of the field arrow value the property of a field. And you notice there's no language specification here and that's because all of the entity types in triple eight sort of have magic getters. So the code that does dollar user arrow pants status it looks like you're just accessing the property of a PHP object but actually it's the implementation of that is through a magic underscore underscore get method which handles which knows the translation that you're currently working with. So dollar user because it's a class object already knows about which language you're working with that's already been prepared for you by the time you work with the code. So you can just write code that doesn't have to in most places doesn't have to be language aware and Drupal will generally prepare the objects into the right language for you in most places. I think we still have a little bit of work to do between beta and release to change that most into an all or at least more most. So I think that's personally I'm excited about that aspect of Drupal eight is the ability to just sort of have multilingual working reliably for all fields whether they're base fields or configurable fields. Okay, so how do you actually add a field? Is so in Drupal seven you do it in hook install with if you were doing it during install and you would use the field kind of the field API functions like field create field field create instance. And that's sort of how you would add a field. And in Drupal eight there's sort of two ways that you can add fields. And so you kind of have to make the decision is this a configurable field or a base field. So is it a field you want people to be able to sort of configure everything about it through UI? Do you want someone to be able to go into field UI and potentially remove the field? Maybe you're just adding the field as a default but you wanna give the administrator control to remove it. Or is it a field that you actually want or they can remove it and then maybe they can add another field in its place that has the same name but a different type. So maybe you created a field of type integer but someone deleted that field and added one back in of the same name and decided to make it a type float. And is that an okay thing to do? And sometimes yes, right? Like the node body field that's a perfectly fine thing to do. But if you have code that is going to rely on the field being there you don't necessarily want your code to rely on configuration being set to a being limit that your configuration values only being what they, you don't wanna make too many assumptions, your code doesn't wanna make too many assumptions about what the values of your configuration is because then it's not really configuration. The idea of configuration is people should be able to reconfigure it to something different and the code still works. So if you have that situation like we do here where we wanna actually have logic based on this field you might want the module might wanna expose it as a base field and that's a new concept in Drupal 8 which is why I wanted to spend more a little more time talking about it. And so you can implement that through this hook entity base field info hook and you can basically define base fields there. And so they're just like fields they're formatted the same way you can configure how they appear in forms and displays that way it's just what, but they're, but you can rely on them being there they're guaranteed to be there they're guaranteed to be of that type a person can't use configuration can't do a configuration deployment and can use the UI to remove this field or change its type or name because it's you're defining it in code and locking it down. How are we doing on time? We're good. Yeah. You got 11 minutes but the next session doesn't start until 15 after so you basically got 20 minutes. Okay. Actually before I maybe move on any I can maybe take like one or two questions on the entity stuff if there's any burning question about that. Yes. Yep. Yeah so the question was how to upgrade sites with existing content and so that's done through migration. So if you have a Drupal 6 or a Drupal 7 site and you want to get and you want to move its content to a Drupal 8 site what you would do is you would build the Drupal 8 site and then run a migration the same that the contrib module migrate Drupal 7 is now in core for Drupal 8 and you would run the migration to do it to basically move just the same way as though your existing site was in WordPress and you would do the same kind of migration. Okay so that's a very, very high level overview of the entity changes. If you're interested in that in more detail again there's the upcoming session that you can go to instead of the lab. But again if you want to come to the lab and actually do the hands-on porting work please do that. Okay so other changes besides the entity API is we have a new frontend system we have instead of tplphp files we have html.twig files. So yeah so basically there was a tplphp file that got changed to html.twig so that's a different syntax. You can kind of see through the stiff it's instead of having an opening PHP you don't need that and you've got some instead of printing variables with PHP print you can just output the variable which is really nice because you're not executing, your templates aren't executing code they are behind the scenes but at least in terms of how the templates are structured they're not executing code which means there's, so twig allows you to print variables but for example when you have a tplphp template someone you could write any PHP code in here so you could basically do like I don't know like drop table node statement in your template which obviously you don't want people doing so twig sort of helps create that encapsulation of you can only do things that are sort of front end related stuff in your twig files instead of just having open access to any PHP code you possibly want. That potentially introduces some cool capabilities for SAS services if anyone's running like a SAS product of Drupal then suddenly you can make it so that your customers can actually upload html twig files whereas you couldn't, you wouldn't necessarily want customers of a SAS service uploading PHP code that runs on your server that you have other customers running on that same server, so. And the other aspect of that syntax that I think is great is in Drupal 7 with PHP you had to know the structure of the, you had to know the nature of the variable that you were printing if you were printing a string you would just say print dollar string. If you were printing a render array it would be print render of that array. If you have an object it would be like print dollar node, arrow body, whatever. So how you structure your principle statement required you knowing the sort of the PHP internals of the, or the Drupal, the way that Drupal structures the PHP variable. In the case of twig you don't, you just print the variable. And if it has sub, if there are children of the variable you can just sort of separate it with dots just like you do with JavaScript. So if you didn't want to print all of content if content say had like a content dot foo you could just do content dot foo. So it kind of gives you this virtual representation of a variable and whether content is a string or an object or a render array or some other kind of structure doesn't matter that the sort of the, behind the scenes the twig integration figures out what to do with it. And yeah, and if you're always separate with dots if you're just like in JavaScript basically if you're, yeah. Okay, here's a stupid little commit that I just put in here to remind everyone that Drupal 8 uses HTML5. So remove your blink tags along with everything else that you might want to do when converting from HTML4 to 5. Okay, so there's also, so I mentioned before that there's a plugin system and as you saw DMU will, there's two aspects of the plugin system, right? You might be in a situation where you want to write a plugin, you might want to implement a plugin that is defined by some other system. So you want to implement the block, you're not block module, block module defines the plugin type for blocks. You just want to implement a block and we saw the example of that before. The other possible situation though is you might actually want to define your own plugin type. So for example, where we had, so for example, like you have a configuration where you want someone to select what kind of pants they want on your site and let's say that based on that selection, you want a different things to happen, right? Like maybe you're going to display this somewhere and you want each type to be able to control how it displays. You could do it in a couple of ways. You could maintain your own kind of like image map if you're assuming it's always an image, but what if you wanted to let people create types of pants where their display wasn't an image output but was something fancier, like some kind of like flash video or whatever HTML they wanted to do. So each one might have a different behavior and you don't want to have a fixed list but you want to let modules add to this list. You want to support the ability for other modules to add to the list that's here and also to define the behavior for that. So that's the sort of the use case for plugins. And in Drupal 7, that use case was most common. I mean, there were different ways of doing it in Drupal 7 but a lot of modules adopted the C tools plugins approach to doing it. And so this commit here kind of shows you how you can convert from C tools styles plugins to your own plugin type. I think I'll actually skip going into the details of that because you can look at it on your own and I don't think I could really summarize it in a minute. If you're really interested, then maybe during the break or during the second session, I'll be in the corner here and if you want to come up and ask me and we can talk more about it that way. So there's other minor changes here like image and this is the kind of stuff you'll just find if you have test coverage or if you actually do manual testing of your site. Like you'll run your tests and you were doing somewhere where you had a render array of pound theme image and in Drupal 7, you were setting the pound path to something and in Drupal 8 that got changed to pound URI. Those are just things you'll discover in the course of like running your tests and seeing what fails or if DMU ever gets flushed out and does all that stuff for you automatically as well. Okay, another really interesting thing in Drupal 8 is render caching. So in Drupal 7, there was block caching and there was even more generally than block caching render caching but it wasn't on by default. And because it wasn't on by default, there were actually many cases in which it didn't really work. Like if you tried to turn a caching on for say one of, like say a views block or one of cores blocks, like a menu block, it would let you turn it on but then you would be getting, you'd be caching it at the granularity that was that you chose but maybe the contents actually varied by some granularity different than what you chose and suddenly you'd be getting cache poisoning. Like people would be seeing the cached output that was in a state that wasn't right for them to see. And so that was a big pain point, I think, in Drupal 7 sites is not being able to cache as much as you want. So in Drupal 8, render caching has evolved. Things are render cached by default now. Every entity is render cached by default. Many blocks are render cached by default and therefore we're making sure that things are actually working for that and that should make a huge performance difference on a lot of real world sites. But what that means is if you provide a block then you can provide information about what your block requires in terms of its caching. So if you know that your block varies by user because you put a link in there that does something that has your user ID in it or any other thing that makes it vary by user then you could implement get required cache context and add cache context.user and there's a list somewhere of what all the different cache context are and how you can make your own. And then cache tags, which is, so varying by user means that in a given running instance of a Drupal site, user one and user A and user B will see different things so you have to vary the cache by user granularity. And then there's also the concept of cache tags which is well, whenever one of those, whenever you change, if you change something about the user and then click save on that user's profile, you need to be able to invalidate anything that you cached and so you can sort of reflect that information and get cache tags. And you can also create additional cache tags like, sorry, and actually this syntax is slightly wrong. It got changed like as of a week ago. So let me even show a little more recent commit. This was like one of the, yeah. So this is a slightly new syntax for how you invalidate cache tags and how you associate cache tags. But I'll go back to here, right, which is, so here I'm implementing cook user view, for example, and right, because I'm adding to the user profile page, I'm adding a display of whether they're wearing pants or not. And what I'm showing depends on which pants type is selected for the site. So because that display is contingent on that, there's a mechanism by which you can basically specify that, oh, I have additional cache tags that I want to add to this item. And so that way, whenever the pants.settings configuration file changes, it'll clear out the cache tags and you'll clear out your cache. Does that make sense? Sort of, okay. Again, I think this is actually one of the really cool features in Drupal 8. Oh, okay. Oh, yeah, sorry. So I think the question is, with everything being cache sort of granularly, does that support, like Edge Site Includes and those kinds of caching strategies? And yes, in theory, Core does not support Edge Site Includes, doesn't implement Edge Site Include technology in Core, but if you have a contrib module that gets that integration working, the render caching is set up to allow for that. All right, so it is three, five AM my time. I don't know what time that is here, but anyway, it's the time at which there's a 15 minute gap between sessions. So if you want to go to a different session for the second hour, feel free to take off. If you are staying here and you want to port your module, feel free to stay and Alex can finish up his walkthrough and then we'll move from there. Okay. Thanks, everyone. I can show you that, but if you want to learn more about this, so we have a lot of defense, and it's going to be an injection, and I see an injection, then you'll find lots and lots of things. So what I call C4 we're using is that, but you know, it's going to take a lot of time. It's going to take a lot of time. When you change the mode to do that, oh, well, I mean, read, write, and then you can see that every single service is just a string that's called up yet. So you can search for the current user. It's a CD. And it's like, let your, it says current user, because you get, which you get, it's just great as a user advance or something, and it works as well, it works as a stack. It's a CD. It works as well, it works as a stack. And then you see it requests a stack, it doesn't take a lot of time. So I mean, it's on what you can actually use for building your stuff. So this is one of the examples of some of the issues that we have. So you basically set it in this service, A builds in B and C, and it's having the whole day and after energy. It's basically a tree of dependencies where you declare which things they have in which things, and then you can go for the tool thing, and then you can replace any of these with some other information. Let's see if we can find any of them. Oh, that might not be fine. I'm just going to use the slide. Oh, do you want it up there? Yes. That's the slide. Yes. Yes. It might come back. Okay. I'm just going to let you go. Why? I don't know. Okay. Stretch the way. Under environments, we're having a lot of stuff over this fall.