 Some people are still coming in. I want to make sure I give you guys enough time to ask questions and kind of get through all this. So welcome. Thank you again for coming to my session. 30 awesome Drupal 8 API functions you should already know, this giant sentence of a session. That seems to be like the new hotness when doing sessions at conferences. It has to be like this very snarky, memorable sentence or it won't get actually accepted. So hope you guys like it. If you want to grab the slides, that's the bit.ly URL up there. I'll show it again at the end. There's a GitHub repository. I'm actually using Reveal.js for the slides. You can grab them because I'll be showing some code. So don't worry about taking pictures of slides and stuff if you want to go and look at them. Then of course, if you want to follow me on Twitter, you can do so. The only caveat is my first name has one e and no k. If you add a second e or a k to it, then you won't be following me. You'll be following some other random person. All right, assumptions. So in this session, the first big assumption is that I assume you want to see some code. I labeled this talk as an advanced session, so it'll be kind of deep diving into the code. I'm going to do my best to kind of interpret it as best as I've looked at it. We do have some distinguished VIP core contributors in the room. So if I say something wrong, I'm sure I'll be corrected. And again, that's part of open source, right? Fork modify and do what you got to do. I'm also assuming you've written something custom, preferably in PHP, if you're coming from a different language. Hopefully a lot of these concepts are pretty similar. I also assume you like using APIs, and APIs in the general of, I want to connect things. I want to be able to change assumptions. I want to see the assumptions that are made behind the scenes in Drupal 8 that are going to empower me to do these really, really cool and awesome things. The fourth assumption I'm making is that you understand the concept that Drupal is a framework. It's not just a CMS, right? It has this very robust, documented set of API functions and just like Laravel or just like Xen framework, right? It has this kind of architecture, and you understand that that's part of the package you get with Drupal as well. I'm not going to argue the merits of those other ones. I'm just saying that the concept is there. Then the fifth one, and this is probably a stretch assumption, is that you've read a blog post that I made basically talking about KDS. And KDS is this really simple philosophy of keeping Drupal simple. And basically only build what you need, right? And if you want to kind of find more about that, there's a link about it. But it's a little bit of a pitch to really kind of think about what architectural decisions you're doing when you're embarking on a project, right? Build versus buy, i.e. should I create something custom versus going off a third-party module? What type of API function should I constantly and consistently be using that kind of thing? So if you take that, and if you're curious about that, please go ahead and take a look at that blog post. It's pretty cool. All right. So you can probably notice I skipped over who I am, but my name is Frederick Mitchell. I'm a senior developer at phase two. And my passions are Drupal. I've been doing Drupal for, I don't know, X years, five, six, seven years. I have to look at my Drupal.org page I haven't looked at in a while. I'm a big proponent of the dry principle, right? Don't repeat yourself. Keep it simple, stupid, silly, whatever. Basically, trying to come up with solutions that you build once and then you use over and over again. And I'm proud to say, right, D8 has a lot of that philosophy kind of built in. I'm also a big fan of strategic communication, right? So if you're a developer or you write a lot of backend code, sometimes it's frustrating to build this really cool, awesome thing and then no one uses it. Or no one uses it correctly, or no one uses it the way you intended. So getting into the idea of how to use strategically communicate principles to clients in terms of what they want versus what they need versus what we've built. Save them money, et cetera, real big into that. And of course, I'm also big into graphic novels. Watchmen, that kind of stuff. So if you wanna get in that conversation, please, you know, ask that question till we can talk about that all day. All right, cool. So before we jump right into these functions, right? Quick disclaimer, in Drupal 7 API functions, right, was the same thing as saying the common procedural functions, right? The word function was the common procedural functions we use in D7. In D8, I'm pretty much using the same thing while acknowledging, right, that when I say API functions in my talk, right, we'll probably be talking about a lot of common class methods, right? Or common classes that you're gonna be using with your D8 stuff. In some cases, I'll actually highlight some procedural functions that actually act as wrappers around certain classes and methods. So we'll kind of talk about that a little bit too. So the functions piece still kind of fits the narrative. And again, the whole point of this conversation is to kind of talk about what we're doing now or what's happening then in terms of Drupal 7, what we're gonna be doing now in the future with Drupal 8. Additional disclaimer, disclaimer. All these recommendations are based off of my introspection of Drupal 8 as of today, right? I've changed this presentation seven times. As many times I've given it, why, because as we all know, Drupal 8 is an alpha and things change. So if I have some names that have changed or pulled out, please let me know. I did my best to kind of go through them and update it for you guys today. So things will change. They will change, not may, they will change. I probably should change that too. It will change moving forward. All right, so let's get into the meat of why you guys are here. So let's start simple. Strings, right? Strings are how we print things, or echo things, or get things out into whatever type of context we plan to consume that content. String, static method, check plane, right? So in Drupal 7, we actually just had a procedural function called check underscore plane. It was a wrapper for HTML special characters, right? That procedural function is still there in Bootstrap, but it ultimately just calls the static method and the string utility class checkpoint, right? So instead of calling HTML special characters, it actually refers to this method. So as I said, you can still use check underscore plane, but again, the idea is to kind of show you that as Drupal is progressing, they're doing that, we're doing a counterbalance between legacy procedural functions and then jumping directly into the appropriate utility classes as you need them. Another one, Drupal underscore placeholder, right? Anyone use this? D7, if you were like, what are you talking about? I've never seen this function at all. So Drupal underscore placeholder is another string function allows you to wrap m tags around a particular string. And again, I'm just kind of highlighting, this is another one of those static methods that's inside the string utility class, right? And that still is in Drupal 8. I'm assuming everyone's heard of t function, right? T function, okay, cool. Yes, I have no idea. Drupal 9 question, that's an interesting question I honestly could not tell you. What's gonna be eventually deprecated or not? But to answer the question, no, I don't have any indication of that. The question was, is there any indication that these will be deprecated in Drupal 9? And the answer is I'm not, I don't think so. That indication hasn't been made, doesn't mean they're not gonna be deprecated. So yeah, getting into the t function, right? We know what t is, it allows you to translate, right? And it sanitizes input if you pass in placeholders. That still exists in D8, which is awesome. So there's a quick little example there, right? And depending upon the keys of how you pass in your placeholder values, it'll either wrap your text around, right? The check plane method we just talked about, placeholder, or actually print it without any type of sanitization at all if you use the exclamation character. So simple enough so far, strings, t, got that. Okay, let's go into the L function. L function's still there. That's good, right? Able to create links pretty easily, programmatically, using a conjunction with the t function, no changes there. So far this presentation has gone, swimmingly no conflicts, t and l is still there, no one's gonna throw a chair at me. You may, by the end of this presentation, there's some function here that I'm gonna say I've been removed, but so far it's going okay. All right, so we got the string stuff, pretty straightforward, not too much, DX changes there. Let's get into rendering, right? Making stuff pretty. Actually taking the content that we have, maybe putting it inside of an array or theme functions or what have you to, again, kind of add that additional layer of user experience context to the content we're presenting. So in Drupal 8, just as in Drupal 7, just as in Drupal 6, Drupal render, right, is still there. And basically as you guys probably already know, Drupal render allows you to kind of give it an array with various keys and then it will do some sort of magic around the various pieces, right, of data that you add to that array, depending upon the keys that you've signified and then give you some nice markup. So the big thing in Drupal 8 is, Drupal render is everything, right? There is no more theme function. Don't use theme function anymore, right? No more theme function. There is kind of buried inside of Drupal 8 inside some of the kind of dark halls of Coreland. There is an underscore theme function that will be deprecated and that will probably be removed. But when you actually want to theme something, you wanna basically build a render array, right? And as you saw from my example, you use the keys accordingly to define how your content should be themed and you use the pound theme key in your render array to determine what theme function should be used with this array of content, right? You can also use pound type, which refers to whatever elements have been defined and hook element info like table, link, et cetera and any other custom ones that you have. So a quick kind of code example, right? In D7, if we wanted to print out a table programmatically, we would call the theme function, we'd pass in our special name for table as the first parameter, then we'd pass in an array of values that the theme underscore table, right? Because it would eventually get passed at the M underscore table, eventually take that information and build you an HTML table. In D8, we actually just start with the array, right? In this case, because table is an element defined as hook underscore element info inside of Core, you can just do pound type table and then pass in the values as key specific to that element type. So header, rows, et cetera. And once you've done your render array kind of setup, you just pass in a Drupal render and you get your stuff, okay? You see a little bit different there with the pager. Pager, that's technically not an element. So in this case, you would actually just call directly from Core the pager theme function by passing in an array with a key of pound theme, okay? Cool. So we did strings, we did rendering, right? Let's get into some meat of stuff. Nodes, storing content and data, right? Wait a minute a second, okay. So I was around in a Drupal 5, Drupal 6, and then when Drupal 7 came around, we had this big ho-up about entities and everything's an entity and forget what a node is. A node is nothing anymore and node is just this thing that's essentially an entity or what have you. Aren't we still gonna be talking about entities with Drupal 8? Why are we talking about nodes? And the answer is yes. We are gonna be talking about entities and I'll get there in a second. All right, so in Drupal 7, the really cool function that I'm sure you guys are all using, right? I'm hoping you're all using, no load multiple, right? When you want to programmatically load an array of nodes, you would use no load multiple. In Drupal 8, right, you're gonna use entity load multiple, okay? So no load multiple is technically still there in Drupal 8, but if you were to actually inspect it, all it's doing is calling entity load multiple, okay? So kind of knowing that any load multiple is that procedural wrapper, so there's almost like two wrappers, right? You got no load multiple calling any load multiple, which ultimately calls, right, the load multiple method for the controller of the entity that happens to be loaded. So nodes, as you know, excuse me, are default entities, right? They're defaulting is to come with core, so the controller that's defining, the controller class that's defining the entity type of node is already there, and so it automatically knows to call the load multiple method for that specific entity type and that specific controller controlling that entity type. Users have a different one, right? And a lot of things are entities, and we'll get into that in a second. Field configurations have their own, field config instances have their own, et cetera, et cetera. And again, that controller is more than likely, again, that storage controller for that entity, and then that storage controller likely ends up ultimately implementing the entity database storage class, okay? And so I wanna stop here just real quickly just to kind of think about that for a second. In Drupal 8, right, we're finding this balance between the functions you know and love, right? But you're at this presentation and kind of trying to figure out, okay, what do they do behind the scenes? And does it behoove me to basically understand what's behind the scene, so that way if I need to change those assumptions, I don't wanna change the storage controller for my custom entity or nodes in general, right? Maybe you have some custom storage controller where you want the node system to look at something completely different, right? Or a new type of database storage. Knowing the behind the scenes, right, allows you to change those assumptions because of the object-oriented architecture that these procedural functions are wrapping around, right? The nature of object-oriented architecture is you can create your own child classes and inherit or implement the various interfaces that are assumed as you need it, okay? So quick kind of code example, right? You have entity load multiple, you pass in your entity type as your first, right? Parameter and then you pass in your NIDs. Just recently, and recently I mean as in last week, there was a new helper static method that I was throwing in there that you see there and you can use that instead of having to call any load multiple and pass it in, they actually have some helper static methods for the first class entity types that come out of core. So for nodes, users, I think another one's like filter formats, all the different entity types that are in there, right? We have the static method that instead of doing any load multiple, et cetera, you can actually just do, right? You'd use the node namespace and then call the load multiple static method and it'll automatically know that it's tied to the node entity type and then you pass in your NIDs accordingly. So there's a lot of these helper static methods that kind of shortcut a lot of stuff. But I think it's really cool because then it'll make it easier to kind of eyeball and skim and read when it comes to, you know, when you're on multiple, when you're in those projects that have been around for a little while and you've got multiple people doing multiple things and changing different stuff, et cetera. Entity view multiple, right? Kind of the same thing. In Drupal 7, you had node view multiple. In Drupal 8, it's entity view multiple. And as we know, this is just how we create a render array of many node entities, right? So as I said before, node view multiple wraps around entity view multiple. The entity view multiple, again, depending upon the entity that you're actually trying to view, in this case, we're talking about nodes. It's gonna load or call the view multiple method, right? That's a tie to that render controller class. That render controller class, more than likely, is the get view builder portion of that entity. And that builder controller is likely gonna be implementing the entity view builder class, okay? So again, just kind of give me a little bit of backstory of how these wrappers, some are there, some are not. So we gotta kind of follow the train of thinking of, okay, why do these still exist? Okay, they're more of a DX, right? Decision to kind of keep it there. But as you get more into DA, when it finally becomes available, it's good to, again, know how the sausage is made. So if you wanna add some cool little spices in there, you can make some spices. Like the metaphor? Cool, so again, quick code example. Any view multiple you pass in, a whole bunch of node objects. Do what you gotta do. All right, Drupal 7, node save, right? That's how we did in Drupal 7, Drupal 8. We're gonna use entity create, right? And this is actually pretty cool because now with this, right? We actually don't need the special procedural function for just nodes. All our different entity types can use the same, right? This same procedural function, entity create. So node save is gone. So in the other cases where it was just a wrapper, this one is actually completely gone. So entity create actually wraps around, again, the controller for that entity and just calls the create method, right? Same kind of, again, deal with the storage controller for that particular entity. And then it's gonna use the entity database storage class. I know that storage controller is probably not the class name anymore. I believe that changed recently, so I need to update it. But the concept is still there. Each entity has its own storage controller and then that controller will implement or implements the entity database storage class for that one. So again, from quick code example, right? You could do entity underscore create, pass in your node type and then pass in any other properties you wanna set for the entity. Similar to what I was talking about with the load multiple, right? Helper function just recently, as of last week, I think it was May 28th. There's some helper methods for the first class entities there too. So if you wanna create a node kind of programmatically, again, you would use the node namespace and then just use the create static method. Does the same thing, okay? So you can set your various properties on that node object, then call the save method and you got your node saved programmatically or any entity in this case, right? Cause it's using the entity create portion. It just happens to be a type node. All right, everyone with me so far? Did I bore anyone, people? Anyone wanna sleep out there? No, okay, cool. So everyone's still with me. So we talked about, again, strings, rendering, talked about storing data with nodes. Let's get into menus, right? You guys love building menus programmatically, right? Everyone loves doing that. So in D7, you had hook menu. Hook menu is gone. Any chairs, any chairs from? Hook menu is gone. I know one change long, a long time ago said hook menu is still there. The last change like I looked at said hook menu is gone. I believe it's gone. So if you've heard otherwise, we can fight about it in the hallway. From what I understand, hook menu is gone. The way that we now define our menu items or in this case, paths, right? We use a routing.yaml file. I won't get into yaml files too much. I'm assuming again from the advanced session, you guys kinda know what yaml files are, right? Their static files allow you to kind of set configuration. In this case, what we're saying is, is that routes are configurations of pretty basic symphony concept. So again, a quick D7 example, right? You got hook menu, you have your callbacks, et cetera. In D8, you basically define a routing file. A yaml, a routing.yaml file, excuse me. And then you point it accordingly to the method that's gonna be used on that route. This particular code example may technically be wrong because I know that in the course of me building the slides, Drupal 8 went from PSR-0 to PSR-4. So the way you actually call this may be a little bit different. So I apologize for the PSR Nazis out there. Oops, down arrow. Okay, here we start, and this is where the chair is really starting for me. All right, so in D7, we have this function called menu get item and it allows you to kinda get a router item, right? In D8, we're using the new symphony router system. Clap, all right, no clap for router system. Okay. I think this is awesome to be quite honest, like the new router system is symphony is ends above. Yeah, that's right. You gotta know, just taking it all in, you're like, okay, it's too much, I can't, I mean, catatonic shock, I can't clap. But anyway, using the router system, and so now instead of calling something like menu get item, which is gone, right? To get a router item, you're actually going to inspect the request object and then the attributes property of the request object. You can actually get a particular request object from there. So a lot of the code that exists in D8 right now, as of right now, that hasn't been committed yet, as of right now, disclaimer, disclaimer, right? This is how they're getting the various route objects and the same is true for our favorite function, menu get object, right? How do we know what node we're on? How do we load exactly what I'm looking at? Menu get object is gone, right? You have to inspect the request object. So in this code example, again, as of right now, disclaimer, disclaimer, this is how you would do it, but it'll probably change, right? You could use the global Drupal namespace and I'll talk about that a little bit. Inspect the attributes and in there you can grab the node itself. Now, as of six hours ago, see what I do for you guys? As of six hours ago, there was a patch that passed, all right, hasn't been committed yet, but there was a patch that passed that talks about a route match object, right? So now instead of having to go into the request object and find all the different things that you need, because there's a lot of stuff in that request object, there's now a helper function or at least a helper object to get the appropriate route. So instead of doing what I'm showing you here, there is a patch that passed as of six hours ago that should kind of help the DX portion of how do I get the object or entity that I'm currently on, et cetera, specifically with the node. So if you want to follow up on that, that link is there. And this is what it kind of looks like, right? Lot simpler than jumping into all the properties inside of the request attributes. You can just use the global Drupal namespace and we'll talk about that again in a second. I know I keep prefacing that part, but with a route match object, according to that patch. And this was a big conversation. I used to have a link in here what showed the Drupal.org issue with the 200 comment responses and I don't understand and I think we should do this in option 17, et cetera. At least this one has, this is what we're gonna do. Let's get the patch in there. Let's get it passing, et cetera. So this is, I believe, I hope, is the direction. That's gonna be taken and eventually get committed to core. Okay, so we talked about meaning to get object, meaning to get item, et cetera. We're hopeful this new route match object is gonna be completely awesome. And that quick little helper in the Drupal namespace, global Drupal namespace is gonna help us kind of get what we need. Going back again to that favorite topic of building menus programmatically, menu tree page data, still there. All right, you can create the page data for a menu using write a machine name or a nice clean name. You can still get that. Menu tree output, still there. All right, so if you wanna build again menu programmatically, what you're gonna use is, right, as we all know, menu tree page data, menu tree output is gonna give us what? Render array, right? Drupal renders everything. So now we have our render array. And if we now want to do something with that menu, pass to a new theme function maybe, what have you, just all you have to do is change, right? The pound theme key in that render array. Then print it out, Drupal render, yay. No more stuff in TPLs and pre-process and template of PHP, et cetera. That's all move away from that. So yes, render arrays, menu tree output, menu tree page data, still there. Two of my favorite functions, unsung heroes. Cool, menus, menus are there. Again, we're just gonna do 30. We're not gonna go through the whole change log and Drupal 8 library, just, you know. But menus are cool. Let's talk about taxonomy, right? We all know these are entities as well. Entities that allow you to categorize content, categorize your data, get some sort of organization. In that wild west of a content system you have. You can see that some of these names are kind of deep, but anyway, in Drupal 7, right? We had taxonomy, vocabulary, machine name, load. Wonderful procedural function that allowed you to load a vocabulary object using the machine name of vocabulary. That's gone, right? Because again, we wanna use the entity API and use all of the entity features and functions that have been built and all the classes that have been built inside of Drupal 8. We wanna use entity load, and as you probably can guess, entity load is a wrapper for a load method. So in this case, in this example, in Drupal 7, you would use taxonomy vocabulary, machine name, load, load the vocabulary, machine name, et cetera, and you'd get your nice, robust vocabulary object. In Drupal 8, we just call entity load and then pass in the entity type instead of node, we pass in taxonomy on a square vocabulary. Then of course, pass in that specific bundle that we're looking for, in this case, forms, and we get the same exact thing. Taxonomy get tree, programmatically building a tree of taxonomy terms, still there in D8, all right? That's pretty cool. You guys probably know this one already, but you would load your vocabulary entity and then you basically would just pass in all your taxonomy terms and build your tree accordingly and do whatever you want with your tree. Hopefully, ultimately passing it to Drupal render, render array, yay, no more theme function. Cool. All right, let's start getting into some real meaty stuff. So we talked about all, we talked about menus, taxonomy, strings, content, let's start talking about fields. Fields got a nice overhaul, right? In Drupal 8, fields allow you to organize the content, create these pivot points of how our content is structured. Before I jump into the code, I just wanna say that I think it's imperative, extremely imperative, that when you're working with folks and you start talking about structured content, right? It's very important to understand the power of using discrete fields versus giant WYSIWYG blocks, okay? Okay, I'm sure hopefully you guys go to Eden Session and maybe you've been to a couple of the ones that talk about the content API philosophy. Do yourself a favor and try your best to convince your organization, your clients to be as discrete as needed. If you need to do some UX improvements to make sure your content creators understand what fields are doing what, do those UX improvements but don't, in my opinion, don't just say we're gonna have a giant blob of WYSIWYG text and kind of move forward, right? The more discrete you can make it, the more future-proofing you're doing to allow you to connect to those discrete elements in various ways, whether it's an API layer down the road, whether it's gonna be consumed in an app, right? Whatever the context is, the fact that you've already structured it and had your content discovery in a structured, componentized way will save yourself a whole bunch of headache in the future and I think one of the shining and kind of unsaid points that I've heard about D8 is because of all these changes, the relationships of how content can exist and coexist with each other, now there's a more significant architecture to make those relationships even more robust, right? So that's my sole box, discrete fields as much as you possibly can. All right, D7, we had field info field, right? To get our field data. In D8, right, we have just a get field method on a field info object that can be returned. So in this case, what you're seeing is again, back to that global Drupal namespace, you'll see that kind of running theme here a lot. There's this nice kind of helper, right? Static container that's there to allow you to essentially load a field and then get the field information as you need it. So in these cases, what we a lot of times use this for in phase two is if instead of, well, let me say instead of, in the cases where features isn't a good fit and we wanna make field changes to a particular platform because that platform may be touching various different contexts, it makes more sense to change field configuration via an update hook versus telling everyone, okay, get out of the system, we're gonna do a feature revert and hopefully we don't break anything that you've done. All right, right? So kind of knowing these kind of field creation, field inspection, API functions is useful in certain contexts. Cool thing about the get field method is that it actually wraps around entity load, right? And why that's awesome is because now the configuration of fields is an entity as well. It's not just a giant array of garbage. Garbage is the wrong word. It's not a giant array of fun things, right? So the cool thing about, again, this is that there's actually a shortcut inside of, again, that Drupal global namespace. So if you really wanna just kind of get the field info, you can just call the static service method and again, because the configuration is entity, every entity has its own service. You can call services via the dependency injection mechanisms and containers that we have. There is a static service method inside the global Drupal namespace where you can essentially pass in that service label and it'll get you the information on that entity. So this kind of goes for all entities, but in this case, trying to paint, connect the picture. So we went through the whole like, okay, storage controller classes, field database, storage controllers, et cetera. Now I'm showing you at the end of the day, right? You've got this global Drupal namespace with this service static method and you can just kind of quickly plop the service information that you need accordingly. Get instance, very similar, right? Instead of updating field configuration, maybe just wanna update the instance of a particular field, right? Again, this idea that if you start with discrete fields, the idea of an instance is that it can be reused in various contexts, right? Those relationships, again, how do you get the information of that particular instance? Well, as you see here, you can grab the instance and then pass in the values that you need, the entity type, right? The bundle, and then the field name itself. This particular one wraps around in the load multiple, which we just talked about, right? And just like the field configuration, the instance configuration is also an entity as well. All right, so you gotta start to see and hopefully you're starting to kind of get these wide eyes, it's like, oh, okay, if everything is an entity and we have this architecture of various controllers and view builders and storage mechanisms for entities, now lots of things become swappable, can be, right? Extended, implemented as I see fit if I need it in that context without having to touch core. I just created a new child class. It's all starting to come together and that efficiency in learning how things actually exist behind the scenes is extremely powerful. Very, very powerful. I'm hoping you guys are starting to think about that as we're going through these, right? So again, quick little examples. We had, in D7 we had field create field, in this case we're still using entity create, but in this instead of passing in an entity type of vocabulary underscore, or taxonomy underscore or vocabulary, or node we're passing in field underscore config, right? And as we talked about, field config is an entity type, right? It invokes the create method that's attached to its storage base, the entity storage base, which just happens to be an abstract class, right? And field config ultimately maps to the field config and field config storage classes that are inside of core. So if you really want to kind of inspect and see all the cool stuff that you can do with the field configuration, definitely check out that class. It's very simple to kind of rock and understand, right? So quick little example, in field create field as we talked about our magic array of awesomeness with fields, right? This is what it used to be in D7. We'd have our custom field and we'd have all this array stuff. DA, look at that. All those lines saved. So much easier to understand. Efficient learning. That should be Drupal 8 mantra, efficient learning. You'll have to learn, but it'll be efficient. All right. Quickly, as we talked about, field instance configuration, same kind of deal, right? In D7, you had field create instance. D8, you're still using entity create, right? And it's just using, it's basically creating a field instance config, right? Object, because it's its own entity. Same exact thing, right? You use had its own field instance config and field instance config storage classes. Definitely jump into that and kind of look at all the cool little goodies you can do programmatically with messing with the field instance configurations. So again, in D7 instances, we're a lot more magical in their arrays, right? You'd have these giant scrolling things and then you'd wanna change something. In D8, just a lot more saner, right? Awesome sauce. Here we go. All right. Look at this one. So I'm actually like trying to do a shortcut and pack in multiple D7 functions with one kind of replacement DA function. So in this case, we talked about updating fields. We talked about create, et cetera. So in D8, we just have save methods. No more field create, field update field, field update instance, et cetera. When you wanna update something, you instantiate the field, right? Using our config object or what have you, our instance object. Then we just call the save method once we're done with it. Pretty straightforward. And the same is true for delete, et cetera. Kind of keeps going on. All right. Alters. I love alters. Sort of. Right? Changing the assumptions, right? This kind of aspect-oriented kind of idea of things calling themselves in this horizontal fashion before the execution continues. So Drupal alter is gone, right? But the alter mechanism is still there. In this case, we're using a module handler, right? Kind of helper that comes back again. So you basically end up getting a service back from this module handler static method inside again that global Drupal namespace. And then you can alter your data accordingly. Right? So instead of using Drupal and score alter, you just use this cool little D8 helper function. Obviously, if you're changing styles or if you wanna change something about, you know, please don't create a render array and then call an alter inside of there. And then next thing you know, you're like altering render array stuff, like probably makes sense to just change the pound theme key in your render array versus doing that chain of events there. Cook form alter, still there, right? So that concept is still there, which is pretty cool. If you wanna change something, you can still do your hook form alters. Hook form form ID alter, still there, right? Now the cool thing about this is, in D7, how do you get the ID of a form? What do you guys do? Do you do that right click, inspect element and look for the, look for the ID in the tag and be like, okay, I think this is the ID. Hopefully this catches, okay. Drupal, you know, Drush Cache clear, okay, this should, this should, okay, I got the right ID, great. Right? In Drupal 8, there's actually a get form ID method. Yay, which makes every form easier to find. What is the ID of this form that I want to alter? So here's a cool, quick example, right? I have my custom form. In this case, I define a get form ID method and that is, right, the string that I'm gonna use in my hook form form ID alter. Sweet. Good, efficient learning, right? All right, and we all know how a form form ID alter works. If you want more information on the form API for DA, definitely check that link out. Everyone loves forms, everything's a form, everything can be altered. We've all been down this road. Drupal 8 makes it even more awesomer. Yes, I made a word, you can tweet that. Make sure you CC me when you tweet it and make sure you like, you know, attribute me as saying awesomer in DA. All right, hooks, engage other processes, right? So in D7, you had a module invoke all, that's gone and said again, we have these helper methods, right? Static methods where we basically just call the module handler service from the global Drupal namespace and we just call invoke all as the method from that service. Get implementations, right? Anyone use this one a lot? See if a module uses a particular implementation of your hook that you've created. If you do a lot of platform building, you're kind of trying to build things that are gonna be reused in various contexts, right? So at phase two, we specialize in building platform, using Drupal as a platform, i.e. if you have these big organizations that have their own individual teams, but they want kind of a set way of doing certain implementations, right? Having a platform that they can essentially fork or start from, custom hooks, et cetera, using something like module implements, something they use all the time to kind of check, okay, what brand is using this, what site is using this, et cetera. Same kind of deal, you gotta get implementations, right? Static method there from that service container. URLs, grab the get, right? In this case, again, we talked about utility functions. I showed you for strings, there was a string utility function. Other utility function, there's the urithelper utility function, so Drupal get query parameters is gone, right? Anyone use that one a little bit? I like that one. Just grab the query parameters real quickly, do some stuff with it. In this case, we're gonna use the filter query parameter static method, right? From the urithelper class inside of our utility stuff. Quick little code example there. You'll notice that in order to get the URL, right, I had to instantiate the request object, but again, hopefully that won't be as, I don't wanna say ugly, but as not as nice looking as it will be once this patch kind of goes through in terms of getting the route. Paths, where am I? Where am I in my code, right? Drupal get path, people use this all the time, still there, right? Glad that's still there, that's the one that's used a lot when you wanna load specific assets or what have you. The user, global user is gone. No more global user, yay. So instead in D8, right, there's actually a helper method inside the global Drupal namespace, just called current user. If you wanna learn more about that, you can, it's pretty cool. So there's a quick code example, right? Actually you can get a full, you don't get a full account object, but you'll get a user access an object and just kinda quickly inspected to see what user is accessing, whatever I'm about to do. Oh, the other cool thing I wanna note out here, and again, this is kind of reiterating these points, the account that you get back from current user extends the account interface, right? Why is that cool? Because then if you then want to change the class that defines an account, you can extend that interface and now your new implementation will be part of it. Yay, module load include is gone, right? Now it's just a load include method on top of the module handler helper inside the global Drupal namespace, okay? Pretty straightforward. Queering entities, right? Who here has never heard of entity field query? Look at that, no hands. So proud of you guys. Any field query, we all know, right, that really awesome thing that Chex built to join all of the tables, the field tables for entities. Entity field query is gone, it's renamed. Now it's just an entity query, there's an entity query static method, again, part of that Drupal global namespace that just calls the particular service that does the querying, the entity query service, okay? So in D7 we would do some cool magic like this and instantiate an entity field query object, right? Add our conditions as needed, execute the query, get what we needed, node load multiple, et cetera, and manipulate it accordingly. If you've never used entity field query, I'd definitely recommend you check out my entity field query presentation, there's the link, but everyone here, no one raised their hand or at least some people were ashamed to raise their hand. So for those quiet people who didn't want to out themselves, here's a link, you can kind of note that down and I won't hold it against you. So in Drupal 8, again, here's a quick little code example, right? Use the entity query static method, passing your entity type, your conditions, et cetera, execute, and you get your stuff. There's a link if you wanna get into that a little bit more if you wanna argue with the core contributors about why they called it that, jump into the changelog there and have fun. Was that 30 functions? Man, I didn't feel like it, right? I mean, we kinda, somewhere removed and et cetera and, right, so what about those ones that would be completely removed? Which ones don't actually get a slide of a replacement in DA, like what happened to those, right? Let's talk about those. Drupal AdJS, Drupal AdCSS, Drupal AdLibrary are gone. There are no replacements. I love the tepid applause, you're like, wait a minute, so what am I supposed to do? Oh no! What am I supposed to do? So you're supposed to use the attached key, okay? And I recommend for those who don't know, this isn't D7 too, so you can do this now, right? So the attached key in your render array, yay! So the attached key is how you can load specific assets. So here's a quick little example. Here's the settings form, actually render array or form array in that case. In the settings form, right? I pulled this from CK editor inside of core. You can see that in the render array, we have the theme function defined, or in the form array I should say, we have the theme function defined. And then for the element of toolbar, you have this attached key, and then depending upon what you wanna attach, a library, a JavaScript library, et cetera, you just basically pass an array of those values, okay? So what did we all learn? Never use Drupal.ac.css, Drupal.ac.js ever again. I don't wanna see anyone in their D7 code using it. Go ahead and take it out, make a note, no more of that. You can use attached, it works today, use it today. Future-proof yourself today for D8. All right, 30 functions, here we go, right? Talk about T, check plane, placeholder. Some people probably roll in their eyes, I cheated with placeholder, no one used placeholder. L, Drupal render, right? No load multiple, no view multiple are gone. We talked about those. Node save is gone, no more hook menu, we're using the routing file. At some point we'll have a route match object, but in this case we have a request object that we inspect to get our attributes, et cetera. The cool unsung menu functions are still there. The long fun taxonomy function is not there anymore, but weak taxonomy is an entity. Any load to the rescue? Same with field configurations, right? The get field method, the get instance method, et cetera, creating entities, all that good stuff, only up to 17, all right? But then we talk about alters, form ID alters are still there. Invoke all, get implementations, right? Replacements, Drupal get quick parameters is gone, but we have a new helper. Drupal get path is still there. Load include entity query, that's only 28, what's that about? That wasn't 30. I was cheated. Well technically no, it wasn't 30 functions, but if you count the fact that I told you not to use Drupal.js, Drupal.css, Drupal.li library, you technically got more than what you bargained for. Plus, right? I have bonus, arg is gone. Yay, arg is gone. No tip and a plus for that one, huh? So this one was committed a couple of weeks ago as well. Arg is gone. If you want to learn what you're supposed to do, then get a chance to do a big code piece, so definitely check that out. Hint hint to use the request object. Yay, when you get object, it's gone, so now use the request object and then eventually use the route match object instead of arg. No one's happy about arg being gone? No one's happy about arg being gone. More bonus, talked about it, right? Technically this would probably get its own little thing, which it does. The global Drupal namespace. So this is, again, as I said, a static service container wrapper that basically just allows you from a DX perspective to quickly load your service containers and also has some other helper static methods to do some really cool things, right? It's a unified global accessor, again, to various arbitrary services, right? Again, we're kind of going into the service motif of various things. So whether you're using something, again, like get implementations or invoke all, they also, other really cool methods in there like has request, the queue, HCP client, et cetera. And again, if those particular pieces have their own service, it'll probably just call that service container if it's something else, right? Then you can expect it accordingly, but the global Drupal namespace, something I feel like you guys are gonna be using a ton. So love it, enjoy it, give it a hug and a kiss and it'll be awesome. So what's next? What should you do next? Contribute to examples. People like the examples module. I like the examples module. G7 examples were great, especially when people wanted AJAXI forms. Like AJAXI, okay. AJAXI form. I don't remember what am I supposed to say? States, is it invisible, is it optioned? Let me go check the examples module. Okay, cool, yeah, this makes sense. Okay, I can do that. Cool, right? Help the D8 examples. Definitely check out the API, right? It's got its own, just like anything else. It's got its own functions. Cool thing about the API, as you probably already know, right? It reads the doc blocks inside the code. So if something is labeled in the doc blocks as deprecated, it will show up in the API. So if you're looking at something, you're trying to figure out, hey, is this gonna be around in a while? You'll see it in the API documentation because it'll have the add deprecated tag inside the doc block. Another cool thing I would definitely recommend is try the scaffolding piece that my friend did, Jesus. If you're curious of how you're supposed to structure and architect your custom modules, this little scaffolding, little scout, this scaffolding app is pretty cool. It basically borrows from the concept of symphony for those who have no symphony already. It's a console application, right? We're essentially very similar to Drush. Load it up in the command line. It prompts you with a whole bunch of stuff and depending upon the services you want, it will pre-create your routing ammo files and your folder structure and all this other cool stuff for you. So you've got this kind of starter kit depending upon where you wanna go. So definitely check that out and that'll kind of give you again that meat to say, okay, this is how it's supposed to look and here's how the namespaces would go and this is what I would include, et cetera. Also next at DrupalCon, right? Participate in the sprints, right? Continue to help improve Drupal. We're still in alpha. Continue to help, help, help, help. Over 2,000 contributors so far. I'm sure you guys heard that a lot this morning at the keynote. But continue to help. And before I end, I'm gonna do something really strange. I'm gonna take, I believe, which is the first ever session selfie. So I want all you guys who wanna be in my selfie if I can figure out how to use them. Which I can't now, okay, nevermind. I won't do it. Sorry. You can see how often I take selfies. I don't even know how to use the camera on my phone. There we go, selfie. All right, here we go. Everyone say cheese. Cheese. Thank you very much. I appreciate it. Any questions? Thank you very much for being attentive and patient and awesome with me. Hello. What's up? How's it going? Hey, it's all right. What's your name? Derek. Hi, Derek. Is entity metadata wrapper kind of moot or unneeded now? And is like the method of accessing data any different inside of an entity like using field to get info and anything on that. So I believe your question is if I want to get the meta information in entity has how I'm doing it right now in D7 change in Drupal 8, is that sort of what you're saying or something specifically to the... I guess maybe it's two questions. One, has it changed at all in D8 for just accessing entity field data? Yes. And then number two, are there still plans? Do you know to port the entity API module maybe so that we can continue using entity metadata wrapper? I don't know the answer to the second one, but I do know a lot of the entity API stuff is in core. Yes. Okay. Yeah. I don't know if the specific metadata one wrappers that function specifically is in there. It's very similar. Oh, okay. Okay, so this man right here with the epic beard said metadata wrapper is being completely dropped entirely, so don't blame me. Yes, sir. Form building, there was a slide that had a very quick sort of class of like a base form, something like that. Yes. Are we building forms and functions or are they classes that return something? I'm gonna say use the classes. You can probably do both, but use the classes. Yep, use the form base class, just extend it, build your form, you're done. Do that. Yay, look who it is, guys, XJM. Yay. Hello. Hi, so Fredrick has done an awesome job of keeping the session up to date, but there is one big change I just wanted to highlight for people that went in a couple of weeks back that the field information's a little bit out of date. Okay. So if you guys wanna see the updated, the list of API changes with regard to getting field definitions and so forth, what used to be called field info, I'm gonna read a Drupal.org node ID out for you. So the node ID is 2167167. And let me just make sure, yeah, so this is the issue that removed field info star procedural functions and it's also a lot of related cleanup. And then they have a, the change record, node ID is 2260037, the title of which is field info methods are now provided by entity manager. So the source for that's moved to the entity manager class. So it's all in one place. The entity is where you need to know, you pass it an MEID and in the case of an instance of bundle ID and then you can get the field definitions from there. Thank you, Jess. I appreciate it. Yay. Sir. Hi, so maybe a silly question. Maybe I'm missing something. There are no silly questions. Wow. Maybe. So now that addJS is gone, if I have to, from a module level, add JS to every page, like with the every page parameter, how would I do that? Because now I don't have access or I don't think I have access to any of those render arrays at the page level. The info file of the theme? Well, but I don't want to do that because it's dependent on, it's the module level, right? Like what if I change themes? It's like I'm declaring this JS to make a module work. I gotcha. Right? Good question. And like if I don't add it to every page, like varnish will like say cache my home page and never get the JavaScript that I need to run something on my sub page. Hook page build. Thank you. Look at that. The answer is hook page build. I have to check that that's existing in DA. It is in DA, okay, cool. Hopefully that doesn't go anywhere. Any other questions? Did I miss anyone? Great, thank you guys. I appreciate it.