 All right, I'm gonna get started on time here so that we can keep to our schedule. So welcome, thanks for coming in after the long party last night. I know this is always like the first tough morning of DrupalCon. So you're here, hopefully, for learning about features in Drupal 8. And I'm Mike Potter, and I'm the primary maintainer of the features module and the features override module. The architect of the OpenHRM2 distribution. I'm a software architect at phase two, and if you wanna get ahold of me, there's my email and my Drupal handle as well, and I'll try to get back to you. So we're here to talk about features. Is there anybody here who wants to admit that they don't know what features is or has never used features before? Oh, excellent, because I did mark this as a beginner talk. We're gonna talk about some more intermediate subjects as well, so if you're not a beginner, don't be worried, we're gonna have something for everybody. But I mark this as a beginner talk because I really want everybody who does Drupal to know about features, and that's been true in D7, and it's really gonna be true in D8 as well. But when you hear about features in D8, you sometimes hear things like this. So here's a quote, it says, who has wasted more than 100 hours with the features module? Gone, problem solved. That was a quote from a Drupal core developer about features and configuration management. So anybody have any questions? We're gonna have a very short session today because obviously we don't need features in Drupal 8. So why are we still talking about features? And we're gonna talk about configuration management and all of its wonderful things. But what is, let's go back a step, especially for the people who haven't used features before and briefly talk about what features is and what it does. So when you put together a Drupal site, you have this giant Drupal database. In that database, you put a bunch of different things. You've got your different pages and your different article content, your comments, your users, your blogs, all of the stuff that you would consider the content of your website. That's all stored in the database. But you also have other stuff stored in the database. You have your content types. You have the fields on those content types, not the content of the fields, but the definitions of the fields, whether they're strings or integers or entity references. You also have views. Whenever you make a view in the UI, that gets stored in the database. You have all sorts of site information, your site name, your slogan, all of that stuff gets stored in the database. And we call that configuration or config. So what makes this difficult is, if you're building a site and you have your development environment and you now want to copy your development environment and put it on a production server, you copy this database. Then people start using your production server and they start adding content and they add blogs and they add articles and things. Then you decide that you need to update the configuration of that site. But you can't just take your development environment and put that on production again because you would overwrite all their content. And you can't take the production system and overwrite your development because then you would overwrite all your config. And because they're both stored in the same database, it makes it very difficult. So you need a way to separate config from content. So what Features does, Features takes your configuration and it writes it out to code. And so it converts that configuration data from the database into an actual Drupal module, which is in code. And so now you can take your production database, update the content, move the new code over, the new code is going to overwrite the config piece without overwriting the content. So that's the problem that Features was solving in D7. And why this was a good thing is, well, if you put stuff in code, now you can version control it. So if I'm making a view and I go make a change to that view and I put that in code and use get to update it, and I say, oops, I made a mistake, I need to go back. I can revert to a previous version of that view. If you did that just in the user interface and went, oops, there's no good way in the user interface to restore your previous configuration. So version control is a great thing. And it lets you solve this problem I just talked about of how do you deploy sites from development to stage to prod? And we're not just talking big enterprise sites here, but even smaller sites. You typically don't wanna be making changes directly on the production server. You've always got some local development version on your local machine and you need to deploy that. It was also used to create reusable modules and bundling configuration together. And we're gonna come back to that. That was actually the original purpose of Features. So Features is not configuration management. Features is not CMI. This is the confusing part. Features was originally built to bundle functionality into reusable modules. The example that people often talk about is your typical photo gallery. Let's say I'm building a website and they need a photo gallery on that website. How do you build that in Drupal? Well, first you go and you create a content type for your images that you're gonna put in that photo gallery. You put a field in that content type to store the image so you add an image field. And fields have two parts. Fields have kind of the base part. And then they have an instance and this allows you to have shared fields across multiple content types in Drupal. So you also have to capture that instance. And now that you've got your image content type, you create a view of those images and you make them into a nice pretty grid. You add an image style to resize the image to exactly what you want. And there's a few other little config variables that you stick in there too as well. You wanna take all of that stuff. And so you might spend a few hours in Drupal building all of this stuff. And you do that on your development environment and now how do you move that to your production environment? You bundle it all together and you use features to store that into a module. And so now you have your gallery module. And I can then take that module and I can put it on other websites and have a photo gallery without having to do all that work all over again. So it's great for saving time and development. You can build it once and reuse it forever and still charge the client the same amount of money and make great profits. That is what features was originally written for. It was originally written by a company called Development Seed for the OpenHRM1 distribution on Drupal 6 to bundle the functionality that they needed in that distribution. But because it can write it to code and it can deploy, people started kind of abusing it. So why features was bad? Features was bad because Drupal 7 did not have a consistent way to convert configuration into code. The configuration lives in the database. How do you convert that to code? What file formats do you use? Every module did it its own way. And so people like to blame features for some problems, but really features is just a wrapper around what the other modules are doing. So when you export a view, it's actually views module and C tools that's doing that export. Some things we built into features such as exporting fields and content types because Drupal itself didn't even have a way to export those. So it was very, very inconsistent. And by writing it to code, I mean you're taking data and converting it to code and that just inherently has problems. There's the classic problem in features of numbers that are either represented as a number or as a string with quotes around them. That's a different data type, that's strings versus numbers. But when you write it to code, PHP doesn't particularly care because PHP is not a typed language. So code is just not very good for data. And then there is this problem of, well what if I go and I change my photo gallery on my production site like I go change the title of my view, now it no longer matches what's in that module. So it's called an override or a change. What do you do about that? Who wins? Is it the module that's correct or is it what's on the live database that's correct? Who wins? So overrides are kind of the bane of most people with features and they have features that are permanently overridden that they can't get rid of. But with all that said and people like to hate features including myself sometimes, that's all we had. That's all we had in Drupal 7. And it's a hard problem to solve. There's a lot of complexity involved in dependencies and everything else. But in Drupal 8 we now have CMI and CMI stands for the configuration management initiative. And I wanna say just at the beginning huge thanks to the CMI team and some of them are here today. Greg Dunlap, Hey Rocker was the original lead on this initiative. He's now past it over to Alex at chapter three. But Jen and Dries and WebChick who committed a lot of patches catch and really it's many, many others. You know if you look at the commit history you'll see a bunch of commits from WebChick and Dries but those are on the behalf of a whole bunch of other people who put those issues in the issue queue and wrote patches and tested patches. So it was a very large initiative. I'll still make the claim but I think it was the most successful initiative in Drupal 8. It was started early. It had a very focused purpose and they've delivered on that purpose. So why is it so awesome? So the first reason CMI is so awesome and maybe some of you, how many of you went to Matt Cheney's talk earlier in the week on CMI? So some of you have heard a little bit of this. What CMI lets you do is it first creates a consistent data format for your configuration. And then this is the so-called YAML format or YML. This is a consistent output format for data. It's not just, it's not a Drupalism. It's not a Drupal thing. It's widely used throughout the computer industry, the web industry. And it's just a file format for describing data. And that's what CMI uses for every piece of configuration in Drupal 8. And it provides built-in mechanisms for importing and exporting. So out of the box in Drupal 8, if you go to the CMI screen, you can export your view. You can copy that file over to another site. You can import it. You can export your entire site configuration to a single file, move that file over and import that entire configuration into your production site. So it has built-in, import, and export. And it's doing it through a core service. There's no longer all of these default hooks that features created to try to tap in and do all of this stuff. And finally, it just works. It's really painless and easy. I have run into really no problems at all with it. It does what it's supposed to do and does it very well. So with that said, let's compare features with CMI and D8. So they both export the configuration into code. In the case of D8, we have YAML files. In the case of features, we have PHP code, which allows version control. So we can have version control on both features and CMI, which allows us to do deployment. So we can now import and export configuration, move it to production, and everybody's happy. And we can bundle functionality into reusable pieces, except not with CMI yet. So that's what we're missing right here, is the how do you bundle, how do you make an image gallery in Drupal 8 with CMI? So what CMI would have you do is you would go into the export, and let's say you've got that photo gallery, you would go to your view and you would export that view. You would copy and paste that YAML data and stick it in a module. And then you would go take the content type, and you would copy and paste that YAML file, and you would stick it in your module. And then you would go find the field YAML file, and you would put that in your module, and then you would go find your view and your image style. And is there anything else you need? And how do you know you know what else you need? What else needs to be there for that image gallery to work? Are you kind of an expert enough developer to know that maybe you're missing some variables, or have you gotten both the field instance and the field storage? So it's complicated. Modules in D8 are designed to provide the initial value of config. So when you enable a module in Drupal 8, any YAML files that are part of that module will get loaded into the Drupal site as configuration. And so we call it default config. But what if you want to update that configuration? Right now in D8, the proper way to do that is you write an install hook. And that's perfectly reasonable to do. Like, let's say I've got that photo gallery view and I mistakenly show unpublished content. Oh, that's kind of a security issue. You don't wanna show unpublished content. So you need to add a filter to your view to say only show published images. And so now I wanna deploy a new module that has that new filter in it. What I have to do in that module is write an update hook to say, okay, go into the view, let's load it, let's change it and add this filter, save it back. So you have to write code. There's no way for a site builder to do this. You have to be a developer who knows how to write an update hook. And of course, as with D7, in doing that, what if that site has actually changed that view? What if they've changed the title of that view and in the process of writing your update hook, you overwrite that change and now they're back to the original title and so you've broken their site. And so CRI specifically doesn't do these things because they don't want to break your site. This is something that you have to be very, very careful with. Sometimes uninstalling a module doesn't remove all the configuration. This is kind of up to the module to do its dependencies right, but if you have a module that has a view and you install that module, now you have the view on your site. If you disable the module and the dependencies weren't set right, that view can still exist and now when you try to re-enable the module, it won't let you. So it's good that you don't remove stuff. People in features in D7, they were very perplexed that if you had a feature that, for example, installed a new content type, when you turned off that feature, they were confused because that content type didn't go away. And the reason it didn't go away is because you might have data assigned to that content type and you don't want to lose that data. Now in D8, it's going to try to save you from that by maybe not allowing you to uninstall the module because that might cause the field to get deleted. So you can run into kind of these catch-22s. If you accidentally disable a module, you might not be able to re-enable it. You might not even be able to uninstall the module in the first place. And I apologize for saying disable a module because in D8, of course, you can't disable a module. You can only actually uninstall it. And uninstalling it will have consequences in a lot of cases in terms of removing that configuration. There's some issues out there that talk about this whole, can you enable a module that already has config and so forth? I invite people to go take a look at those issues. So we still need features to bundle functionality. So the key features are features. So features is going to let you import, export and detect changes in your feature module very much like CMI. What we've added that's kind of new is a system called assignment plugins to determine how to package a feature. So in features D7, you go into the features page, you have a blank slate. It does not create features for you. It tells you you have to go create a feature and you check a whole bunch of boxes to decide what goes in the feature. And a lot of people get confused by that. They wonder, you know, how should I build my features? Should I have all my views in one feature? And please don't do that. But what goes into a feature? So in Drupal 8, we have this new system that will actually auto-create features for you based on some rules of configuration that we call assignment plugins. It's a very pluggable system. It uses the Drupal 8 plugin system. Another new feature that we have in D8 is something called bundles and namespaces. So now you can namespace your features in keep and so if you're working on a site, for example, with open atrium, and you have open atrium features, and then of course you have the penoply features, and then you might have your own site-specific features, here you can actually keep those all separate and keep them all namespace so they don't collide, and it makes it a much easier interface. We do have Drush 7 support, and we've brought over all of the Drush commands from D7 into D8. Some are there, kind of deprecated, for people that their fingers are used to typing things and you'll see that in the demo, but we've also renamed a couple of them as well moving forward. It has a modular UI. The feature UI is now a sub-module that you can turn off if you want, if you don't need the UI. And finally, features is more of a development module. When you create a feature in D8, like that image gallery feature, when you move that module to your production site, the production site does not need to have the features module. These are real modules now, not features, not special features. So I have to say, first, this feature in D8 was a collaboration between myself and Nejo Rogers, who couldn't be here, but if you know Nejo, he's a great guy, he's been in Drupal for a long time, writes a lot of modules. When I started working on features a few months ago, I came across this module called Config Packager that Nejo had written, and it basically packaged configuration. I said, gee, this kind of sounds like what features is supposed to do. And so I got together with Nejo, he was very happy to have help, and really what we ended up with is something that was better than what either of us could have done by ourselves. He had great ideas for what features could do. I had ideas from the previous experience with features that I brought in. We put it all together, so what you have now in D8 is actually a better version of features than you have in D7. And this is really exactly how Drupal and contrib are supposed to work along with the fact that you have the core CMI that adds to all of this. So it's a really great open source effort that has produced this. So let's actually take a look at features in D8. If you weren't aware, the features D8 alpha version was actually released last month, so it is not just in dev, it is out there and available for you to start using on your D8 sites. So when you first put together a D8 site, where you find features as you go to the configuration area and then down under development, and then you go into the configuration management. So features is kind of part of the CMI interface in Drupal 8. And that will refresh the screen to get rid of the mobile glitch there. And now you'll see features is a new tab. So here's the normal CMI. You've got the CMI single important export. This is where you can import and export like a single view. And then you've got your full import export. This is where you can export your entire site configuration and import it. And then the features tab is there as the second tab. When you go to that on a blank site, you'll already see four possible things that you can export. The first two are based on the content types that come with Drupal. So you have an article content type and a page content type. And then there's some kind of generic core stuff and then some unpackaged. If you expand the little description area, you'll see the exact components that could potentially be exported to that feature. But you'll notice that the status over there on the right says that it's not exported. So unlike in seven, D8 has this concept of a feature which has not yet been written to disk or is not yet in code. They are basically taking your whole site configuration and kind of breaking it up into pieces and suggesting that maybe you export these different pieces. As you'll see later using the plugin system, you can change how these things are presented. So this is a content type based export. So article and page are your content types. If you want, you can go in and configure it and say, hey, show me my configuration by view. And in that case, it would show you every one of your views as potential features and all of the dependencies with each view would be included with those features. And these are called the assignment plugins that you'll see a little bit in more detail a little bit later. And just keep in mind because those are plugins, if you want, you can write your own assignment plugins and completely change how features packages these bundles of a configuration. So let's see it actually in operation. Let's go and create that gallery, okay? So here is our D7 site and we're going to go build a photo gallery. So we make a content type. We go at the image fields with content type. Now we go add a image style for that content type for our gallery. Now we'll go add a view. We're going to make a grid view that displays our content type, our email style, our views done. Now we need some content. So let's go add some images. And you know me, gotta have some cat images. It wouldn't be for the presentation without cats. So I've got my cats. We're going to add them all to our new image content type that we're building. It's our photo gallery. All right, so now that we've built that, we don't want to have to do that again. We want to create that. We want to put that into a feature. Okay, so how do we take this and put it into a feature? So we're going to go back to the features page. So as I said, we're going to go to development and configuration management. And we'll go to the feature tab. And what you'll see is there is now a new suggested feature called My Image. That was automatically detected for us. If I click on it, it will show us over on the right the same interface you're used to in Drupal 7. With the blue stuff is the auto detected configuration that it's suggesting that we export. So we've got our views and our fields and our content type. Now in this particular version, there are a few little bugs and dependencies. It did not find the field storage. So we go and we add the field storage for the image node. And it didn't find our image style. So we go and then we add the image style. And the interface works as you see, just like in Drupal 7, as you check the boxes, they go down below. We'll give it a name and a description. And down at the bottom, you'll see the two different ways we can export this. We can write it directly to disk or we can download it as a tarball archive. Those are actually generator plugins. So if you want to write your own generator that does things differently, you can write a new plugin and it will show up down there as a new button. So now that we've written it to disk, you can see that it's uninstalled, but they're listed as a new feature and you can see it's kind of separated from the ones that are not actually exported. Now to enable the module, you no longer do that from the features screen. This is a real module. So you go to the extend page, which is the new modules page in D8 and you go find your module and you enable it and you save it. So that is going to turn on the module. Now you'll notice that this has allowed us to turn on a module that contains the same configuration that we just got through building on the site. So we already had a gallery view. We already had a image field. We already had that on the site and now you can see that the feature is enabled. The features is doing some tricks with CMI to allow you to enable a module that actually has the same configuration that already exists on your site. Normally Drupal is not gonna allow you to do that. So now that we have this feature module, we can now move it to another site. Now this may be small for people in the back and I do apologize for that. I'll try to kind of describe what's going on here. But in the version, this is all by the way based on the beta nine version of Drupal 8. I haven't actually updated it for beta 10 yet. I think it works okay, but I haven't actually checked. In beta nine, there was not yet away from the modules page or the extends page to install a new module from a tarball file. So in the actual release of Drupal 8, you'll be able to take your tarball archive and just upload it directly on the modules page and enable it. But here that wasn't working yet. So I actually had to go to the command line and copy it over here. So here we are on the Drupal route. We're gonna go down into the modules directory of Drupal, which is empty. We're gonna copy our tarball archive for my image over to this directory and we're going to expand that archive out so we get all the module files for my image. And now we can go to the modules page or the extend page and now we can turn this on. Now, this is a new Drupal 8 site. If I look for the features module, it does not exist on this site. This is a plain Drupal 8. There's no features on this site, but I can now go enable my image module and click save and Drupal is going to go enable all of this for us. And if we now go up to our site, we can now start creating content. So we now have a new content type when we go to add content called my image. And once again, we can add more cat pictures and we're only gonna do two of them this time and we're not gonna use any fancy music. We'll just stick two images in here. So now we've got two images and now we can go to our gallery tab and there is our gallery on this brand new site. So it works just like it should. All right, so what about changes? So we don't use the word override anymore in Drupal 8 because people hate that word. We now call them changes. So let's take this, so now we're back on our original D8 site that has the three pictures on it. Let's say that the client isn't happy with the name of this gallery. So we're gonna use the inline editing in Drupal 8. We're gonna go up here and click this button and say edit the view and we're gonna change the title and then we're gonna call it my cat gallery. So now we have a new version of this view on the site and it's different than what we exported to code. So when we go to our features page, we're just gonna go back and refresh the page here. You'll see over on the right hand side it's now says that it's changed. There's that little orange marker that says changed. If you expand the details, you can actually see that it detects. It's the view that has changed. And if you click on the changes, it will show you the changes. And it shows you that in the active site configuration, it's called my cat gallery. But in code, it's just called my gallery. And so they're different. In this case, I'm going to select this and I'm gonna say import the changes. Import means I'm importing the code back into the database. So now this is equivalent to doing a revert in D7. I just reverted this feature and we're now back to the original my gallery. So we imported the code into the database. So in D8, we talk about importing and exporting. So let's go change it back again. It's like, no really, I want this to be called my cat gallery. Darn it, don't override my feature. So in this case, what we wanna do is go back to the features page and instead of importing, we want to export. So we can just click it, say write, that exports the database to the code. Now we just updated the feature and it's now my cat gallery. If I go look at the code for this, for people that are geeks and wanna look at the code, in the feature module, we have a config directory. And if we go to the view YAML file and scroll down and find the title, you can see that the title in the code is now, in fact, my cat gallery. Now, is it gonna keep going? Okay, good, it stops there. So what I also wanted to highlight here is this kind of shows you what a feature module looks like now in D8. So a feature module consists of a config directory with an install directory underneath that and a whole bunch of YAML files. Those are the YAML files that are imported into the database when you enable the module. There is no .module file. You'll see that there is a .info.yaml at the top level for the module. In D8, you don't need module files anymore. All you need is the overall top level YAML file that describes the module, which is kind of like the info file that we had in D7, except of course it's in YAML format because that's the format that D8 is going to use for everything. And we'll see more about that YAML file in the future. But like with D7, you're free to add other stuff to this module. You can create your .module file, you can start adding your own services and everything else if you want to flesh this out and have more than just config in your module. So let's look at something new. Let's look at bundles. So bundles in features are just a way to group your configuration or group your features. So you see there's this little bundle dropdown. It currently says none. If I go to configure bundles, I have a way to create a new bundle. And this is what is listing all of the different assignment plugins. I'm gonna try to pause the demo here so I can talk about this a little bit more. These are all of those plugin assignment methods that I referred to. They have a specific order. They get run in order. So for example, the first one says, please detect any existing feature modules and bring those in as packages. And assign configuration on the site to those modules. So this is where it's looking at the YAML files in your module and making sure that anything that you have exported is still connected together. We then exclude some configuration that you don't wanna see. And you'll notice that that third one has a configure button way over on the right hand side which you can click to determine what stuff do you want to exclude. You know, people have always had this need in D8 to say, you know, I just never care about menu links because menu links are content, not features. Can you just hide that? Because I've got 500 menus on my site and that just makes features really slow to have to load that all the time. Here you could just go and you could say, hey, just exclude that. I never wanna see that configuration. I never wanna put it in the feature. The fourth one called profile brings stuff into your feature that would allow you to write that as an actual install profile. So Nejo has put in a lot of work to really integrate features with building install profiles. So if you don't like to have your configuration in modules and you actually wanna put them in install profiles, you can now do that very easily. Base type is actually one of the really cool ones and we're gonna expand that one in a minute so I'll come back to it. That's the one that determines whether or not you're doing it based on content type, review, core type determines what goes into that core package that I showed you. And then finally the namespace one implements the bundles and the namespacing and then the last one dependencies. That's the one that will auto-detect stuff in blue. So if you don't like features, auto-detecting things for you, you just come into here and turn off the dependency plugin. You don't have to do anything else. So now whoops, I knew I would do that. Stupid thing. Yes, you can't hit space to pause videos in keynote. You have to use a special magic key called K because that's really obvious. So we're back here. So what I'm gonna do here is we're going to go show you the configuration page on this base type because that's probably the one that you'll be most interested in changing sometimes just so you can see all the things that you can base your features on. So you'll see we've got content type checked. You can actually check more than one item. You could check views but those are all the different things that you can base your features around. Now here I'm gonna create a new bundle. So let's say I wanna start creating a bunch of open atrium features in D8. So I'm gonna create a bundle called open atrium and I'm gonna give it a machine name. This machine name is gonna prefix all of our modules, all of our features modules. So we're gonna put in OA as the prefix and we're gonna give it a little description and we're gonna go down and hit save. So we've now created a new bundle. If we go now to our features page, we'll see that we're now looking at the atrium bundle and there's no features listed there. We can go back to none and we can see we're back to all of our features. So none displays everything. Let's go now move my images into OA into the atrium bundle. So you go click on the feature and you see there's a bundle drop down where you're gonna select open atrium and it tells you that okay it's gonna prefix your module with OA underscore automatically. So you don't have to worry about name spaces, that's all done for you. We go ahead and write this to disk and now we've just created a new module called OA underscore my image. Now yes, it just let us write that same configuration to a new module. We now have two duplicate features on our site and you'll see they're marked as a conflict and so we need to remove that first one so that we're only left with our OA. The way you remove things is you can do a bunch of different things, you can uninstall the module, I'm just gonna go in, I'm just gonna remove the files because they're actually features thinks they're the same thing. It still thinks it's the my image feature because of that namespace. So all we have to do is delete the old one, refresh the page and now we've got our atrium one and so now if we go into the atrium bundle we will see that single feature. So it remembers this in your session so if you're a developer and you're only working on the open atrium features of your project, you'll live on this page, you won't see any of the other developer features. Some other developer might be working on the Panoply features, they'll use the Panoply namespace and all of your work is nicely isolated so that you're not messing each other up. So that's bundles and you'll notice it allows you to very easily now copy features and clone features and rename features using this bundle. So what makes a module a feature? How does features know that my image is a module and how do you remove something as being a feature? What if I don't want features to manage this anymore? So here we're gonna go to our image and we're gonna go take a look at the code again. We're gonna take a look at the files and I mentioned the YAML file. If you look in the YAML file, there's this features tag. We can just remove that features key and then refresh the site and now our feature is gone. So now it's just a regular old module. It's not a feature. If we wanna put it back, we just go and we can just say features true and that's enough to get it auto-detected. So now features true, we refresh the page, now it's back again. Because it's namespaced OA underscore something, it actually already knows that it's in the open atrium namespace automatically. But to be nice, the way to really do it is to instead of just saying features true is to under the features key, give it a bundle key and tell it that it's in the OA bundle. But that's also how you can change what bundle of feature is in as well if you want to. So that's bundles, something people have actually asked for in D7 for a long time. There was a real pain to do in D7. So how about drush support? This is gonna be another one of those that you probably won't be able to see in the back so I apologize. But all your drush commands are there. So we've got drush FL is your feature list. Now here I've actually changed that view again. I've called it my cat gallery versus my gallery so you'll notice it's marked as changed. If I do an FL directly on that feature name, it will show me all the config files that are stored in there. If I do FD for feature difference on that, it will actually tell me what the difference is. Same format you're used to in D7 with the red and the green. If I now do a feature import so the new command FIM, that's feature import, that is going to import the code into the database. If you want to export the database back to code, that's feature export or FEX, effects. But for those people that just, oh and then there's, yeah so feature difference. So if you want to take this difference, we still do support the drush FR for feature revert is still there. And of course people just love drush FU so we had to keep it around. And yes, drush FU all does still exist as well. There is also the drush FC command for feature component. This shows you a list of things, a list of different things. So here I showed a list of views and I can use the FA command, the feature add command to add something new to my feature. So here I'm adding the who's online view to my image gallery. And now I list it and you can see that the view is now shown there. If I now come over to my disk, I can see that there's a new YAML file which is the who's online file. I can just delete this from my disk. It's just a file. So now it's no longer in my feature and if I do a drush FL, it's now gone from my feature. So YAML files are cool, but you don't have this problem where you have to go edit your .info file because that's where features keeps all of its stuff. There is nothing in the .info file other than a simple feature tag that says hey, this module's feature, everything else is in the YAML files just like it should be with CMI. So what is features doing that's still bad or kind of bad? How does features kind of violate some of this core CMI rules? So the first one that you saw is that a module can be marked as a feature and can be enabled on your site even if it contains configuration that already exists on the site. So we saw that when we first exported the gallery, right? We had just created the gallery. So we had a new gallery view. We exported that to a feature module and then we enabled that module even though that module contained that same view and Drupal doesn't normally let you do that, but it's really necessary from a developer experience when you're creating your features, you wanna be able to enable these things and play with them on your development box. So we actually overrode the config installer in CMI to allow this to be done if a module is marked as a feature. You can't just do it with any module, you can only do it with a module that's marked as a feature. Which of course, by the way, means if you do have a module that's not a feature and you're a developer and you just really want to install it and it was not letting you, you go into the ML file, you say feature true, now you can install it and now you go delete that and you're back again. Tricks. The other thing you saw us do that was kind of nasty is it allows you to have duplicate configuration across multiple modules. You saw that when we used the namespace to make a clone and when we had a conflict between those two features, we had two features on our site or two modules on our site that had the same configuration. Again, we allow that. It's a temporary thing that you can be doing on development while you're refactoring code, like let's say you're moving a module from Panopoli into OpenHRM or vice versa, you need to copy it. It's something that we want to allow developers to do as a good developer experience but it's not something that you really want to do a long term and that's why it gets marked as a conflict. And of course, it still allows you to import config into your live site. And this is something that we really try to avoid in CMI in general. We really treat the site configuration as gospel. We don't want modules messing with your site configuration because we don't want your site to break. Just because I decided to update an OpenHRM module and I push it to your site and you turn it on, you don't necessarily want all your stuff to change. But with features, sometimes you do and so that's why it's allowed. Sometimes you do want to allow the feature to update itself, in which case you will, just like in D7, lose any changes that you've made when you revert or import that feature. Which leads us to the question of overrides and I'm not gonna really dwell on this very much, but overrides are still an issue. It's something that we've got a lot of thought going on around how we can really improve this. So overrides, again, this is the situation you have of I've changed the title of my view to my cat gallery. The person who wrote that module gives me a new filter on the view or a new field on the view. How do you merge those two changes together? You really want both, right? You want your title plus the changes because that's a security issue. And in the past, it was either or. You could accept the entire module or you could accept the entire site config and you couldn't merge them together. Now in D7, I wrote the features override module to attempt this and it works most of the time with some of the more well-behaved modules like C tools and views and things. Works poorly with some modules that still require array orders and things. And so you have overrides like that. We don't have the equivalent of that in D8 yet and we're still trying to think about what the best way to handle this in D8 is. It is gonna be a submodule in features that you can turn on. And as I said, what we're gonna try to do is provide a way to merge partial YAML files together so you can have the best of both worlds and control that from a code and site builder point of view. So the future. So summarizing features. Features is used to bundle functionality. It's not configuration management anymore and this is a good thing. Features in D8 is a developers module. You do not need it on production. It's intended to be used for people creating feature modules. You don't need it to use a feature module because a feature module is just a normal everyday Drupal module. It has some new functionality. It has bundling, it has auto packaging and assignment plugins and lots of cool stuff. And like CMI, it actually now just works. So that's Features. But I wanted to end with a couple other thoughts because this was a very interesting project for me personally. This was my first look into D8 and I did this in the month of March. Phase two was very generous. They supported me for a whole month away from Open Atrium and away from clients and all that stuff. They let me spend a whole month on doing features for D8 specifically for Drupal Con this year. And I was the one that told Frank, yeah, I think I could do it in a month when he asked me, so how long do you need? And at the time I had not done anything with D8. So the first week I started learning D8, I watched a bunch of videos. If you're a developer in the room and you're just starting with D8 and you didn't go to Larry Garfield's talk earlier in the week on Drupal 8, go find that video and watch it. I think it's one of the best overviews of Drupal 8 that's out there right now. It's certainly helped me an awful lot. What I found was that Drupal 8 was actually a heck of a lot of fun. Now I do have a background and kind of object-oriented programming and model view controller kinds of frameworks. I used to do code igniter stuff before Drupal. And so this was kind of refreshing to kind of go back to the old days where things just work the way you kind of want them to. But it was actually a very interesting experience. When I first installed Drupal 8 the first week and I brought up the site, I was like, wow, this looks like Drupal. It actually looks like Drupal. It's got views, it has content types, it has taxonomies. I'm like, did they really do much? Like, what's been taking them so long? This looks just like Drupal. And then I went and I looked at the code and I went, holy crap, this is all different. It's a minor miracle how much they changed behind the scenes and still ended up with something that we would call Drupal and that we would recognize as Drupal. And so again, hats off to the core developers on that. There is a learning curve. If you haven't done object-oriented programming before, this will take a little getting used to. But this is a good thing. You're a developer, you're supposed to grow your skills. You want to get bigger, better jobs in the future and get more money. Like, this is good stuff to learn. So learn object-oriented, learn MVC frameworks and learn about some of the stuff in Drupal like services and things. It's good for you. So it only took a month. So my original session submission for DrupalCon was I will show you a dev version of features. And my vision was, yeah, I'll probably show you some Drush commands and we'll talk about how hard D8 is and all this kind of stuff. And what I ended up in a month is a full version of features with new functionality. So it really was rather amazing how easy it was to take a module as complicated as features and port it from D7 to D8. So was this really a port? What actually got involved? Here's some fun statistics, because people ask me these questions having had this experience with a real complicated module. How does the D7 version compare to D8? And you probably can't read all the stuff on the graph there. But the little bar chart at the top, the blue is Drupal8 and the red is Drupal7. So Drupal7, of course, has this big old spike on the right, which is called CMI. Because in Drupal7, features had to do CMI. And in Drupal8, we don't and so there's nothing in blue. If you look at other things, scaffolding is what I call things like interface files, YAML files in D7, those are your info files, your API.php files. It's just kind of the extra stuff that you need around your modules. And people think that D8 is really bloated with all this extra object-oriented stuff. It really actually wasn't bad at all. I'd add it a little bit, but not very much. The base functionality in terms of I wanna create a package or something like a package was pretty much the same amount of lines of code. The UI was actually about the same amount because actually I was able to use most of the UI from Drupal7. CSS went down a little bit because we were able to get rid of all the crap from D6 that was still cluttering things up. The JavaScript came over almost without change. So it's about the same. Drush commands came over almost exactly the same. Drush is very, very similar, which is actually disconcerting. Once you start playing with Drupal8, you kinda want Drush to be a little different because it's not object-oriented and you don't have classes and class variables and things like you do in D8. And then what we added to Drupal8 in blue were the plugin system and the plugin UI for doing the assignment plugins and bundles and those kinds of things. So overall, the result was it was about the same number of lines of code. All of that CMI stuff I took out, I put back with new features or new functionality. So the overall module ended up being about the same weight. It was not hugely bigger or anything like that. But it also wasn't tiny. And that little pie chart down below shows some of the breakdown of where the code came from. So in blue, that's the code that came from Nejo's config-packager. Now it had to be refactored. We had to rename everything from config-packager to features and do a bunch of stuff like that that took a little while. But that's kind of a third of features is what was in config-packager. In red, that's the code I was able to bring over from D7 without change. The form API hasn't changed. So all that nice user interface, you'll be like, wow, you've got the same user interface. Yeah, that's because I just copy and pasted it into D8. Now you do have to change some things. I mean, form state is an object now, which is actually nice. So you do have to do a little bit of refactoring. You're not gonna find kind of a one-click convert my form into D8 helper module probably. But once you get used to the ideas, it's actually not that bad. In the kind of greenish color, that's the brand new code for doing things like bundles. And then the purple code is the kind of new code that was written for core features to do the packaging and stuff like that. So again, people are just kind of interested in how that broke down. So if you wanna get involved, right now, as I said, we have alpha one available. Like I say, alpha one is for beta nine. So you might wanna wait till I get back for vacation in a couple of weeks, and I'll have an alpha two that is for beta 10, or maybe beta 11 will be ready by then, we'll see. So I'll try to keep up with the beta versions as we go through the summer. Take a look at the code. Go install it on your, if you're playing with Drupalite, go install it and play with it. See if it does what you need it to do. See if you find any bugs or crashes or problems and put suggestions in the issue queue. I would love to hear from people on that. And help write tests. I will not create a beta version of features until we have full test coverage. And there's already actually been a start. And thanks, Jonathan, if you're out there somewhere for starting that issue. So we have a few tests that I will get into the next version, but that's a great place. Actually, when I talked to Jonathan, he said it was a great way for him to learn how features worked was by writing tests for it, because that got him into the guts of it. And finally, now we can finally stop hitting features and start loving Drupalite. So thanks, and I'll take any questions. So there's a mic in the aisle, so please go up to the mic since we're recording this, we wanna get your questions, but go ahead. Oh, is it on? Still not on. Did it right, did it right? Okay, I already have you guys left. I'll repeat the questions. Yeah, so the question is if features isn't used in production, but I make a change in production and now I wanna synchronize with the feature, how do I do that without the features module? So the answer is you don't do that on production. You do that on your staging server where you have features, and then you use CMI to export your new configuration to production. Obviously, if you really want to do it and you really have to do it, you could obviously turn on features on that. We actually are, for the reverting, we're using another contrib module called configupdater that Jen Hodgins wrote, and you can use the Drush commands from her module actually to import your changes as well if you just wanna take the code and put it in the database. But no, I encourage people to do it on their QA server and not on their production server. Yep. Yeah, so the question is if you do have conflicting config or you have config in your feature that exists already on the site with features on your dev server that works, but then on production, how do you enable that module because it's gonna conflict. Is that right? Because it exists. Yeah, and so again, the way you need to do that is, well, again, kind of almost back to the old answer of do that merging on your staging or QA and then push. Or what you would do is actually go on your production and you'd have to delete it first. If you don't wanna install features, you would have to delete that existing configuration first and install it. So like if it's a view, delete the view. Now, once we get this, in Alex and I were talking about this a day or so ago, once we get the dependency stuff working well on this, you actually may be in situations where you can't uninstall modules that have that preexisting configuration. So how did that configuration get there in the first place? I guess is how I would ask it, right? It had to get there somehow. Did it come from a module in which case it was already a feature and why is it different on production than your QA and why can't you just use CMI to deploy it? So yeah, so the question is when you're using bundles and copying features into different bundles, what happens when you have existing content that's already part of that? So what's changing is it's the namespace of the module. The actual configuration is not namespaced, okay, right? So your existing configuration is actually the same and that's actually why I got away with just removing that old module and having the new one worked. They have the same exact YAML files within the module. So like a view, the view itself wasn't namespaced. Just the module containing the view was namespaced. So yeah, so the question is wouldn't you want a namespace that comes as well? I think yes, there are use cases for that but I think those are kind of outside the realms of features at this point in terms of namespacing configuration because literally you would need to create like if you wanted two different views with two different names, you would do that through cloning the view or something like that or copying that YAML file, giving it another name. And so you can actually already do that through just kind of YAML file manipulation. Making that easier is probably another good place for contrib to do something. So next. Okay, so the question is can I repeat what I mentioned about merging that it might be a submodule? So yeah, as I said, we're still trying to decide the right way of merging and how you would do that. It's for people that actually wanna talk about this later in terms of throwing an idea out there. And again, this is something I talked with Alex about. One of the things I'm thinking about is you normally are supposed to update this stuff through update hooks, right? And update hooks have a number, like if you're a developer you've seen like hook 7100 and when you run update.php it goes and runs that particular update hook. And that allows Drupal to run these things in order. So what we're considering is creating a directory within your configuration that's numbered by the update hook. So you have a subdirectory called 7100 and in that subdirectory you have partial YAML files that have just the title change or just the field change and that a new submodule like a feature override module would hook into the update hook system and kind of write the update hook for you and what the update hook would do is go look in that directory for the partial, take the current, do a merge operation. And so it would kind of do what you would do in code normally without having you having to write that code. That's kind of the current idea. Nejo doesn't actually like that idea so I need to talk to him about his ideas and that's why we haven't done anything yet but we need to do some kind of YAML merging there as part of the update process or we're through a drush command or something like that. Next. So the question is in D7 there were alter hooks and that made it very easy to override small bits of things like a part of a view or something like that and basically what's happened to that in Drupal 8? Can we still do that and so on? Part of that I don't actually know if the alter hooks might still exist. It's kind of up to the modules themselves. It kind of, in CMI, the very strong opinion and result was that we don't want alter hooks. That when you go look at your view in the views UI you're seeing your view as it is and there's no magic going on behind the scenes where some module is altering it at runtime only so that it changes like there was specific work done to actually kind of stop that kind of stuff because it makes supporting sites actually very difficult and there's better mechanisms for doing that but I can't actually say for sure that some modules don't still have alter hooks to let you do that kind of thing. Yeah, in views, that was a bad example. In views it would but there were some other things that you could override variables and things and not necessarily see the right one in the UI and stuff like that. So again, we're trying not to do that, trying to provide actually cleaner mechanisms to do that so that it's better. Is that fair Alex? Yeah. So Alex's response for people that couldn't hear it was that when you do it with an alter hook and you then go save your configuration you've now saved that in the database and now that's the live configuration so now there's no longer an alter or an override and that because in D8 your site is your configuration you shouldn't need to do it with an alter hook you just go directly change it on the site and instead of altering it just make it what that site needs because that is the site configuration. Next question. So a very long question. So I'm kind of gonna summarize you have a module with a lot of code and some configuration but the module is designed to allow users to add fields and add things to it. So right now the module just provides the starting point, right? The basic structure of the fields and then on any given site you're gonna have new things added to it, right? So currently you're doing that through features and you revert the feature and because features is not going to care about any other fields that works perfectly fine. That same is true in D8. Every field is a separate YAML file so when your module creates new fields it's creating these, when you export your configuration it's creating these new YAML files and those aren't part of your module because your module's just providing the default config so there is no conflict there it's really gonna work just like you're used to in D7 now. Correct. Yeah, great question. So the question is I have a whole bunch of features in D7. What's the upgrade path to convert those into D8? I've thought about this actually. There may end up being something as a helper because if you look at the YAML files they really have a pretty direct correspondence to things in D7. Like I think I can imagine some basic mappings. I can see where fields go. I can see where views go and things like that. Obviously the actual export structure has changed like even if you look at a view in D8 it has some similar qualities to the export in D7 but views has changed and there's some new fields and new properties and things so there's really no way to take that exported array from D7 and somehow auto generate a YAML file. What's best to do I think is actually rely on the module update paths themselves and I mean upgrade paths is still a question for all of D8 but it's still up to the module. So for example, views may already, may not, I don't know, have some kind of upgrade path? No, okay. The idea would be if you can get that, perform the update on your site so that in the database it's updated the view to its new format and then re-export it with CMI now you'll have the new export of that. So rather than trying to convert the code export of features to a YAML export you kind of load it into your site, let the site do the update and then export it back out again would kind of be what I would say but I think what features can help with is at least give you a helper to say hey, you're exporting these things in D7, you should export these things in D8 and since the interface is pretty much the same it's probably not even that bad of a thing to go and just check the boxes again if you absolutely had to to re-export it. Probably wouldn't take that long but yeah, there's not gonna be a magic and that's true with a lot of arrays in D8, there's not gonna be a lot of magic upgrade or updating going on. I don't think it should be part of CMI, I think they split that really just right in D8. They provided the pieces that should have been in core all along are in core now but I don't think, I think the direction CMI has made in terms of its opinions about site configuration is actually what you want and in terms of packaging that's more of an extra developer experience that should be supported separately. So I am actually not sure I would make much change there. There may be some little things like it'd be nice to have some API functions to do some of the stuff that config updater's doing or some things like that but those are all pretty minor so I don't think I would change too much of that split and I don't think I would move stuff more into core. In terms of the future direction of features I haven't thought about that too much, I mean it's doing its job now so I'm not like somebody who just wants to add something for the sake of adding it, it seems to be doing its job, I think there's been some things still in D7 to help with the UI and stuff that maybe get some tweaks but I don't think you're gonna see any major revolutionary thing. Unless somebody in the community or like Nejo did with his assignment plugins which was a new idea to me, if somebody comes up with that then sure. Yeah, so the question is what about strong arm in D7 that was used for doing variables and configuration variables? So that's actually part of CMI now. CMI has two different types of configuration, there's something called simple config and then there's entity config. The simple config is basically the variable system so it replaces the whole variable get variable set with variables in YAML files. In features, even though your variables, and I'm trying to figure out the best way to explain this, your variables are stored in a single YAML file, like it doesn't make a file per variable like that would be crazy, right? So they are all in one file and yet features in CMI does consider them separate things so you can import and export individual variables even though they are kind of collected in one file and so that does kind of make variables a special case versus everything else which is more of an entity config kind of thing. So yeah, strong arm is gone, it's not needed anymore, it doesn't have to be special.