 Okay. Thanks everyone for joining us. Today, we are talking about what developers can expect from Drupal 8. And our host today is George Demet and Larry Garfield from Palantir. And we're really excited to have these guys join us. We're excited to have you attending as well. And it looks like we have people from all over. Someone from Scotland, someone from the West Coast, the East Coasters. So thanks for joining us today. If you're listening from your computer, make sure that you select the mic and speaker audio option just to make sure that you're hearing us okay. Just to let you know, you'll remain muted during the call. If you have any questions as we go along, we're using the Q&A window for go-to webinars. I'll stop Larry and ask questions if there's a good stopping point, but definitely there'll be time at the end to ask further follow-up questions. And then also please make sure to check out our post-webinar survey and fill that out for us so we can better tailor the webinars to what our audience needs. Just a little bit about the Drupal Association. It's our mission to foster and support the Drupal community so they can collaborate together as we innovate the project. There's so many ways that we can help the community. The Drupal Association helps host Drupal.org and we're building a tech team to improve the site. We provide grants for community members to fund ways that grow communities and further the project like starting new camps and areas or running a multi-city roadshow and evangelizing Drupal. We also host Drupalcons which bring thousands together to work on the project and bond as a community and this year will be in Austin as well as Amsterdam. We provide scholarships to help community members around the globe attend the events and also this is funded through our membership and our partners. So some upcoming events, we have our Drupalcon Austin coming up. You can see the link at the bottom that's coming up in the next few weeks actually in June. We have Drupal Global Training Days which is a really cool program where either community members or Drupal training shops can host free or low-cost inter-Drupal trainings and we've had a really successful year so far. 25 different countries participating in over 40 companies hosting and this is a really great way to grow your community, really talk about Drupal and get new developers excited about it and obviously build the momentum for the project. Our next webinar is May 13th. We're talking about how to hire great Drupal talent and you can check out more webinars on that link listed and of course we couldn't do anything without our supporting partners. Thank you Palantir for hosting this webinar and giving us some information on what's happening with Drupal 8 and we couldn't do anything, couldn't do what we do without them so thank you so much. I'm going to introduce our speakers. Now we have switched it over. We have George that's going to start and then Larry will take over and without further ado, George if you want to begin. Sure absolutely. So welcome to what you expect from Drupal 8 for developers. Larry is going to be leading the bulk of this presentation and I just had a few words wanted to start out with as part of the introduction. Just talking a little bit about Palantir.net. We're a boutique web firm based in Chicago. We create engaging online experiences for clients who value accessible, sustainable best practices and human centered approaches to process strategy, user experience, design, development, quality assurance, training and support. We're deeply invested in the Drupal project and community and we're strong supporters of the Drupal Association and its mission. In addition to being supporting partners of the Drupal Association, Palantir also gives back to the Drupal community providing support for helping organize community events like local and regional camps and sprints. We also believe in giving back to the Drupal project and our team includes several leading contributors to the core Drupal software like Larry as well as prominent module maintainers and Drupal security team members. If you like what you hear today and want to learn more, Palantir offers training programs tailored to the needs of in-house developer teams as well as consulting and development support and of course we also work end-to-end design strategy and development projects. Our goal is to make both the experience of building a website and the experience of using a website enjoyable and transformative for all by making good both inside and out. So without further ado I'm going to pass things off to Larry. Thank you. All right hello everyone this session is so me my name is Larry Garfield I'm a senior architect here at Palantir. For Drupal 8 I've been the web services lead so I've been running the web services or whiskey initiative. I am also the Drupal representative to the PHP framework and probability group that's kind of the United Nations of PHP you can take that with all the good and bad implications that has. I'm an advisor to the Drupal Association so hello and general purpose level will patent. This talk is going to be fairly code-centric and kind of dense. My goal here is to give a an overview of enough of Drupal 8 module development so that when you then don't do it yourself you recognize the patterns so we're going to go through a lot of code. I don't expect people to memorize all of the code and every API I'm talking about that's not the point. The point is to get a feel for it and and recognize the patterns so when you go to play with yourself you will have a good idea of what to be looking for. That said if you would like to play along at home here's a link here to these slides that presenting straight from bit.ly slash count here dash d8 dash devs and the sample code that we're going to be walking through is all in a module called hugs because we are Drupal and Drupal is all about hugging and that link is there as well so if you want to play at home play along at home that's fine or just follow along the slides here. So I'm assuming most people are existing Drupal 7 developers you already know Drupal and so you've got the sense of I've heard Drupal 8 is going to be so different it's completely be written how am I ever going to learn this whole thing and the things remember is that a lot of things have improved but a lot of the concepts are the same a lot of the overall architectural concepts in Drupal 8 are the same as they've been for years it's just expressed in a new more consistent more industry standard vocabulary at the code level so there are a lot of new looking APIs but the concepts behind them are really the same ones that you should be used to at this point and the idea of those new concepts is they really do make life easier in the long run for developers because there's more consistency in the API it's easier to test code and so forth so we'll have some examples of this again we're only gonna kind of scratch the surface and set a foundation because this is only our long talk we have I have done this as a four-hour training before so this is the teaser version so start with just enough theory so this is what a PHP for application looks like you have PHP boots up and you have a bunch of superglobals that get created you dollar get dollar posts and so forth and your PHP script runs and it does some combination of calling the header function to define header strings for the response and printing out text and you hope that you get it in the right order because if you don't everything breaks in annoying ways and that's the problem is that's not actually how the web works the web works more like this you have a request come in and that's over HTTP and HTTP request of some kind and your server does whatever it's going to do and it responds with a response which is a message from in HTTP that response that request this is subtly but importantly different because you're sending it back and forth messages not bunch of strings that you hope are in the right order and one of things we wanted to do for 2008 was shift from the old PHP for mindset to a modern PHP 5 HTTP mindset and actually using the web the way the web was designed to be used and long story short short we found another open source project called symphony who's had a component called HTTP kernel which was modeling exactly that concept in in PHP of request comes in response goes out and this was essentially what we were looking to build anyway so hey they've already built it let's use it open source for the win this is the entirety of that of that kernel interface it's an interface with a single method called handle that takes in a request and returns a response and everything else that happens inside that is your application your application lives inside that method and various other subcalls from it that takes the information of the request and returns response and that's a very powerful model to work with Drupal is what happens inside that handle method the particular kernel implementation that Drupal 8 is using is the standard implementation used by symphony as well as a as well as a number of other projects and it looks kind of like this so you have a request come in and then a request event fires events think object-oriented hooks essentially or rather hooks are a procedural version of an event model and you can think of the request event is like hook request alter essentially and a lot of stuff happens there like access control and routing then there's a controller event so part of the purpose of the request event is to find the controller which will be the piece of code that handles that particular request think page callback the controller events is essentially hook controller alter in practice we're not really using it odds of you ever touching it yourself are pretty minimal and then the controller runs the controller as I said is essentially the same idea as a page callback it's the particular piece of code that is responsible for a particular request and that can be in theory a function and method of an object method of a static class anonymous function in practice in Drupal that is 99.9 percent of the time a method of an object that controller can return a response itself or some other value and in Drupal's case you'll usually be returning something else and as some kind of intermediary if you don't return a response so there's a view event which only fires if you're not don't already have a response its job is to take whatever you return like say a render array and turn that into a response so that's where the page theming happens is in that event then there's a response event again hook response alter in essence and that response gets sent and then it's a terminate event think hook exit so the pipeline is similar to what we're used to but it has a much better set of places to hook in and the overall flow is a lot more flexible so mention these things called controllers and as that we use to think of these as page callbacks it's they live in the same place conceptually so this is your simplest possible controller it's a method of a class and returns a response object if you're not familiar with it this is PHP 5.3 and later code so classes are namespaced so we're saying the symphony component HTTP foundation response that is the full name of the class since we declare that up here at the top of the file we can just say all right response and we're going to return the entire body of an HTML page and then that's the end of it there's no theming that happens we have complete control over the response that goes back also important to note hello the hello method is the controller not the class the class is sometimes called a controller class but it is just a place to hold the actual controller the controller is the call is the method so this is the trivial case but you can also do something more interesting like return JSON data so there's a JSON response class which is a subclass of response and we pass it some nested array of data which as Drupal developers we should be familiar with and we'll render that into JSON and set the proper HTTP headers and format it correctly and all of that kind of fun stuff and all of that is taken care of for us this also means if you had to do anything other than return pages in Drupal 7 you probably run into the fun hacks you had to do where you would print something yourself and then return null or you would print something yourself and then call exit please don't do that all of those kind of hacks go away if you return a response you have complete control over what gets sent back and the theming system is completely bypassed for most cases you don't need that but for those cases where you want to do more powerful and more robust interfaces or powerful and more robust systems that is really nice there are other things you can do with the response and subclasses thereof so for example there's a stream response so let's say we want to get back a lot of data create a stream response and set its header you have type csv so we're going to return a csv file again no theming involved then instead of trying to build up one gigantic string that is the entire csv file which could be several megabytes in size we're going to set this callback function which this is an anonymous function in php 5.3 if you're not completely familiar with this syntax that's fine don't worry about that for now you won't be using it very often but the idea is this function here will get called later when we're actually generating the output which means this lots of data variable however big it is we are only going to have one record of it in memory at a time rather than building up the entire string we're just going to stream out our data set this is really good if you're doing exports or rest responses or generating a csv file or various other things because this keeps you from blowing out the memory on your server which is generally a good thing in actual practice most of the time your controller will return a string in which case the system knows aha the string is the body of a page or a render array render arrays are still around i apologize but a controller that returns a render array that render array will get rendered as the body of the overall page one important thing to note here is it's rendered as the whole page if the request is for html if the request from the browser is not for html but for say an ajax callback or a modal dialogue then that body of the page comes back wrapped up differently which means every single page in drupal can be rendered in a modal pop-up or can be loaded asynchronously from the server and just placed into an existing page just by varying the accept header in the request that's something you could never do before in drupal and is seriously cool you can also have parameters just like in page callbacks from the request so if we have a request to hello world from two notice we've got these bracketed uh placeholders here that maps to these variables and notice they're not in the same order they match up by name not by order so i can move these around to whatever order i want and nothing breaks and then we can use those values in a render array we also can have access to the whole request if we want to in usual practice you will not need it i recommend against yeah getting the request unless you need to access something like uh query parameters if you just need placeholders don't bother with the request then we tell the system about this controller with a yaml file this is roughly equivalent to hook menu hook menu in drupal 7 did about seven different things and that's a problem so as we'll see we've taken hook menu and ripped it apart into a lot of different single purpose tools which at first blush seems like a great more work in practice gives a lot more flexibility in terms of building and rebuilding the system so it makes it a lot easier to reconfigure drupal uh as needed important notes here so this is the route name every route has a machine name which is by convention module name dot something meaningful that something meaningful should not simply be the path it's a meaningful machine name not a script or the path the path begins with a leading slash and is the url at which this route should appear with placeholders under defaults we can specify default values for these placeholders as well as a couple of other special values that begin with an underscore in this case we're saying the content callback that is the controller that handles the body the page is the class drupal my module controller hello controller any method hello world which if i didn't have a type word my slides would be this method um under requirements anything that doesn't have a leading underscore is a regular expression for these values so you can have a route that matches only if a placeholder is a string or only if it's an integer or only if it's an integer between one and five or only if it is one of these possible these three possible strings and if that test doesn't pass you'll the system will generate a 404 not found for you so all of that can be taken care of you can also specify uh other requirements for access control for example underscore permission access content that means the user has to have the access content permission to get this route there are you can actually have multiple requirements specified which means unlike in drupal 7 where you had only a single uh access callback per menu item you can have multiple access checks per route and that the system handles negotiation of those so that's a another nice new feature so you probably think at this point all right enough this is enough theory what what can we actually do for reels and so we're going to go through a fairly simple module here and there's a couple of things i want to keep want you to keep in mind overall the the way you approach drupal is a two-step process first build a tool that can solve the problem you have and then wire it into the system don't just write code that solves the problem you're facing build a tool and then connect it in you should be used to this from the idea of hey write a module and then you can use the module to configure it it's that same concept taken down another level so uh that's same idea of build a module put it in place rather than just vomiting custom code in hard coding custom code in place that applies down at the individual component level now put another way in most cases what you will do is extend a base class or implement an interface you say you have a class that extends something or implements an interface and then you'll tell drupal about it and drupal takes care of it from there which again should be fairly familiar as you know the idea of write a hook with the right name and drupal will figure it out same idea here you write a class tell drupal about it usually explicitly and drupal will take care of it and that telling process could take different forms depending on what it is you're telling it about and we'll see a couple of those uh in a moment so how do I define a module how do I tell drupal I got a module well this couldn't get easier you have an info.yaml file uh yaml is a configuration text file format that we're using all over drupal now uh for routing files um info files and so forth this is essentially the same as the info files we were using in drupal 7 and in drupal 6 and in drupal 5 except it's now in yaml instead of our own custom format that's it all you need is the info file uh you don't need to dot module file anymore and you know that module shows up in modules page so that couldn't be easier then you have just the code you're actually going to use so for example let's put a page at a url so we're going to create a file in um called a hugs controller we're going to have a module called hugs and it's going to live in the slash modules directory in drupal 7 earlier we would have said never ever put modules in slash modules because that's where core modules go in drupal 8 this is where you put them core modules have moved off to another directory so um just roll with that but you have a module called hugs inside of which we have an src directory which is where all of your object oriented code lives and the namespace of your code is going to be drupal hugs because that's the name of the module and then whatever else and that whatever else maps directly to uh the file name so this is the class hugs controller hugs controller in the controller sub directory uh sub namespace from our module one to one mapping and we're going to extend from this controller base class which has some nice utilities for us and then we've got our controller method called hug it's going to take two parameters to and from and we're going to just format a string uh using the t function or t method works the exact same way as the t function we're used to except because it's a method it's a method on the base class on controller base and there's other utility methods there that let us uh make it testable if you use functions inside of a class you cannot unit test the class period and a lot of work is going into drupal 8 to make it possible to unit test more code and so that you'll see a lot of utility methods like that that bridge to older systems but the logic of t is pretty much the same so we're just going to make a string and return that string and we're done and we tell drupal about it in our hugs that routing file in the module give it a path of slash hug from two again notice the order here the order on the previous slide don't matter or they're not connected we're going to not give the faults for these but we're going to specify our our content callback which is that method we just defined and we're going to give the page a static title of hug and require the access content permission and when we do that we go to our site slash hug slash from two and we format larry sends hugs to jupycon because jupycon is huggable he's friendly and that's a page write one method one file to tell drupal about it and you're done pretty much the same level of effort as in drupal 7 with hook menu entry and the callback the code's just moved around so how do we make content venable how do we make it more fancy than just a hard coded string so for that the theme system the registration for it has not changed radically it's still a hook theme hooks are still around and they still you're still returning an array of definitions so the template so the theme is called hugged page the template file for is hugged page and we have two parameters to that's theme key from and to so this should be very familiar if you've written in drupal 7 one other thing to note here this syntax may look a bit weird got this just a short bracket rather than typing up array this is the php 5.4 array syntax i use it on all of my slides because it's shorter and so saves room on slides you are free to use that or not as you'd like they are syntactically identical both this format and this format for arrays the template itself however has changed dramatically in drupal 7 we used pfp template in drupal 8 we're using something called twig and these twig templates go in a templates directory in our module and our names wherever the theme key is or whatever the template name is dot html dot twig and they look like this note here you've got these trans and intrans variables or markers what this means is the values between these two pseudo tags should be translated effectively it's the same as calling t on it but it's now in html markup so all of the display here is at the hands of the themeer you can push a lot of logic off to the template safely that you used to have to do either in your code or in a preprocess a lot of that can now just push out to the template where it belongs and now these double curly brace means print variable so we've got from and to or the variables we have and we're going to print from and to because these are inside translation tags they will automatically get escaped for us and then we can simply modify our controller to say you take those parameters pass them along to the theme layer and we're done notice here the controller is really really small that's a good thing and here's our output so we had the from it's with a strong tag and the two is an em tag and we're done and if you look at the source there would be a section tag around it if you don't want that markup cool use whatever markup you want or let your themeer use whatever markup he or she wants because they're the ones who should be deciding that that's their job so that's all well and good how do we make Drupal configurable after all that is the point of Drupal was configuration this gets into the new configuration management system in Drupal 7 the way we would do this is for simple things you'd use variable get and variable set and for complex things you would roll your own table in SQL and you're on your own neither of these is a good solution least of all for deployability and also for performance so for Drupal's 8 we have a new configuration system that lets you define configuration objects these configuration objects are encoded in YAML and you can interact with those objects directly without having to deal with SQL or loading and so forth and using that common API lets the core system automate a ton of things like take all your configuration and dump it out to YAML which means you can check those files into git and do your configuration deploying it that way this is way better than trying to shoehorn everything into features which was never designed for that anyway so we start off with in our hugs module we have a config directory and an install directory and a settings.yaml file and this can be any number so I can have a hug settings I can have a hugs dot you some other setting for a different form potentially in this case I'm just going to define a single property default count and give it a value of three if we wanted something more complex it's just a bigger YAML file we then also need to tell Drupal what the structure of that file is with a schema I'll be honest I don't fully grok all of the pieces of this but this is a standard YAML schema format and mostly this is for translation the system will work without these I believe but you want to tell the system which values are translatable strings and then you can even translate configuration values we're not going to get into that here but that's why that's there. Larry sorry to interrupt you we have a question really quickly for the hug page template is it hug underscore page or huge underscore page dot tpl for the template did I have a typo I don't know if it was a typo or maybe through the the question it was a typo regardless is it is it just the beginning part or with the dot tpl for the template okay so the you specify the template's name in the theme hook which in the 98% case is the same as a theme key name and then your template file will be that same string dot html dot twig technically we still support multiple theme engines I don't think anyone's going to use a different theme engine but in theory that's possible and that's why there's a little bit of separation there great thank you so now let's look at our form and you're going to look at this and go oh my god wall of you know wall of code not quite forms in Drupal 8 you're going to define with another class and by convention they live in the form namespace of your module that's not a hard requirement just like controllers could live anywhere but putting them under controller is the convention just for nice organization and everything here should map cleanly to something you remember from drupal 7 so we're going to extend to there's a form interface we have to implement in practice you're going to usually either usually extend either form base or config form base config form base is the equivalent of the system settings form function from earlier drupal versions we have a method that you require to influence that returns your form id and then a build form method which is essentially exactly the same as the build functions from from drupal 7 form array itself is still a bunch of nested arrays and that really hasn't changed your it's just a structure around how you define them that's changed so we have a number type which is a html5 number field that's new in drupal 8 title we're going to give a title for this form elements translate that again this t utility method and provide the default value here there's a utility method for called config it's part of the form base that gets us that hugs.settings file we just defined or that hugs.settings object we just applied so straight out of the gate as soon as you install the module its default value will be three and so you get the default count property it will be three if you had more properties in your in that particular settings object that config object you would specify those and you know get those values as well and then you return the parents build form which is you know the same as calling the drupal settings form in the past gives you all the automation and then your spit form method is your you know your form submit callback in which we just grab that config object again set the value that the user submitted and save it and we're done now we have to tell drupal about it again remember create and then tell drupal about it we're going to create a path admin config system hugs here's the route machine name give it a title and we're going to specify underscore form this time which says this page this route should give should give a form which form the form defined by this class and that will wire everything up for you of course we also want this to show up in the menu and so that's now a menu links yaml file the implementation behind this is currently changing but the syntax should be the same again we give it a title give it a description tell it the route name that this menu link maps to and its parent drupal seven would try and figure out the parentage based on the hierarchy of links based on the path that ended up being very convoluted and very complicated and more trouble than it's worth so now we specify it manually we defined a new permission there so we have to have a permission hook this hasn't changed at all since drupal seven it's the exact same thing so now we have that's a configuration page in the menu and here's the form with the form element we defined its title and so forth our save configuration button is there automatically and if you're on chrome the browser will lock this into integers and not that you enter anything else firefox currently doesn't support number elements so it will not but drupal will still enforce that on the backend so that's all automated for you that's creating and saving values for configuration so what do we do with that now so let's go back to our controller and enhance it a little bit and add a count parameter and we'll say the count parameter lets us specify how often or how many times someone gets hugged if count specified we'll use that if not we'll call a config utility method get our settings file and get that default so whatever the default is we'll use it unless the user specifies one in the path and we extend the the routing definition file so we add this extra parameter and let's give it a default value of zero zero because that's going to be false so that will if the user does not specify a count we'll get zero and then the controller will say oh it's false therefore i will use whatever the default is in the system we'll also restrict it to being numeric so if someone puts in you know larry slash duplicon slash bob it will give a 404 which is what we want we have to update the theme with a new theme key and we can even specify plural alternative in the case that's the count variable is plural exact same thing is the format plural function in PHP which we now do it directly in the template to show different strings and there we go we don't specify anything in the url then larry hugged duplicon three times if we do specify a value then that value is using fit done a little bit slow so how about blocks to talk about blocks we need to first talk about something called plugins plugins are the new hotness they are if you view c-tools plugins the same kind of idea but much better implemented a plugin is a swapable user defined piece of functionality a plugin type be a category of plugins so all plugins belong to a plugin type and discovery is the process of finding and cataloging all the variable available available i can use i can talk plugins of a given type put another way you can think of this as a plugin type it defines an interface a plugin is a class that implements that interface and discovery is finding all plugins that are implemented interface it doesn't actually use php's instance of check there are other mechanisms for that but conceptually it's the same idea really we're just abstracting and automating common o practices so make it really easy to slot these into the system in a way that lets the ui have control over which ones get used rather than the developer and that is really really important because extensibility in triple seven was kind of lame to be honest we had info hooks and that was about it anything else every module did its own thing a lot of modules leverage c-tools plugins but to be perfectly honest c-tools plugins are a nightmare from a developer perspective because they are trying to re-implement object-oriented ideas using nothing but php4 functions and it's really gross i sorry it's gross and so there's really no commonality between different systems you learn one system you have to learn another system differently in drupal 8 if you want a user configurable thing you use plugins that's just your go-to tool if you want to define a new type of plugin you define an interface you have a manager class which we're not going to get into too much detail and that's it and then modules can just slot their way into it which it really creates a learn one supply everywhere model which is what you want because that makes it a lot easier to pick up new parts of the system once you find this pattern in one place once you're comfortable with it in one place it applies to a whole lot of systems all over drupal we're using the same plugin architecture this is just a sampling of the systems that are now plugins which means they're a class with discovery mechanisms and you're done so let's look at blocks in particular plugins if in most cases their class does need to be in a specific directory so they're actually multiple discovery mechanisms the most common is annotations which is this block here and so we're going to say blocks have to live in the plugin block directory plugin block namespace and then their name for their class this block here is called an annotation it's a way of providing metadata about a class right on the class this is not PHP syntax it's a common extension that's used by a number of projects drupal symphony doctrines and a whole bunch of others PHP unit so it's not documentation think of this as an info hook that is put right on the class rather than put somewhere else and so it has a machine name as everything does it has a translatable administrative label as a category and then we are sending a base class again and the only method we have to implement is build or return our render array that is whatever the output is for that block this is the entirety of a block and that gives us this on our blocks config page we have this new hug status blocks we're going to add note the blocks are not you could define them once and use them once they are you define a class and then it gets instantiated a whole bunch of times and can be placed on a page multiple times just like class and objects each instance is an object of that block class so if we click that this link here hug status and we get this nice pop-up with the block configuration we can place it into a region this should all be familiar from previous drupal versions and we now have that block sitting on the side of the page and we can make multiple of those and put them in different places if we were so inclined let's make this a little bit fancier and provide some configuration so we still need the annotation i'm just skipping it for space reasons but we're going to add three methods here default configuration block form and block submit if you've used views plugins in the past this should be very very familiar we're going to give our default configuration which is there's one key called enabled which is true we're going to have a block form just like the block build method before where we're going to add a checkbox for enabled or not block submit just writes back to that configuration to that this configuration array and then builds can leverage that to vary its output and so we get this nice additional checkbox here if you want to override the entire settings form completely you can you should not do so in most cases but is potentially there to do so i'm going to try and go a little bit faster services this is something new in drupal 8 that when you think about it seems weird at first and not familiar but in practice is something you should have been doing anyway just with functions so a service is an object that does something not is something does something it is a it is a doer object these doer objects are stateless meaning they are not going to change their internal values once they're created if you call a method on a service object that does not change the service object it may write to a database it may return a value but the service object itself does not change that's something you want in most cases because it makes testing a lot easier it also makes bugs harder to get harder to creep in and in practice you'll generally only have one of them this does not make them a singleton they do not enforce this themselves but in practice something that's only going to exist once in your system is a good candidate for service that's in contrast to plugins where you may instantiate multiple blocks or multiple widgets or multiple image formatters so you don't want to make those services services you're going to want only the one of one instance of at any given time so that's a good candidate for service so let's have a service called hug tracker that tracks information about the hugging state on the site this is just a plain old php class nothing special about it at all we have an ad hug method and a get last recipient method and we're saving that to the state system the state system is a key value store in Drupal similar to variable get variable set but designed for not configuration but values that should not be deployed so that's things like the last time cron ran whether the site is in maintenance mode things like that which you really don't want to deploy from from a dev to staging to production but you still want to track and this is a good lightweight way to track that information in this case we're just tracking two values actually one value the name of the last person to be hugged and we're taking that state system as an injected dependency meaning we're passing it into a constructor if someone says dependency injection what they mean is you pass stuff into the constructor that's all it means we then tell Drupal about it in a yaml file as as always hugs up services not yaml we have top level key called services here's the machine name of the service here's the class that we just wrote and arguments are here are the other services that you should pass into the constructor so now when we ask the service container for hey give me the hugs hug tracker service Drupal will go out find this class instantiate it and pass whatever the object is for the state service into it and all of that happens for us without having to do it manually now let's go back to the controller and again wall of text but it's fairly bite-sized the controller base implements an interface for us called container injection interface which means if there is a create method we're going to get the container think of the container as a giant array of services it's really what it is this giant array of service objects and rather than Drupal creating an instance of this class for us we're going to create that instance by saying all right create a new instance of whatever this class is that's what static means and pass as its first parameter to its constructor whatever that hug tracker service is and then we save it to a variable and that's all there is to it and in terms of making this service available to us if we wanted multiple we would just add another parameter here and save it and so forth and then the only change we're making down here in our controller is every time someone gets hugged we call the hug tracker and add a hug to it so whoever was just hugged we're going to record having this service separate from the state system lets us vary how it gets stored we could potentially use entities or nodes to store this information instead if we wanted to get really fancy but that would not change this code and that's what we want the hug tracker contains our business logic and then on our block we can do the same thing we implement the block the plugin version of that interface have a create method which is the same idea but has a few extra parameters for it we just have to pass through it's a little bit annoying but we deal so pass in all of those parameters that are part of the plugin system and that same service save the same service and then in our build method we say all right if we're enabled then we say who the last person to be hugged was by just grabbing that last recipient out of the service now notice this code is really readable because oh hug tracker guests get last recipient so I know exactly what I'm getting back I don't need to guess I'm the method itself says what my business logic is that's a good thing if you don't need to document that method because the method name itself documents it that's good you still want to document things in general but your code should read it nicely and now when we display our block the last person to be hugged was druplicon so we say druplicon is the last person hugged obviously your business logic would be a little bit more complex than that I would hope but hey if hugging is all you're doing with your site more power to you how about content is our last section we're working with content what how does that API look like in Drupal well Drupal 7 introduces this thing called entities and Drupal 7 the API was a third baked if we're being polite it was thrown into the last second it barely worked an entity API module in contrib was used inconsistently it also had some issues with it mostly around complexity so that has been totally revamped for Drupal 8 and it's much nicer all content an entity it can be anything that is a storeable a storeable ID with an object that is we can store it and load it the same thing again with an object think nodes users and so forth there are two kinds content entities which generally are fieldable and configuration entities which are a useful layer on top of the configuration system you will probably not interact with those directly but those are used say when you have that block and we were editing its configuration by just setting values on the configuration that's actually a configuration object behind the scene that data could save to a configuration entity and saved just like any other configuration objects and therefore that is deployable meaning block configuration is now deployable and as I mentioned the API actually works now and there's there's still some things changing in it but the basic API is quite nice source content entities go this is the list you should be used to right now if you've worked with Drupal nodes users terms files comments we've got a couple of others now and about a dozen configuration entities there is some stuff you can do with configuration entities like I don't know if we're at the point yet where we can do a view of views but people are working on that so let's create a node let's create an article with a title and a body and a couple of tags tags are taxonomy terms which are another entity and so if you've worked with a triple seven you know term reference is actually a reference field to these other term entities that part hasn't changed conceptually so let's make a new route at node slash node slash hook this placeholder is using the name of the entity node which means we will automatically try and up cast that integer to an actual node object that logic is going to change that there's a patch in the queue right now to make it not depend on the machine name here but instead depend on the type into the controller which we'll see in a second which is a good thing to make it possible to have multiple nodes in the same path automatically up cast so let's give it a new controller method node hug same permission we could if we wanted to restrict this to being an integer probably should have and now let's play with that object so we've got a node it's been up cast for us by magic we're going to specify syntactically that has to be a node because nodes are all entities are not classed objects and that way if something goes wrong ph people yell at us very clearly with what we did wrong rather rather than waiting for oh property called on non-objects go figure it out yourself because it's an object we have methods on it that make sense so for example node is published we'll return to our faults node get owner returns the user object that is the author of that node and that object because it's an entity we can call methods on and get its label labeled is the abstracted form of no title or term name or user account name all of them are now called label so the the interface for it is very consistent additionally if you want to get fields out of a an entity that api is that syntax is greatly simplified body here this looks like it should just be a bunch of objects but this is weird these are not actually direct references there are no there's no body property sitting on the node object we're using the php magic get and set methods which means you could also say node method get property body this is the shorthand for it which is a lot nicer and if you do not specify the offset so all fields are multi-value of course as in triple seven but if you don't specify an offset we assume you mean the zero with one this is really really nice because if you know a field is multi-value you can specify the value you want or you can iterate over it if you know it only has one value then you can just use it as if it were single value if later on it becomes multi-value because you've changed some configuration the syntax doesn't break because we're just going to assume oh you meant the zero worth value the first value which is what you would have had anyway so this is a lot tercer a lot more robust a lot easier to read than dealing with the field array structure in triple seven which to me is a nightmare so we're going to grab out the body value and the format for that field and run filter on it check markup really should be turned into a service someone please do that we just haven't gotten there yet that I hope will still change we can also as I said iterate over a field because it's multi-value and each of these tags are going to be an individual term reference field for any field that is a reference which means entity reference term reference and I think that's it at this point there is an entity property which gets us the actual entity that that term points to so this is get me the name of all all the terms on this note in one line of really simple code this would be way harder and triple seven the syntax for this would not fit on this this slide would not fit on one slide if we were doing this in triple seven it's a much easier to read much tercer much more maintainable syntax so now that we've got our array of terms then we're just going to make another message and concatenate that message to our formatted value of the body not because that's a good thing to do but because it was simple enough to fit on a slide I can also return a title for the page dynamically rather than specifying it statically in the route so in this case we're going to say node label which means the node title and then specifies bundle bundle is the generic word for node type so in for taxonomy terms bundle would be the vocabulary users don't have a bundle for nodes if the node type again common word common method common interface which you can therefore use on any type of entity so if you want to write code that applies to all entities that becomes a lot easier because you don't need to do that weird you know get me the callback function that would get me the title if this is a no entity of this type that's just gone it's just encapsulated into OO and we're done so print that and technically some of this should be done in the template but whatever and here's our output we're at node slash one slash hugs and everyone hug name of the user that was the author of this node because the tags and here's the body for it and here's the node title and a type again not the most useful example of what do you want to do but it shows how the entity API works and what the syntax is for it all right that is your taste of Drupal 8 once again I want to reiterate build a tool wire it up that's the pattern throughout the entire system build a tool wire it up if we get into that habit then it will get you know Drupal 8's actually fairly straightforward and fairly easy the way you wire something up and the way you tell Drupal about it can vary but the general approach is the same the biggest difference is are you telling Drupal about something or you telling Drupal where to put something if you're telling Drupal about something it's probably going to be an annotation because you're describing you know here's the thing and here's what you need to know about it if you're saying here's a thing and here's where you should put it then it's probably going to be in a YAML file a routing file the services file menu links and so forth they're all here Drupal here's where you should put this thing because that is all technically configuration that means you can change almost all of that if you want to without technically hacking core there are different ways of going about that which I'm not going to get into here just for time reasons but that you have a much better control over the system much more flexible system now because you have this separation between building something and wiring something just like turning on and off modules in the past same idea just taken to the next level some good general guidelines for developing Drupal 8 smaller classes or to me small classes and smaller methods you want very small bite-sized pieces small bite-sized pieces are easier to read easier to test easier to reuse don't worry about breaking things up into too small of a piece you can do that but better to have things more fine-grained than less it's more flexible that way and easier to test your controllers should be very simple your controllers should not be doing heavy heavy business logic that's the job of a service pull a service into your controller and then your controller just acts as a bridge from incoming request to here throws some values out of the request add a service let the service do his thing and return a response you want your business logic to live off in services your forms your controllers should all be simple one thing to note i spent a great deal of time in Drupal 7 building a robust powerful easy to use database layer for talking to an sql database which we did not touch in the slightest in this entire presentation there is a good chance that as a module developer you will almost never write a sql query yourself that's a good thing if you do so it means you're bypassing all of Drupal's automation and all of Drupal's ability to handle configuration deployment for you to handle saving content for you to handle hey i want to swap out sql for mongru db or memcache or not memcache for content but you know i want to use memcache for caching i want to use redis for my key value store for the services for the estate service i want to use mongru db for my content if you're writing directly to the database you can't do that go through these apis which means they're now swappable if you're writing sql i'd say there's a 90 chance you're doing it wrong also if you find yourself unable to write unit tests not simple tests but php unit tests which we didn't go into for time reasons um then odds are you're doing it wrong if you find that writing a test with php unit is hard because there are lots of dependencies probably that's a sign you should break it up if you have code that's really easy to test and verify it's right odds are your code is right in the first place not a guarantee but that's a good guideline of if it's easy to test you're probably on the right track if it's hard to test you're probably doing it wrong which means even if you're not doing full-on test driven developments of write your tests first and then do everything else honestly i don't do that either but if you find yourself struggling with your tests because you they're hard to write that's your sign to yourself oh i should go improve this and you know make the code easier for me to test and probably find some bugs in the process that's been my experience and that in a nutshell is Drupal 8 if this is uh this taste has not been enough for you as george said earlier we do offer training classes we've done this as a four-hour training we're looking to do an eight-hour version of it as well we've opened to presenting at conferences as well as internal training for companies and clients so that's something that interests you to get in touch and with that do we have any questions we do have one question larry in symphony calling get on the container returns an instance of that service this not the case with the container here the container we're using is the symphony service container we're using their service container directly so when you call get you're getting back that service object and if it already exists you're getting back the one that's already been created if it doesn't exist it's going to get created for you without you having to worry about it so if you already understand how the symphony service container works ours is the exact same container great any other questions about here Drupal 8 or Palantir yes back in create method example something new static container get something was used in symphony container get something would return an instance of something okay let me go back to that slide because I I think to make more sense if I we just go a little bit fast a little bit slower through that short example great so let's see here we go so container get so this method is a static method so it's called statically on the hook hugs controller class and it's past the container this is the symphony container the get method on that container returns an instance of whatever this service is the hugs hug track tracker service we're simply passing that as the first parameter to a call to create an instance of hugs controller so this could be written as return you could do this as you know tracker equals container get whatever and then return new hugs controller with one parameter that is tracker this is just the common all in one style that core is using because there's really no reason to have the temporary variable for that and static is php 5.3 code for whatever class I'm in use that it's like self in earlier versions but it works correctly so yeah this is the symphony container and it is returning that service we're just passing that service directly to the constructor of hugs controller does that make more sense to whoever asked that question yes thank you very much good any other questions we have one do you think that Drupal 8 will have a core user module that scales for enterprise usage a core user module that scales for enterprise usage I suppose that depends on what you mean by scales for enterprise usage um Drupal has been able to hook into say LDAP for user authentication for a very long time and to the best of my knowledge that still works in probably very similar to the same way I haven't worked with that part of the system directly um you know obviously Drupal has been able to handle having millions of users in a system before Drupal.org has been running with you know over a million users for some time now um yeah can you clarify what you mean by enterprise levels of user management I'm not sure what that means specifically if you want to go into another question of that personally no in the context of cache a being busted when a user logs in oh for caching purposes um so let me go into a bit about what we're doing with caching um in Drupal 7 uh and earlier we have a page cache we have a ton of low level caches and we have sort of render caching which is rendering the caching the render arrays and the page cache works for nano users and is completely disabled for authenticated users because the content could vary um and then the render cache in practice in Drupal 7 almost no one used because it was all opt-in and you had to do very special things to make it work and block caching didn't work half the time and so on so in practice Drupal 7 earlier you had your head good performance with page cache on or you hope you have okay performance with page caching off for any who's logged in that basic model hasn't changed dramatically in Drupal 8 however most of the reasons why the partial page caching and render caching and so forth didn't work so well is because of globals because when you had Drupal uh say if you had a formatter that was or a view plugin that was creating a uh output that required a css file it called Drupal add css which is a global function that stores in a global variable that you need a certain css file if that gets cached an extra quest the output is cached but not the fact that you need the css file so the css file is missing and your page breaks which is why in practice you couldn't really do any good render level caching in Drupal 8 all of those Drupal add functions are either gone or being removed you should not use that instead you will be specifying those in the render arrays which means we can actually do automatic caching of parts of the page so this is still active work in progress but the idea is if you log in and most of the page is still the same as it would have been for an anonymous user or for some other authenticated user then most of it will already be rendered and not have to resend everything as I said there's still a work in progress and a lot of it is just swirling out all the places where we have globals and global state and getting rid of them and working out with those communication channels but that's the the intent there it's not quite full on esi at this point long term that's where we want to go feeling a lot of that's going to end up in contrib a large part of my work in core these days is continuing to line up the dominoes and get the pipeline in place so that contrib can do things like esi as the way the page is built and that's that kind of thing is how we hope to really improve the the performance for the typical authenticated user by being smarter about the information we have smarter about what content is on the page is where and how it gets built so that we can intelligently cache it rather than leaving that entirely to the module developer or the site builder to try and figure it out and adjust themselves because no one ever did that and so we're trying to automate that process does that answer your question yes two more questions and then I you know I want to be cognizant of everybody's time there's a question do you think that uh jubilee will support all jubilee seven hooks jubilee support all jubilee seven hooks no a huge number of hooks have been removed because they either don't make sense anymore or they've been replaced by plugins or they've been replaced by something else so hooks as a concept still exists they are the only place that you should have procedural code another general rule if you're writing a function that is not a hook you're doing it wrong hooks are still functions um that's the only procedural code you'll have if something was an info hook in the past it's probably going to be a plugin now like the block system had five or six hooks none of those exist anymore there's just hey you have a plugin make a class you're done and so that's kind of the approach there so definitely not all hooks from Drupal 7 will still exist many do hook theme hook permission and so forth are still there some still work in essentially the same way others have intrigued a little but yeah that many hooks have gone away and that's a good thing great last question will Drupal 8 also support PHP template in addition to twig in theory it does support that right now in practice I don't think anyone is actually verifying that it stays working because I don't think anyone really wants to use it if you have a theme in Drupal 7 that's using PHP templates I would recommend rebuilding it in twig anyway not just for the syntax but because so much of the default market but the system has changed to be responsive and to take advantage of the fact that we now only are caring about modern browsers i.e. 9 and up that you're going to want to take advantage of that anyway I couldn't actually tell you offhand if you know a PHP template theme from Drupal 7 how easy it is to try and use PHP template in Drupal 8 4 there will still be some things that change in that it will be some rakeage so yeah in theory it's supported in practice I wouldn't bother with it okay great thank you I'm going to switch back over to my slides now thank you Larry thank you everyone for participating that was a really great webinar we had a lot of positive feedback and we appreciate your time Larry and George putting this together and we know this is only the tip of the iceberg there's so much more coming up with Drupal 8 and we're really excited to see that just a really quick reminder again we had Drupal call in Austin coming up in June we have global training days a great opportunity to get your Drupal training company showcased and really participate and get back to the community wherever you are and again we have our next webinar in May on May 13th about how to hire a great Drupal talent and you can see all other listed webinars coming up and Palantir is also sponsoring Drupal Austin so come by and talk to us at our booth we're happy to answer questions about Drupal 8 there as well awesome I also wanted to add in when Drupal 8 is released and I know a lot of people were asking this question there will be very in-depth conversations and training sessions from various sources on really how to utilize that and I'm sure Palantir again will be a part of that as well I just wanted to mention that we have Drupal Association organization membership as well as an individual membership these are the these are the things that also help fund more scholarships grants and our servers to make sure that we have everything that we can do for our community and support as many people as possible so thank you to everyone that participated we had really great attendance and great questions from our attendees and also again thank you to Larry and George from Palantir please feel free to get in contact with them if you have any follow-up questions or you can also call email me lauren at association.drupalup.org and I can forward those questions on to the guys thank you guys thank you take care