 OK, guys, well, without further ado, you guys have found yourself at a managing code and configuration with update functions and staying sane. I think I hold the title of the longest talk title at the conference, so it's one on my belt. I'm Lindsay Gaines. I work for Monkey in Melbourne. We're a small web agency that does pretty much anything digital, and we build a lot of sites in Drupal. So yeah, I thought I would give a talk about some of the processes that we use to kind of keep our sanity when working in Drupal sites where there might be a few different deployments. This talk is targeted at developers, probably people who are at the beginning end of the Drupal spectrum, just getting started writing things like custom modules and starting to put custom sites together for your clients, also at site builders who want to kind of make that transition. I might just close this. All right, so hopefully some of you guys have at least written a custom module for Drupal 7. Maybe you've worked on a site that has multiple deployments. So by multiple deployments, I mean even things like your dev copy, the staging copy where you test or do QA with your client, and finally the live or the production environment. Maybe some of you guys have seen install profiles. At a minimum, you've probably run the minimal one when you were setting up a new site. So a lot of times when we're working with Drupal, we run into a problem to do with configuration. You need to go through a bunch of different interfaces and click a bunch of stuff, type in a few new values when you're developing a new feature or maybe trying to change something about the way that the site works. Whenever you encounter a situation like that in Drupal, it could be a bit time consuming to go through all of that stuff. And it's not just on your dev copy that you have to do it. When you get your feature ready and you roll it out to staging, you've got to go through the same process and set up those same configuration variables. And then finally, the nerve-wracking one is when you want to deploy your feature to live. Having to go through and click through all of that stuff just after you've deployed your code. I think anyone who's gone through that process can find it a little bit nerve-wracking because you've got to get it right on live. And also, that's a lot of clicking around and manual processes that in the modern age, hopefully, we can automate some of that stuff. So the risks of working like that, of having to go through and manually update those kind of settings. First of all, the settings and the configuration that you're working with, they don't live with the code. When I say live with the code, I mean, the stuff that you're developing, hopefully it's going into version control. So your new feature has been committed. If there's a setting that's relevant to that new feature that it depends on, ideally we'd like for that setting to live with the code of the feature in version control. Because that means that future deployments like won't miss out on it. Sometimes you'll be developing a feature branch in parallel to another developer and you wanna make sure that those feature branches get the benefit of those configuration updates. If you don't keep those kind of configuration changes in the code, you won't be able to do things like automated testing. This is, what I'm gonna go through today is kind of one of the core building blocks that you need to start using. If you're gonna start using things like simple tests. Did anyone here go to the simple test talk earlier today? Yeah, I went as well. I thought it was really interesting. That's something that we've only just started delving a bit deeper into at Monkey. So yeah, hopefully what you learn here in this talk will help you get there as well. Of course, the most dire risk of working by doing all of your configuration manually is that you forget to update a deployment. Staging sites are often the ones that miss out. All of a sudden, something doesn't work properly and people don't really know why and the client gets stressed. That's never a good situation. The other thing that happens all the time, Alice is working with Bob. Alice updates the configuration on her dev site because of a new feature that she's built. She commits the code, but she forgets to tell Bob to make that same configuration change on his site. Bob might be in a situation where his dev copies some feature that he's working on just completely stops working. He has no idea why. This is Bob. Why isn't it working? It was working a second ago. Bob is getting very agitated. Okay guys, Bob lost his job after this and it was all because he didn't get the memo about updating his deployment. So how do we solve this problem? What's the tool that Drupal provides to us? The tool is the update function or hook update n in the documentation. It's a function that lives in the install file of your module. Basically you can use hook update n for any configuration or setting that lives in a database. All Drupal devs have probably run updates before when you've updated a contributed module. You can, there's a couple ways to do it. You can go to update.php on your Drupal install or if you use drush, you can use drush update db. The configuration, if you're using, if you're putting your configuration in an update function, it means that it lives with the code inversion control. So the same commits that have your new feature, they will also have the updated configurations inversion control. And that means that all the deployments that get updated, they all get your new configurations. Running the update is almost instantaneous. It's really quick, so you won't be clicking around everywhere and you also kind of don't have that anxiousness when you're rolling out to the live server because you just click it and it goes bang within a few seconds after updating the code, your site now has its new configuration as well. An added benefit is that your mouse won't be destroyed because you're absolutely clicking the hell out of it, trying to get your configuration up there. And of course Bob keeps his job. So update functions. They live in a modules install file. Some of you guys may, your modules may not even have an install file because you probably wouldn't need one unless you've got update functions. There's only a couple other things that can go in an install file, but yeah, you just drop it into the same directory as your module. Originally they were used to update modules between major versions and you can still use them for that. If you've got a module like 1.0 and you're completely changing the structure and you're releasing it as 2.0, modules update functions will help your users like migrate all of their database stuff to the new version. They can be used for a lot of different stuff. You can add and remove fields from your content types. That's a very common use case. You can provide default values for any of your Drupal variables or enable modules. This is one that is really something that you guys should think about adopting. You should probably never go into the modules page of your site and tick enable and hit save unless you're just playing around with stuff on your dev copy. If that's something that's being done on staging or on live, you should really put it in an update function. The system table in the database keeps track of which modules are enabled and it also keeps track of the version number of every module. So your update functions will only get run once because once they get run, that version number in the database is updated. Interestingly, update functions aren't just for modules. They are also for install profiles. That's gonna be really important later. So one of the interesting and kind of tricky things about update functions is they've got a very specific naming convention. My module is obviously the name of your module. Update and then N. N can be a number ranging from like 6,000 up to other things. If you're working in Drupal 7, yours will always start with 7,000. This update 7,000 is used when you're updating a module from the version, Drupal 6 version of that module to Drupal 7. That's really, really useful if you're doing a site migration from a Drupal 6 to a Drupal 7. Most of us who are working with update functions will start with 7,001. This is like you've got a Drupal 7 module and this is your first update function. And then you just number them sequentially. There's a special number for the second digit which is used to indicate what the major version number of your module currently is. If you're not really using versions of your modules, you'll pretty much never have to worry about that second digit. There is some interesting stuff around how these do get applied if you are migrating from major version numbers of modules, but if you guys are ever in charge of doing something like that, you'll probably be reading a lot of the documentation, so I wouldn't worry about it too much right now. So I'll just show you guys a really basic example of an update function in an example module. So this is the stay sane install function. Can you guys read that at the back? Is it too small? So this module just here is our update function 7,001. All it's basically doing is doing three variable sets. Variable set obviously changes the value of a named variable in the variables table. You'll find that most contributed modules and a lot of core modules, they store their configuration and their settings in variables. So this is a nice way to get in. In this example, we've got a module that is an image carousel. We've developed like a really rough version of it and rolled it out to the site. And then we decided that we wanted to make some of these things configurable. So we've created some functionality that uses these three variables to allow the administrator to make some tweaks to how the carousel gets displayed. So the max number of items and we've got some JavaScript settings as well. Lastly, our update function returns a string that's run through T. That will basically put a message up on the completed page of update.php. If there's any major change of functionality that the admin of the site should probably know about, it's worthwhile putting a message in there. But it's also important to realize that if you're using Drush update DB, those messages don't actually come through in the interface. So if there's something really mission critical, you should probably put it in something like a Drupal set message on your modules configuration page. Now we've got another example update function. In this one, we're gonna restructure some of those variables. Now I just wanna show you up here, the comment block for an update function actually gets used by Drupal. It's really important to have a comment at the top of every update function. The reason that is is because Drupal actually reads this in and when you go to update.php, the description of what each update function is that you're about to run comes from the comments. So always make sure that you at least include a concise comment of what you're about to do. So in this one, the specifics probably aren't really important, but we've decided that instead of having two JavaScript like variables, we're just gonna put them all into one variable that is kind of a structured array. So in this case, we decided to change how our module works and something needs to go in and update it. One of the caveats of update functions is that you can't always assume that the module is loaded. It's kind of counterintuitive, but you may wanna use some functions that you've defined in your module and if you need to do that, you will need to explicitly load the module file because in the update.php that's running, it doesn't always instantiate every module. So that's an important caveat to take note of. In this one, we don't have a message being returned because these changes are kind of all invisible to the admin. They probably don't need to know. Update functions can also be used to do really like large updates of a lot of nodes. For example, let's say that you had a node with a field that had no default value and later on in the process, you decided that you wanted to add a default value. One of the things that you might wanna do is go back through all of the nodes that were created before you made that decision and if they are set to null, if they don't have a value yet, you might want to slip that default value in for them. In that case, depending on how many modules you've got, I mean how many nodes you've got, if you've got like thousands of nodes, you may not actually be able to update them all within one PHP execution time. For this reason, the update functions can use the Batch API to kind of pass information about what has been completed and it can run in several passes. The specifics of that are probably a bit advanced for this talk, so feel free to look up the documentation on Drupal.org and check out the Batch API if you need to do something like that. So failures, if your update function doesn't work properly, you need to find a way to notify the code and also the administrator. In Drupal 7, we use the Drupal update exception and as always, it's good to throw that with like an illustrative message so that your administrator knows what's going on. If there's a database error, like some query or an update fails, Drupal will automatically throw a PDO exception. This one is probably familiar to you if you've ever run an update that didn't work. That's typically the culprit. It's also important to note that during the, like when you enable a module, even if it's the first time that that module has been enabled on a site, your install functions, your update functions for that module will not run. You kind of assume that the update function is updating your database to something that's already taken care of in your new module, but if you're doing things like providing defaults for variables and you're doing that in an update function, you actually have to manually invoke the update function during your modules install. This is something that you have to think carefully about when you're deciding exactly what's going on in your update functions because it's not always a good idea, but it'll be pretty intuitive when you actually try to do it yourself. Okay, so that's update functions, kind of a summary. Now we're gonna get into install profiles. They're basically almost exactly the same as modules, but they have some special logic built around them. They live in the slash profiles directory in your Drupal installation. That fact that they don't live in sites is a constant frustration to a lot of people, but that's just the way it is in Drupal 7. So typically an install profile is like a module, but it usually has a long list of dependencies. What we would do when we set up an install profile is we pick all of the modules that are gonna be enabled in our site and we put them all in there as dependencies. Because they're all dependencies, when Drupal goes to enable your install profile, it has to enable all of those modules as well. Install profiles are also commonly used to set up a lot of common parts of a Drupal site. If you look at the standard install profile that comes with every Drupal, it's very instructive. There's a lot of interesting stuff in there. It sets up the page and article content types. It sets up user roles and it also does some configuration settings. They were originally designed so that you could provide Drupal distributions. Something like a conference website is gonna be really similar across DrupalCon Sydney and DrupalCon Portland. Even though they'll look completely different, they're still gonna have speakers, submissions, registration, ticket sales, stuff like that. So basically you might set up an install profile that packages a set of modules, perhaps a set of compatible themes, and an install profile where the install profile is responsible for setting some sensible defaults. It can also add a few extra pages, like forms to the install process if there's certain things that you need to get out of the user. Okay, so I don't know if any of you guys will be building distributions anytime in the near future, but you probably will be building a custom site and how is a custom site similar to a distribution? Like we talked about, we're gonna be deploying it in multiple places. We've got our dev staging and live instances and they are all gonna need the same modules installed. They're also gonna need the same configuration generally and now that we've got our configuration in an install profile, it's portable and it lives in SVN. Some of you guys may work by setting up a lot of stuff in your dev copy and then importing that database into staging and you're left over with all of the cat gifts and stuff that you've put in for your sample images. If you put configuration and stuff like that in an install profile, it means that when you deploy your staging site, you actually are setting it up with all your configuration in place but none of your content unless your content is absolutely pivotal to live with each iteration. So you end up with clean installs everywhere and that's really nice, especially for a client if the client's gonna be doing their own content population, it's really nice for them to rock up to the staging site and the live site and just have everything clean. So I said before that the standard install profile that comes with Drupal is really interesting. There's a lot of stuff in there and it's a good place to look to get an idea of the kind of things that you can do programmatically. They create text filters. You guys probably have worked with full HTML and filtered HTML text filters. They're both created in the standard install profile. It sets up and enables some default blocks. It adds a few fields to the content types that it's created and it sets some site-wide configuration, creates taxonomies. As I said, an install profile can add additional steps to a Drupal install if there's specific stuff that you need to collect, but if you're working on a custom site, you're not very likely to use that feature. If you guys wanna know more specifically about install profiles, the install profile API is really great and there's a really good page on Drupal.org called how to write an install profile for Drupal 7. All right, so back to custom modules, something that most of us are probably familiar with. They deliver your functionality that your client has asked for. They may be responsible for some custom content types. Sometimes you'll be changing the behavior of an existing contributed module that you installed and sometimes you're taking a bunch of contributed modules and all binding them together into some interesting feature. Yeah, so that's what we're doing with custom modules. So what kind of stuff are we gonna put in our update functions for our custom modules? You wanna concentrate on generic functionality here. Like the example that we looked at, we had a carousel and we were adding a new admin feature that allowed them to select the number of items. So you wanna provide a default, that's a great thing to go in the update function. What you wanna avoid is updating variables like that that already exist for your module. If your module has a default max items of five but your client has decided that they want six or seven, we don't wanna put that in the update function for the module itself and I'll show you why. So in our stay sane example module, we've got our max items to display and some JavaScript settings. Let's say that our client wants us to update that number of max items to six. It'd be really easy because we've already got this module for us to just bang that right into an update function. We're just setting a new value to an existing variable and that is gonna be used on the page that renders our carousel to spit out six items instead of five. What's gonna happen then if we're using that module on another site? One of the things as Drupal devs that you guys wanna concentrate on doing is making sure that the features that you write are not tied to a specific site. If at all possible you can write your carousel so that you can bring it across to the next site that you're working on, you'll save a lot of time and a lot of money and especially if you're demoing that site to prospective clients, they might see a feature that you've built for someone that they want. But if you've got your stay sane module on a bunch of different sites and you add an update function to change that value, it's gonna probably cause problems because the second site that you've installed it on, they may not want six max items on their front page. So it's okay to provide a default value when the module is first enabled or in that feature that variable is first created but it's not a good idea to change that value in an update function if the feature is already live. So the question then is how do we manage that kind of change? A change that deals with a module but it's not required for that module. It's really a site specific configuration and basically to do those kind of updates we put that in our install profile. If we used an install profile to set up both of those sites we can bang that same update function that does exactly the same thing in our sanity install profile because that's only on one site and not on the other it will update the site that wants six items and it will leave the one that's got stay sane with five items just the way it is. The update functions in install profiles work exactly the same as update functions for modules. The only difference is the weight of install profiles is set very high it's set to a thousand by default so typically when your updates run the one in your install profile will run last but that's usually good anyway because you've put some other stuff in the update function for the module and you want that to run first before the install profile tries to give it a different default value. All right so some best practices for our update functions. When we're writing a module we only wanna put changes that are necessary for all sites that use that module in our update function even if there's only one site using that module right now because you may put it on another site later it's just a good practice to follow. But in install profiles you wanna put configuration changes that are necessary for all of your deployments things that don't belong in a module that are specific to a specific site. And that's a really good reason for you guys to use an install profile on every site that you build like a custom install profile. Even if you kind of never use the installation part of your profile it's really good to have that file included so that you can put update functions in it later if you need to update your configurations. Okay so how do we actually write our configuration updates in an update function? This is gonna be something that's different for every feature and every setting that you do because configurations for different contributed modules they're all stored in different ways. Typically though a lot of them put their stuff in the variables table so we can use get and set variables. But again sometimes it can be tricky to figure out exactly what those are. One thing that you can do there's a module called variable changes. Effectively what it does is it lets you back up your variables table and then you can go through and use the actual normal interface for Drupal to go through and make whatever change it is that you need to make. Then there's a report that variable changes gives you that tells you which variables have been changed since you did your last backup. So let's say that we wanted to change the site email address. Your client has created a new email for their site and you're not exactly sure where that lives. You would back up your variables table then go to your site configuration page and update that email address and click save. Then you go to your variable changes report and it will tell you the name of the variable that's changed and what the new value is. So then what you would do is take that variable name and the new value and you would put it in a variable set in an update function like the ones that we looked at before. For modules that don't store their configuration in the variables table it can be a bit trickier to figure out like how to save the new change like where it goes, what code we use to make that happen. In a lot of cases the best way to find out where that stuff is stored is just to read through some of the code of the module. You don't really wanna read through all of the code from some contributed module just to find that out though. One of the best places that you can look is go straight to the admin form and typically the submit function. There will usually be like a variable set or something in there. The other thing that you can do is go to those admin forms and use like a Chrome Inspector or Firefox debugging tools and look at the actual name of the input element that will usually correspond to something like a variable. Okay, so what things are we gonna do that work really well in an update function? Basically anything that you can do with the Drupal API you can do in an update function. Specifically variable set is one of the things that you're gonna be using a lot. You'll also be doing things like enabling modules. When you are developing a custom site and your client has asked for a new feature and you've decided there's a contributed module that does exactly what they need and I need to install that and enable it on their live site. The way that you would go about doing that is you take that module, you put it into your version control in the modules directory and you create an update function in your install profile that says enable that module. Then you deploy your new code to the live site, you run updates PHP and that module is enabled for you straight away. That's kind of the best practice way for enabling new modules on a staging or a live environment. You can make changes to the content types and modify fields. This is probably going to happen with custom sites that have their own content types. One of the things that we've had to do is we had a content type that gave you a dropdown list and we wanted to change one of the values to something else so we used an update function. We looked through the entire database and changed everything that had the old value to the new value and then modified the field. You can also use it for working with user permissions pretty much anything that can go in a database query. Although obviously if there's a way to do something with the API over a database query you should generally go with the API. You will find in your work as a Drupal developer that there are things that are very hard to put in update functions. It's almost always doable but it can get pretty challenging. Anything that's hard to do programmatically obviously is going to be hard to put in an update function. A lot of times you'll find that you're working with specific nodes or specific node IDs. Sometimes you'll find yourself with a variable that stores like the NID of your homepage or something like that. If you're not storing that NID as a Drupal variable, if you're storing it somewhere in the code, that can get a bit hairy because you don't know that the node ID for that thing is gonna be the same across dev, staging, and live. So basically any functionality that you have that relies on knowing the NID of a specific node, please try to make sure it's in a variable somewhere. Complex changes to content types like the scenario I described before, they can get pretty complicated especially when database assertions tell you that you're not allowed to change something like a field that already has values. It is usually doable but it's hard for a good reason because when people have created content they don't necessarily want you to go in there and change one value to something else. But if you have to do what you can. Enabling and placing blocks, this is one of the things that just really wasn't designed to be done using the Drupal API. It's always been kind of a bit of a sticking point. It is doable and if you look at that standard install profile that comes with Drupal, they do do that in the install profile so you can see kind of a method of what they do but it generally revolves around straight database queries and updates. The last thing that is often troublesome is configuration updates to anything that deals with C tools. A lot of site builders use things like views, panels and pages and those have very complex structures in the database so it can be pretty hard to figure out sometimes what the existing values are and where they're stored and how to change them to something else. But thankfully most of those modules have things like exportables and you can also use the features module typically to break those things out into a bit of PHP code that you can throw either into a file or an update function. Doing stuff like that with update functions, the learning curve is pretty high but once you figure out how to do it once, you pretty much have it. I guess you always have to assess when you get into those complicated scenarios when it may actually be worth it to just go through and do it the old clicking way. I don't recommend it because I like everything to live in the code and we already talked about all of the bad things that can happen when it doesn't but if you're working with something like a view and all you wanna do is switch around some columns, if it only takes you 30 seconds to do it using the interface and it's gonna take you eight hours to write the update function, obviously you've gotta make a call about whether it's worth it or not. I would always put it in an update function but it's up to you to decide for yourself. So testing update functions is always interesting because they make one way changes to your database but all you need to do is use something like a database backup and restore tool. You can use PHP MyAdmin or SQL Pro. There's some like three Drush commands that you need if you wanna do that with Drush and you can write your own bash scripts and stuff if you're into that. The commands that you're gonna wanna use if you're using Drush, okay. In our testing workflow, first we're gonna create all of the test data that we're gonna need to test our new update function. Sometimes this step is trivial, sometimes you've gotta create four or five nodes. You always wanna do that first and then take a database backup because otherwise you're gonna do it every time. It's gonna take you a lot of time. So enter your test data and then take a backup of the database. So if you're using Drush, there's a great command called SQLDump. Can you guys see this at all? Not sure if I can. Anyway, the command is SQLDump and it gives you a messy bit of SQL syntax. So we're just gonna pipe it to a file. In my case, I'm gonna pipe it to gzip and let gzip save it as my DB snapshot. So that will basically use my SQLDump. It creates a file that has all of the SQL statements that you need to recreate the exact state of database that you had before. So once I've created my backup, then I'm gonna go back and I'm gonna run update.php or drush update ddb. If you guys are doing debugging and you wanna spit some output out during your update function, you're gonna wanna use something like dd. For any of you that are familiar with the DEVEL module, which I highly recommend, there's basically two ways for DEVEL to spit out output. One of them is using DPM and that will spit it out in a really nice structure on the page. The other way to do it is to run dd which spits everything out into a file on the hard disk and what you can do, it's typically stored in tempDrupalDebug. What I like to do is tail.f and well, I don't have it now because I haven't been doing any debugging but that'll let you watch the changes as they happen. So you've got your debugging output, you're ready to run drush update db or update.php. If you've got debug output, examine what happened, go to any page that you need to go to to confirm that it worked or how well it worked. If you need to make some tweaks, then you've gotta go back and restore the database. So to do that, we use a drush command called sqlc. sqlc basically just lets you put query code straight into the CLI. And like I said, the snapshot that we made before using SQL dump, that is just a file containing query code. So because I gzipped mine, I'm gonna gunzip that file and I'll pipe it to drush sqlc and bang, we've just restored our database to what it was before we ran our update function. So then we can go back and do all of our testing again. All right, so trying to teach you guys some best practices about how to work in Drupal 7, but unfortunately everything that I'm telling you is gonna get thrown out the window when we get to Drupal 8. Not exactly everything, but we're gonna try and do things a bit of a different way. Install profiles are getting changed in Drupal 8 because for something that essentially is only used when you first set up a Drupal site, the core developers didn't want that code included essentially on every page view because your install profile is being loaded as a module on every page that's getting executed and that's some wasted cycles. So in Drupal 8, install profiles are only gonna be used during the install process and then they'll basically be ignored, which means we can't put our configuration changes in update functions in our install profile anymore. They'll just get ignored. There's a few different ways that we're gonna be doing it in Drupal 8. If you wanna keep using this basic method, what they recommend doing is that you create a special module just for your configuration changes and that module will be different on every site that you build. It won't have any functionality in it. It'll basically just be an install profile, sorry, an install function, an install file for your module and all it will contain are update functions. So you put your update functions into this special module and they will get run. Hopefully though, we're all gonna be moving to the new configuration management system. The configuration management system that's being built into Drupal 8 is really nice because it actually puts all of your configuration into files and what that means is those files can live in your subversion and they don't have to be in code. They don't have to be in update functions. You can version them across your different deployments and stuff like that. So the new configuration management coming in Drupal 8 is gonna be really nice and it's gonna save us from having to do all of this stuff. But seeing as that's maybe a year or more away, we're still gonna have to use this method for the time being. Okay, so just to sum up some best practices, we're gonna try and use our proper use of update functions both in our modules and in our install profiles. We must use version control. It's absolutely crucial for any Drupal site. Any of you guys, I'm sure that you're all using it. You're all very smart people but if you're not, start using it. Whenever you do an update from version control, especially if you're working with another developer, always make sure that you run update PHP because otherwise you're gonna end up like Bob and we don't wanna end up like Bob. Again, if you haven't seen it before, look into the DevL module. It's really simple but it provides a lot of great tools for when you're developing modules. If you've never done any module development before, I highly recommend that you install that module and look at some of the documentation. You're all probably using version control but one thing that you may wanna look into is version control that works with one click deployments. This can either be a service like Spring Loops or Beanstalk or it can be something that you host locally. There's plenty of scripts out there that you can find on GitHub. Basically, a one click deployment just means that it's somewhere where you go and set up the details of your staging and your live environment like SFTP credentials and it allows you to deploy whatever the new code is to your staging and live environments at the click of a button. You don't have to worry about manually SFTPing in and updating your new files or whatever. Yeah, it'll save you money and headaches. I absolutely promise. And for any of you that haven't looked at Drush, if you're gonna get into developing, it's definitely, again, a tool that you really need to check out. Things like, it's got excellent tools for things like install profiles, working with a database. It's a huge wealth of functionality. For any of you where this talk may have been a little bit too beginner and you wanna get deeper into install profiles and things that you can do with that, there's some really great resources. Specifically, I recommend an article called Drush Make and Install Profiles. There's basically a way that you can take your development copy and use Drush Make to create an install profile for you that includes all of the modules that you've got enabled, all of your configurations, and all of that stuff in one go. So if that's something that you're interested in, definitely check that article out. These are a couple of modules that are probably worth looking into. We've got Profiler, which is similar in some ways to features in that it lets you take some of your configuration settings and export them automatically. If you're interested in doing stuff like that, you should also check out the configuration manager module. The thing that's interesting about configuration manager, it's pretty new and it's based on the same ideas that the configuration management in Drupal 8 is going to use. If you're looking to get ahead of the 8 ball, you might want to start looking into that soon and then you'll be really familiar with configuration management when Drupal 8 rolls around. Thanks, guys. I know that this probably wasn't the most exciting talk that you could have gone to because there's so much awesome stuff, but you guys came here and learned about update functions. So thanks a lot. My name's Lindsay Gaines. I'm also known as Ether on Drupal.org and I'm from Monkey in Melbourne. If you guys can, I've been asked to remind you to evaluate the session and you can find the code examples that I showed you in a sandbox on Drupal.org. If you just download the slides off the Drupal Considney site, you can get those links because I know that they're probably really small. I would love to recommend some other talks that you guys should go to, but it's a little bit late, so I hope you enjoyed Drupal Considney and I hope you guys come back to the next Drupal conference that we have here or anywhere else. If you guys have any questions, now is the time. Can I tell you anything about Merlin of Chaos? I haven't met him personally. I just know that he writes some really, really hairy code. I've wrangled with some of the stuff that he's done, trying to get things like panels and panel updates to go into Drupal update functions. That was some of the hardest work that I've ever had to do, but no, I can't really tell you anything about him. Sorry. Any other questions? Yeah, so that's ADEA. Yeah, field display settings. That's a bit tricky. If you're working with a field that you have defined as part of a custom content type, I guess it depends on whether that content type is really specific to a customer's site or whether it's something that you think could be like used across other sites. It is something that you can get in and change programmatically, but it's kind of a hard thing. It's kind of gonna be dependent on the specific site that you're working on. I guess typically I would probably put it in the install profile, and it's something that you use. I think the function is called update instance, but yeah, it's pretty tricky, that stuff. But when you're working with custom content types, that's the kind of thing that you'll be putting in your update functions. Sorry, did that answer the question at all? The display suite, yeah. Basically, there's a field read instance function, and what it gives you is a big structured array. It just tells you what is currently enabled on that field. What you would basically have to do is go into the content management interface and go to that content type and go to that field and look at the dropdown of what your available formatters are, and when you inspect that in Chrome, the names of each option in select are the things that support that field. So you pick the one that you want. Yep, so you use a function called, I think it's called read instance, and you pass it the content type specifically that you're looking for and the name of the field. That gives you the structured array with the current settings for that field, and one of those options, one of those things in the array will be the formatter, and also whatever it's called, the display. And basically, you just swap out that value in your complex in that array, and then I think it's just save instance, and that saves it back to the database. There is a lot of functions around reading and saving instances. You just have to get the differences between an instance and a field around your head, because the field, if you do a read field, it will give you all of the available options for that field. We did have to do that on a site that I just worked on, so I know that it's possible. Yeah, if you come later, I'll bring up the source code. Okay, so what Features does is it bangs everything into just a module file and an install file for that module. What you could do is you could use Features to get it to export a bunch of that stuff, but then you may have to go into the code that it's generated and look at what it's doing, and then you can copy and paste some of that stuff into an update function. Yeah, because Features doesn't write update functions. Yeah, it just writes the module and the install function. Are there any other questions? So you're talking about testing in an environment where you need to test on the live data. I'll be honest, I really try to avoid ever exporting the live database into a staging or a dev environment. A lot of the sites that we work with, there are privacy concerns about having that data outside of your hardened production server. So I really like to just use lorem if some generators and node generators and stuff like that. If you have to do it, obviously, you have to do it. I would just export that data, put it on your dev copy, and write your update functions to work with that data, make sure that everything goes right, do whatever checks you need to do to make sure that you haven't messed up the data that's there, and then hopefully delete that database off your dev copy and commit your update function. And obviously before you deploy that new code to live, you're gonna take a database backup anyway, so in case something does go wrong, you gotta roll back. Does that answer your question? No, it's figuring out what to put in the update function. Have you ever looked at the actual exportable for a panel or a view? It's like a huge block of PHP code, it's usually a set of objects or structured arrays. And it's not as simple as taking the initial exportable, making the change, and then taking the next exportable and doing a diff, because when you do the update, you need to include the whole object. But that's probably the best way to do it, if that module has exportables. There are some things like panels that make it almost impossible for you to do that stuff programmatically. Especially because oftentimes you're working in a situation where if you're using panels, the client may have gone and made a bunch of changes to a page that haven't been done on your dev copy, and you can't really tell your client to follow this methodology, because that's the whole reason that you installed panels in the first place. In cases like that, you really do need to go to the live database, get that data into your development copy, do those diffs, and put it in an update function. This is probably the hardest part, is telling your client that while you're working on the feature, they can't touch the panels for that page. Yeah, it's just always tricky, I guess, working with those heavily client-focused features that allow them to click through a lot of configuration. Any other questions? All right, cool, thank you guys so much for coming and listening to the talk. If you guys have any questions, just come grab me.