 The first thing I'm going to say is this is by far the largest room I've ever presented in so I'm right now scared out of my wets. So please like make huge jazz hands if I get way too animated and start talking way way too fast because I did that at Drupal Khan Bogota and I still have not forgiven myself for that so just let me know to slow down. All right so why don't we get started um just in case you didn't know which room we are in this is for capture the Drupal 8 flag. First thing you might be wondering is who is this weird person in front of you with the weird red hair and uh yeah you might be wondering yeah I actually do say that especially at 3am when the flag tests do actually pass. My name is Tess Flynn otherwise known as socket wench that's not wrench. I'm the module co-maintainer for flag for flag friend and for examples and I am a Drupal developer with FFW. There's a lot of different names for what FFW is supposed to stand for the one I'm most fond of is fruit flavored wombats. Who wants a t-shirt? T-shirt? I got one more anyone want another one? I think you raise your hand first. I've also got some flag stickers up here just a limited amount because I gave so many away already and I've got two sunglasses pairs of sunglasses so I'll be giving those out too. It's in case you didn't know we are hiring and you can either talk to me or you can talk to the people at the booth if the booth is still there because it's the last session of the con. So you might be wondering why the heck did I port flag module to Drupal 8? Well let's set the way back machine all the way to 2013 and I was in a room very much like this room at Drupal con Portland and I was listening to Angela Webchick Byron talk about the pants module and she was up there begging people please we need someone to port modules now because all we've done so far is core. We don't know if any of this will actually work in a module yet and I thought well yeah that's not a bad idea I can completely understand where you're coming from but yeah that's someone else's job and the thing is because my natural first question was why shouldn't I just contribute to Drupal 8 directly? I mean that sounds like the best thing to do right? Why waste my time on a module when I should be working on Drupal 8? Well there's a few problems I was facing. The first problem I would like to call is the reverse Sisyphus problem. Now if you remember the myth Sisyphus is a man that was doomed by the gods to push a boulder up a hill every day of his life and by the time he nearly got to the top of the hill and was almost finished it would start rolling all the way back down and he'd have to start all over again. Now the problem is the reverse Sisyphus problem is that the boulder is already running down the hill and I have to go and chase after it and hope that maybe maybe I can catch up to it. It imparts some small sense of momentum in it before it gets away from me again. I only had a few hours a night to work on this and every night I'd have to learn a whole bunch of stuff just to start contributing to Drupal 8. I had to learn about symphony. I had to learn how PHP object oriented programming works. I had to do all this stuff and I was like by the time I catch up at the end of a night because I start every night picking an issue study by the time I was done my three hours per night were up I had to go to bed next day I get back to it and someone already posted a patch. I was stuck in what I call the valley of earth. Now when you're a beginner you're up on beginner's hill and there's lots of stuff that you can do there's issue summaries running tests you could reroll patches but everybody really wants to be in dev city to work on to actually write those patches work on real issues really push core forward. The problem is between beginner's hill and dev city there's a big valley and in that valley of earth there might be some stuff you might work on. You've already you're already bored with all of the easy stuff you can do and it doesn't feel like you should be the one doing it because you're experienced at it you can turn it over in a few minutes a novice should be doing this now not you you want to do on something more impressive more interesting but there's not much between dev city and beginner's hill and I was really starting to bug me I was starting to get really depressed and I was sitting there one morning like any morning a good idea came to me while in the shower and it occurred to me you know given all this why don't you just do something else why don't you just completely change your strategy there's got to be a different way and I thought well I'm already a flag module maintainer why don't I just port flag module so who in this room knows what flag module is show of hands okay let me ask the opposite question who doesn't know what flag module is okay this section is for you guys and you know at one of you one of you should get a t-shirt or two shirts you and if someone could hand that way back to the gentleman way all the way back here there we go this is I'm amazed that my wrist is still holding up because I entered it in the cycling accident about three weeks ago so the flag module you'll hear this is picture of a rendered node on droop lake looks like any other node but there's these two little weird links at the bottom those are flag links now what does this allow us to do well let's abstract this a bit here we have a node happy little node and we have a user that comes along and goes oh shiny and they go and stick a flag in it the module that makes the point sound has yet to be developed you have a patch though I'll take it other users come along and add their own flags now from this we can actually come up with a definition of what flag module actually does it enables administrators to define boolean fields that may be attached to site content which each user each user may set or on set it's different than a checkbox because a checkbox only gets set once and usually only the node creator or editor can do that this is for every user it works kind of like this there are three principal objects involved there's the flag there is the thing that gets created to identify what the flag if it was flagged or not called the flagging and then there's the thing that we're flagging which my english teacher has never forgiven me for the flagable and it works kind of like this you can define the flag administratively and it lives as long as it's been defined flagging's can be a term be defined for the flagable entity and once a flagable entity a flagable has been a flagging has been created for the flagable entity it shows as flagged until they either unflag it or the flagging gets the flag it gets deleted I'm waiting for one person to finish their picture there we go so flags are the administrator defined boolean field it's stored as an entity since Drupal 7 since the module version 7x2x it may be attached to only one entity type but multiple bundles of the same type so you can define a node flag and it can be defined to one or more bundles one or more content types or you define a user flag or you define a comment flag in Drupal 7 Drupal 8 it's different or you don't have or you don't have to define oh geez there's a whole bunch of other kind of entity types that you could flag they're all created under administration flags and may be fielded as of Drupal 7 version 3x now flaggings are the entity created in response to when a user sets a flag it basically has four pieces of information in it which flag was set on what entity the flag was set when was the flag set and who set the flag flaggables are the entity that has a flag defined for it and for which flaggings may be created okay we know what flag module does now so let's sit down and we're ready to go we were said okay we're all fired up we're going to port this module to Drupal 8 it's going to be awesome there's going to be objects and there's going to be plugins there's going to be all this cool stuff and I'm ready to code in that's the last thing you should do first thing you should do is a code review ask yourself how does your module really really work one of the core pieces of flag module that I found is we have something called handler classes in the Drupal 7 version and they do a whole bunch of different stuff but usually they relate the flag to the type of entity that it actually applies to mostly the module is a pretty standard Drupal 7 module there's a large surface area of straight functions entity for support was refactored in object-oriented programming was actually used but well you know it's a bit like the blob php4 classes are just kind of weird today in flag there was a whole bunch of weird factory methods to make objects because there were no constructors in php4 and all of the object-oriented design in flag 7 came from php4 not 5 so we have all these weird factory methods all the methods were public too we had no access control on the individual methods all variables were public and basically what we got is a big blob of functions for every flag handler class it was a mess so now that we've reviewed our code we need to pick where we need to start the first thing after that how once you've done your code review you really want to sit down and look at it with new eyes figure out what you really want to do create a new vision for your module you want to question all the things ask yourself does the module really have to work this way we had to allow for assumption x before do we still have to allow for it can we do this better can we do the simpler you might also want to actually go and ask your users how do they actually use your module because you may have an idea on how your module is supposed to work but your users might have a very different idea indeed come at it with new eyes get up at 3am if you have to go on a vacation get away from code for a week and then look at it again anything to put you in a fresh mindset to look at your code from a completely new perspective and then start questioning everything then you want to set some expectations usually with the Drupal 8 module there's kind of two different perspectives you want to work at this there's the people who want to just get work done and then there's the people who just want to learn now if you're someone who wants to sit down and learn Drupal 8 and you don't care how long the porting process takes how many blind alleys you go down how many times you have to start all over again start now don't wait start now go go ahead open your laptop start coding i'll wait if you're the kind of person who wants to just get work done you're not that interested you just want to get the module ported and move on with your life then you probably want to wait now if you're in the middle you might want to keep it experimental open a branch or a new repository or a local folder of your code and just start playing around see what comes to your mind see what ideas you might want to explore most people are going to be in that keep it experimental stage you might have also thought okay well if i'm going to start my module i'm going to port my tests that's not a terrible idea test driven development has a lot of merits going for it but the thing is it's a double-edged sword simple test is available in Drupal 8 so you can largely write the same tests in Drupal 8 that you did in Drupal 7 it's not the preferred way it's probably going to go away in Drupal line but you can still do it now the only problem is that porting your tests means that you'll probably be limiting your thinking because with those tests come all the old assumptions of your module and you're no longer questioning everything after that identify the most central piece of your module and then work your way out now for flag module that was the flag entity so first we wanted to redesign the flag class with php5 and modern object oriented programming so what we did is we created a flag class but we also created a flag interface now an interface is kind of like a contract for your object it says this thing will do this stuff it's not the actual work but it says that this is the promise that we'll have these are the things that it will get done we also derive from a Drupal provided class called config entity bundle base and that does all of the Drupal work for us we break this down this is what the flag interface looks like it's a bit bigger now than it is but these are the core methods the interface is that contract it tells you what the module is supposed to do the things it does it does not contain any state or any method bodies it just contains the method names and signatures this is also a wonderful place to document your code because you can keep all your documentation in the interface class and the interface class then is a lot easier to read and then when you actually have your real code all you have to do is use an inherit doc in each method and you no longer have to have a huge doc block in your class Drupal has so Drupal 8 has two different kinds of entities in Drupal 7 we only had one an entity was an entity was an entity was an entity in Drupal 8 we have two different kinds we have configuration entities and we have content entities now configuration entity is designed designed for administrator defined structures it may be exported to YAML it lives in the database but it may be exported to YAML at any time and therefore moved from site to site to site and basically it's structure not data for our config entity we actually derive from this is supposed to be config entity bundle base the code is right the slide title is wrong it's the foundation class for configuration entities oh this does all the Drupal work for us so all of the extra stuff that makes an entity an entity is in that class we don't have to copy it we don't have to work with it it's just there all we have to do is extend from it and then it does all of the Drupal work in order to find the fields that belong on the configuration entity we need to create a config entity schema now the schema basically is a key value system that contains the data type of each field and what fields that it Drupal needs to save from the class this is a portion of flag schema it's stored in the module root slash config slash schema and you can see it's just a series of name values with types and labels this is just a sample there's a lot more in that class ideally we want to create a class variable for every field we define in the config entity schema this gives us a few different advantages it gives us code completion in our integrated development environment and it's also the easiest place to document the schema don't document it in the yaml file it's a mess it doesn't work very well documented in the entity class it feels much more natural it will belong there this gets to another point please please use an IDE and a debugger yes really it's time in Drupal 7 we had about 3000 files of which you needed maybe a dozen of them in order to actually understand how Drupal was really working how to write modules with it and those files tended to be very big in Drupal 8 there are at least five times that many files and each one of those is much smaller using a basic text editor can be done but you either have to have an amazing memory or you have to search google a lot an integrated development environment will actually save you a lot of time and a lot of hair pulling it will be frustrating if you're a plain text file editor at first then in a few weeks once you get used to it you'll wonder why you haven't done this sooner I like PHP storm but there's also net beans and a whole bunch of other ones that you could choose from also create a getter and setter for all your schema variables your interface isn't complete until you have a getter and setter for every schema variable also never mark any schema class variables as private because Drupal won't be able to access them and the reason why is that within the base config entity class there is actually a get and a set method which will be able to access all the class variables now if your schema variables are protected those methods will work without a problem if your schema variables are private in your entity class Drupal won't be able to do anything and your entity will be blank every time it tries to save all right we have our flag entity class defined let's plug that into Drupal so we have our class we're gonna hand it over to a on a golden platter to Drupal and then we're ready to go I was like I have brought you this and then Drupal's like what the heck am I supposed to do with that that's just a class I don't know what you're I've got lots of those why do I need another one and of course the flag class is sitting there sad and lonely the problem is that we need another piece of information we need something to tell Drupal what this class actually does we need kind of like a like a a config entity assembly manual for flag when we hand the assembly manual and the class to Drupal Drupal goes oh I get it now and it goes off and build stuff that assembly manual is called an annotation it's metadata contained within the class doc block so that Drupal knows what this class is supposed to do now it kind of looks like this it tells Drupal what the following class is why it's important and where to find the other important pieces of functionality this is what flags annotation looks at looks like at least part of it and you'll notice there's a lot of different stuff in here there's an entity type there's a whole bunch of id and label stuff some handlers some links let's break this down what is all this weird stuff the first thing is that we have this at config entity type at the top this is the annotation type it tells Drupal what follows is a configuration entity it's used for feature discovery after a clash and a cache clear so this actually prevents Drupal from having to execute all of those five times as many files it treats them as a text file and reads the annotation first and then it knows what to actually execute in PHP the next thing is the handler sequence the handler sequence tells Drupal where to find other related pieces of functionality like the list of all of these entities page or other key forms to create edit and delete this entity type all right so we have plugged our entity into Drupal now let's build the administrative interface it looks like this this is the this is the list all entities page for flag it's very rudimentary it's just a series of rows one ad flag button and some operations and some extra text at the bottom how we made this as we create how we derive from how we created a class called flag list controller it derives from a Drupal provided class called config entity list builder and provides the administration flags page it only has two important methods it has build header and build row build header defines the number of the kinds of columns that are in the list table and each row actually lets you populate the content of each row of each row in that table we don't even have to load the entity Drupal gives that to us for free now that we have the list page we need to do the ad and edit flag pages now the way that our ad and edit flag page works as they're kind of similar they're mostly the same other than a few special details so we have a number of form classes we actually have four form classes we have flag form base flag ad form flag edit form and flag delete form now let's ignore flag delete form for the moment and let's look at flag ad and flag edit both of those derive from a base class called flag form base and those derive from a Drupal provided class called entity form flag form base does all the real form stuff it builds the form it handles the validation it handles the submit so why do I have these two other classes then well both of these handle those different details that make one form different from the other when adding versus editing the flag it basically determines where the default values come from either statically or from the existing entity or and also changes the text of the flag submit button that's it that's all that's in there this is actually a very common pattern for creating forms in Drupal 8 you'll see this a lot you'll have a flag form you'll have a form base and then an ad form and then an edit form and we also have a flag delete form now the flag delete form looks like this when you actually access it it has a question it has some text and has either a delete button or a cancel link now that derives from a class called that that actually comes from flag delete form and flag delete form derives from a class called entity confirm form base now entity confirm form base is a Drupal provided class that provides us this quick yes or no form it only has about three methods we need to define that's it and then we have that form completed okay we have our admin interface we have our entity let's make it routable so we have a user they go to uh they go to Drupal 8 and then after that where we need to match all of this to our form classes somewhere in Drupal in previous versions we had hook menu but we don't have hook menu anymore so how do we tell Drupal where to find a route a path and match it to a piece of code to execute well we have a file called flag dot routing dot yaml and flag dot routing dot yaml contains these key pieces of information a route name and the path now we have the annotation as well which tells uh when we have the route when we have the path it matches to their outname and it matches to the annotation and loads the correct form this gets to another point Drupal 8 doesn't think in paths it thinks of route names so we wanted to add you know that add button to our existing path how do we do that you think oh we'll just add that to the routing file right i mean that works the problem is that we can't do that because the routing file only is for new paths you can only define new routes you can't modify existing ones for that we have another file we have flag dot links dot menu dot yaml this allows you to add to existing routes and what this does is this one adds the list page to system admin structure so that we actually when we go to the admin structure page we actually have a link to the flag list we don't define what flag list is because that's already defined within the routing document next we need to connect that add button again we can't add this to the routing file because we can only define new routes we need to add to an existing one so we have another file we have flag dot links dot action dot yaml which allows us to attach click actions to existing routes it has just it's basically a key value store it has the route name and it has which page it appears on so from here dribble can assemble all of this stuff necessary to actually link all the pieces of functionality together the thing is at this point you're like oh geez that's just a lot of code to write i'm gonna be at this forever because it's going to take me months to write all this boilerplate code and it just starts feeling like i've got a bunch of deep hurting and i'm not sure if i'll ever get any of this module stuff working again well i'll be in right now i'm going to show you how to do all of that build all of that in five minutes we have lots of scaffolding and dribble eight that's actually kind of par for course for any object oriented system we have lots of yaml files interfaces base classes base forms it's all necessary stuff and in the end it's actually better practice programming but it's really tedious to write so what are we going to do we're going to reduce our tedium by using dribble console dribble console is another project that will allow us to generate a whole bunch of that scaffolding code with a few clicks and a few key strokes on a command line so here we have the generate module we actually invoke dribble console and we call dribble generate colon module and then interactively we specify all the stuff we want the name of the module where we're going to put it the description the package name if any the core version and a few other things once we're done we can hit enter and boom we have the module structure but that doesn't really do anything yet okay that's fine let's make a config entity because that took a long time to make all the annotations the base classes and all this other stuff well there's also a generate colon entity config command we specify which module we want to do it's tab completed so we don't actually have to type the whole thing in then we enter in the class name for the entity we want to create and anything else and then after that it makes all this stuff for us the schema the routing file all the links file the interface the entity and the form stuff so all of that stuff that we've been talking about all done in that one command you can get dripple console at dripple console dot com or you could go to the dripple console page on dripple dot org all right so we have all of this module done now we need to make the flagging entity we need to complete that picture flagging entity starts out very much similarly to the flag entity we have the flagging class we derive from another base class called content entity base and we create an interface that contracts so we know what the flagging does content entity base is best for user created classes it lives in the database you can't export content entities to yaml they live in the database the fields are defined not with a schema but actually by overloading of a method on your entity class called base field definitions there's no need for hook schema anymore dripple will read base field definitions and make the tables for you beyond that flagging are really really weird they're not created through forms like a node or like a comment it works like this you go have a user they go to the web browser they go to dripple they load a node dripple will call flag entity view hook entity view and then it's going to attach a flag link to that node the user might click that link it goes to some route in dripple somewhere and then to something and then eventually we want to get to entity save so that we can save our new flagging now we could do the something could be a straight function called flag we had that in dripple seven but it's not really a dripple eight way of doing things so what we want to do is we want to do something better so in dripple eight we actually created a new flag service the flag surface is a plain php object but it's registered container wide in a file called flag dot services dot yaml and it allows us to compose other functionality from other modules as well as other pieces in dripple and create our primary storefront for our module this is where the api lives it's in flag service you can create any create a basic structure with dripple console with generate service once we have the service if you ever need to flag anything in dripple eight you actually just call the service from the container so you get the flag service and then you call the flag or unflag methods and that's it all right we want to make this expandable we have a working module but we have a large ecosystem of other modules that we want to have live on in dripple eight so we want to make this entire system expandable now we have the first thing is that we had flag we have the flag entity and we have all these flagable entities we want to relate it to okay well that makes sense we have a node a user and a whole bunch of entities we'll just make a subclass for each one of those i mean that's fine we'll have a flag node a flag user class and then oh right that doesn't quite work because suddenly there's a whole lot more entities in dripple eight than there were in dripple seven there's lots of entities you can practically trip over them in dripple eight and we don't want to recreate handler classes we went down this path before it's hard to expand it's not discoverable and generally no one has created another flag handler class in dripple seven in dripple eight we have to do better than that so what we have instead is instead of creating subclasses we create a flag a flag type plugin and the plugin relates the flag to the flagable the flag type plugin is discoverable using a custom flag type annotation you can create your own annotations in dripple eight and it's added dynamically to the flag entity it's not a subclass now because there's a flag type annotation and also a flag type base class if you want to make your own flag type go right ahead we have given you all of the pieces just define it in your module hit cache clear and it will show up we have a few different a few different flag type of classes we have node flag type user flag type they both arrive from entity flag type a base flag type base so you can even do non entity types if you'd like and they all derive from a dripple prided base class called plugin base so when we have all of this we have a node flag type and we have a user flag type but we still have that problem all those different kinds of entities well we have a special kind of flag type the entity flag type is called a derivative it allows us to use data to create the appearance of one entity type plugin for every entity on the site dynamically so everyone gets their own plugin all the time we also have to handle the problem of the other problem where we have that some route where does that some route come from because if we're going to make it so different for each individual entity type we want to have that kind of versatility as well so we want to salt and close that gap and what we have is another plugin we have a link type plugin now there's actually four link types now this is this screenshot has three there's an ajax one a confirmed form link and a regular normal link so if you want to expand the flag interface grab the link type base create a link type annotation and then you can do whatever you want you can make your own link type very very easily all right we want to create an api as well in flag seven we had hooks hooks were everything we had them to do all this stuff to define flags validate and grant access react to events provide flag types provide link types the thing is it's a lot of stuff in a droop will eat hooks aren't everything so instead it looks a lot more like this when we define flags if you have a default flag that your module provides we actually do that in cmi so you just have a yaml file that contains your flag you can even create it using the gooey in your instance of droopal and then export it and then just copy that into your module file for providing flag types and link types we have plugins we also have events now let's say we have a flag service we have someone we have another thing called an event dispatcher within droopal so we have something happens in flag module we flag something we unflagged something we delete a flag we reset a flag we want to let everyone know that that happened instead of invoking a hook the flag service actually is going to talk to the event dispatcher the event dispatcher is a piece of droopal another component within droopal that a whole bunch of event subscribers have actually listened to and they say i want to listen to this flagging event or these flagging events you can only get the events that you want and then every time that event happens flag service creates a flag event class which contains the information that is related to that event and then gives it to the event dispatcher the event dispatcher then broadcasts it to everyone who's looking for it there are only four events so far actually there's three events i'm really trying to get a patch to get number four in right now just entity if something is flagged unflagged a flag is deleted and if a flag is reset hooks hooks still exist in droopal eight there's actually another class called the module handler interface it provides a method called invoke all that's where module invoke all went off to in droopal eight you want to inject that module handler into your service and it would look kind of like this if you want to implement that in your services constructor you would inject that and then assign it to a local variable a class variable the thing is in flagged service we assumed that it was going to be a necessity that we'd have to use hooks and yet we haven't needed them we have not even needed hooks yet in droopal eight because there are so many different ways that we can do a lot of the things that we did before we might though in the future still use hooks there's still a debate about that all right we have our module let's have a few lessons that i learned while doing this entire porting process over the last two years first of all you want to do this in public but attach a warning label to it when you actually start your project the first thing you might want to ask is where should the code live should it just live on my particular laptop that's not really a good idea you want that module to live somewhere out there so that maybe you can pick up some extra contributors and if godzilla decides to attack your house and step on your laptop then well you might not have any backups of your code anymore then you'll have to start all over again there's three different way and three different places you can usually put it you can put it on droopal.org but is your module really ready to put it on droopal.org that's really public and you might just be starting your project you might be starting with an empty repository you don't know if you're going to get to be finished with it or if you'll have to start all over again okay you can put it in a droopal sandbox but droopal sandboxes have limited visibility they're really hard to find you'd have to do a lot of public PR yourself you might also want to put it in a public repository like github or bit bucket maybe you just need a clean break from droopal to develop your particular droopal eight module for a while until you deem it ready to move it back to droopal.org in flag's case we actually put it on github that's where the module started we kept it there for about a year and a half another thing is that we had to keep up with core keeping up with core over the last two years has been a bit difficult I can go into a long discussion about how difficult that was and the things that I learned and all the techniques I came up with but today none of that is really that relevant what you want to do right now is start with the latest release start with that and stick to it stick with it until you're ready to actually update once you get to a good break and updating your module then move to the next release that was that is out avoid developing against droopal head unless if you want to lose all of your hair because you will lose all of your hair if you try to keep up with droopal head by the time your module is kind of stable you might want to start testing it against head instead because the change is necessary to to keep up with head will be far less than the changes to your module that you want to make in order to complete your module also ask for help but be patient show a lot of appreciation there's lots of places to find help I went to droopal contribute on IRC that's where I found the most help but you can also find a lot of help on the droopal.org list changes page or just the issue key for droopal sometimes money is your problem sometimes you need to ask for funding so you can have travel money to get your team together you might want to attend a conference you might want to just take some time off from work just so you can code in my case I actually needed to run a crowdfund to go to droopal con Austin so that I could get to and get through the last few big hurdles that I was experiencing in the flag project and I actually ran that project and it was successful and we had views support by the end of that week you might want to start wondering when do you want to move your module back to droopal.org if you kept it in a sandbox or if you kept it in a third party repository now there's a lot of things that you might want to think about when doing this issue cue noise you might be rapidly developing your module making a lots of little commits and you really don't care about the commit messages or making issues about it because it doesn't matter because you already know what you're doing and no one else is working on it you might have git log pollution where you have all of this stuff is happening you might on the other side of that you might want to really leverage your community in order to help you work on your module or you really need the visibility so that you can attract developers to your project now you might be tempted to do this the issue cue noise and the git log pollution that stuff is forever it's going to take a lot of mental effort and it's going to live in your repository for a long time and really in that case you'll be you'll think that well I don't think a lot of people are going to be working on this because I'm going to keep this all in my head and it's not it doesn't have to be visible because the module is already pretty popular don't do that you want to do this one thing that we had during running flag modules we kept it on github for far too long it took forever to get it anywhere because it was just me working on it and in the end the issue cue noise we wasn't really a factor we came up with 70 issues by the time we moved it back to triple dot org and all of those were notes saying please do this later also the git log pollution that was a bit more of an issue but in the end it turned out turned out that it was more important to keep all of that history rather than actually throwing it all away and making a big bang squash connect leveraging the community and having visibility is far more energy intensive because it takes a lot more time to raise the awareness you have to go and talk to people get on podcasts do all of this stuff and keep screaming and yelling and talking about your new module in order to get the attention necessary to get one contributor to submit one patch you don't want to do that you get it for free on drupal.org in your existing module project also things are a lot easier now we have example module for drupal 8 we didn't have that when i started we didn't have drupal console either so i had to do a lot of this work myself reading core code which is a bit of an effort by itself just to try to figure out how to make all this stuff you don't have to suffer the way that i suffered there's a lot of ways you could do this now that's a lot easier one night i sat down with drupal console it took me 15 minutes to make 75 percent of the entire module and i had to go have a beer after that port if you're if you're looking at your drupal 8 module you want to port now if you're here to learn if you're to work you'll probably want to wait but don't wait too long we're late in the beta stage that release candidate's going to happen at any time we're at 25 criticals the last time i looked at it and furthermore we have in flag module not have had a module breaking problem for three months that's a long time in git commits so really don't wait too long also do a code review question everything that your module does nothing is sacred question everything so you can really reimagine how your module works please use an ide and a debugger it's going to save you a lot of time in the ad patiently ask for help when you can but show appreciation a lot of the core developers are glad to help but they're really time constrained especially after this long development cycle that we're at things are actually easier now especially since drupal console than it was then where we had to ask people directly for every little thing do your make your module in public but put a warning label on it don't have users go ahead and downloading your module if it's going to break or if it's half done put a warning label on it but don't hide it make sure people see it is money your problem maybe you want to consider crowdfunding also move out of your sandbox quickly don't keep it in the third party repository order drupal.org sandbox for too long and also things are a lot easier now all right i'd like to take a moment to thank all the people who made flag module today possible and also for the reason why i'm here today especially ffw who i work for we're hiring just in case you didn't know again who wants another shirt i've got like three of these and two it's like you raised your hand first and then there was you not so much of an arm okay sure i again i do have some flag module stickers up here two sets of shades i also have stickers for the twin cities drupal camp which is just next month it was mentioned in the keynotes we throw a great camp it's four days long one day of sessions one day of free training two days of sessions one day of sprints it's a beautiful beautiful sunny minneapolis all right come sprint with us today tomorrow right here learn and contribute about drupal core mentors will help you set up and find your issues or maybe you want to work on flag module with me maybe just maybe it'll be right here at the convention center room 403 ab from 9 a.m to 6 p.m all right thanks everyone you can find the slides on github.io and you can find me on twitter and i don't even know how far how much time we have left am i over i think i have like 15 minutes i think anyone have any questions question i think i saw your hand first see now my other wrist is tired from how holding the microphone the entire time um thanks thanks um great i enjoy using flag all the time um did you say we're not manually building install files any longer that schema that a custom table is so we don't really need to define define hook schema anymore when defining a configuration entity or a content entity it does that automatically so it just looks at the either the base field definitions method for content entities or it looks at the configuration schema for config entities and then it will create the tables for you i think it's really cool i saw the there's a form you added that because that was uh bundekraut had done a module for dupal 7 for flags to do a form as the flag in i saw it's in there right you put it in the model yeah there's actually a new um field entry link type and drupal 8 it's one of the big features that i actually added in this release cycle because we've had it for so long but it was only accessible programmatically so it was kind of a mess and now we actually just have a link type so you select it and you can add fields to your flag like any other entity and it will have all the regular form fields and it will be awesome anyone else uh what approach did you take for the tests did you do it as you went along or did you wait until you kind of had a certain chunk finished and what problems did you come up with uh tests there's a story about tests so how it kind of went around is that for about nine to ten months of developing the module we had no tests in it it was just me trying to make a flag and then flagging something and that's because most of the module didn't do any of that stuff and we weren't sure if behat was going to be in core or if we should be using ph php unit or any of those things in the end it came down to it was getting too annoying so i sat down one weekend and learned how to write simple tests because i hadn't done that before and wrote a whole bunch of simple tests at that one time and we're still maintaining them i'd love to rip them all out and replace them with behat tests which was my original vision but that hasn't happened quite yet someday i might do that any other questions yeah this is really a follow-up on that so um i've been i've ported my initial module you know i got a couple of contribs and i've gone through that once like back in october or something like that um so what's really confusing to me is kind of where testing really is at from that perspective in terms of because there's all the what's available in drupal 8 versus what's actually on drupal.org versus you know that kind of stuff so do i hear you saying that behat testing is available in drupal.org or that it it's kind of available we've laid the groundwork and one of the criticals to actually support broader behat testing within drupal.org and on base core drupal but it's not really yet a full behat solution where you can just write gherkin syntax stuff and then turn that over it's not quite at that point yet but i'm really hoping that someday it will be because behat tests are a lot shorter and easier to maintain any other questions okay just i've got two of them you're closer unfortunately so if i understood right uh hooks can be substituted by event subscribers the answer is yes depending on if you're asking krel or not the other co-maintainers are like no you can pull the hooks from my cold dead hands and krel is like why the heck are you still using that events are good the only problem is that that events are not as performant as hooks so if you have a hook that is invoked a lot of times you might want to keep with a hook because it's still faster than an event we're working with that to make events as fast as hooks and then the idea is in drupal 9 we probably won't have hooks anymore it will probably be events and in practice events are actually better because you only subscribe to the ones you need and you can pass a class with any structured information you need with that so that it can take much more complicated data than a massive array of doom and then a few scalar parameters you particularly prefer events so far i have preferred events because they are more the object oriented solution and we we haven't really had any hooks yet in fact i'm trying to get one out of the module right now because flag service doesn't depend on the module handler yet and this one is kind of old leftover 7x code and we're trying to replace that with an event i think that will get in by tomorrow night but we'll find out and i know that you had a question and fortunately you're in an empty row so i can get to you fast i think you answered most of my question i think you pretty much had the similar question but yeah i was going to ask you what was your learning experience on getting away from hooks and how invented you know not to use hooks and do you think it's going to change anytime soon that you would want to go back to hooks because they might improve so to be honest i'm a mutant because i started i have tried writing drupal five six and seven modules for years and the fact is that i never liked them and i came from an academic background where object oriented programming was a lot more common so as a result i'm much more used to objects and all of the weirdness that drupal does in order to work made sense in php4 but in php5 it's like why the heck are we still doing this and i don't really like hooks i find them weird mystical magic metachlorian level stuff and i really don't like them all that much so that kind of the common complaint we have at work everybody hates hooks and we're like why are we still doing this look we have much better ways to use and the other thing is that hooks are really kind of nightmarish for documentation they are horrible horrible horrible horrible for documentation because every time i have to go work on client work in the drupal seven world after working on drupal eight during the evening it's like i can't find anything that works you mean i have to implement three hooks to get this one thing why isn't this an object because i would be done already and it only needs one page on drupal.org to tell me what i'm supposed to do instead i need three different hooks and they're in three different pages and they're not telling me all the stuff i need to do it's a mess objects are a lot easier to actually document they're a language level feature to document so they have language level support so it's actually a lot easier in the end once you get over the intimidation factor and over any knowledge gaps that you might have with object oriented programming even if a performer is better with hooks i i i particularly prefer i would prefer using events yeah this is no this is what i i'm catching that's kind of how i think about it too because i can define an event on the event class and i could send one link to someone saying here's the events after that use the normal event pattern to subscribe to stuff you'll be fine and you can do all the stuff you need it's like what kind of structured data do i need how many of you in this room have had to go where in the array of doom do i have to find the stuff i need that's passed to my hook i hate that but if it's an object it's like oh i just go find the object it's got a name there's the fields there's the methods okay i'm all good i'm all good give me another coffee anyone else all right awesome again i still have i don't have any more t-shirts but i actually still do have two pairs of shades if you want them um and i also have some flag stickers there's only a few of them left don't don't go let me go home with them please i also have a bunch of tc drupal stickers so please go ahead and take them please take take