At DrupalCon Los Angeles, the question on everyone’s lips was: “When will Drupal 8 be released?”
Each time it was asked, it felt more and more like a recurring dream. Is this thing real, or did some Belgian guy start a rumor?
Views in core? Really?
Drupal configuration in code?
Ha! Now I know you're kidding!
Well guess what: Drupal 8 is not just some intangible vision that Drupalistas keep dreaming about. It exists and, ready or not, here it comes, barreling down the road. Very soon, my friend, the dream will become reality.
But bear in mind that the Drupal 8 dream is a lot like Disneyland:
- Entry to the park ain’t free. (You're going to have to acquire some new skills.)
- There will be long lines for your favorite rides. (Not all modules will be stable right away.)
- At the end of the day, you’ll be pooped. (Your first Drupal 8 project will exhaust you.)
- You might be too small for some attractions. (Neither you nor your clients will be quite ready-to-go on Day One of Drupal 8’s release.)
Putting skepticism aside, I am truly excited about the things coming in Drupal 8. The one new feature that I’m particularly excited about – and I think many others are, too – is Configuration Management. Drupal 8 will finally give us the ability to store site settings and configurations in code instead of mingled with content in the database. For me, and for your DevOps person, that’s the dream: Finally, no more scribbling notes on the back of an envelope for what we changed so we can remember to do it live in production.
If you’re as excited about configuration management as I am, you may stop reading now and just jump in and play with Drupal 8. Or maybe take a look at this article from a couple of Drupal Watchdog issues ago.
But if you're not ready to take the plunge, or know that you’ll be using Drupal 7 for a while longer, then please read on.
Let’s start with a preface: There is no single solution, no silver bullet that will solve all your configuration problems. But a lot of work has gone into making them less painful, via some contributed modules that are available today for Drupal 7: the Features module and the Configuration module. With a bit of time, patience and, perhaps, some creative thinking you'll find that these two modules will put you in a good place – and even prepare you for the Drupal 8 way of thinking as it relates to configuration in code.
You’ve probably heard about the Features module already; it’s been around for a while. If you haven't used it since the 1.x days, it's time to download it and give it another try.
Features basically captures a set of configurations in a single package that can be exported and moved to another site. Once there, it can be enabled just like any other module. In other words, it's a module that makes modules from modules. Features provides you with a module that you can give a version number to – and commit to – your favorite version control system. It's great!
Let's give it a try. For this example, I’ve created a blog on a development site. This blog consists of a content type with some fields and a view named Blog. From here, get and enable Features.
$ drush dl features && drush en features
We can export our work by telling Features which components of the site need to be captured. You only need to know the machine name; I use
drush features-components to get a list of the components and source machine names, or
drush fc for short. For this blog we know that we used the Article content type, and the view name is Blog, so our machine’s names are
Our export command will look like this:
$ drush features-export mycoolblog node:article views_view:blog --version-set=7.x-1.0
This will create a feature module named mycoolblog and even though a version isn't required, I set this example to 7.x-1.0 because it's good practice. Drush will then save it in the sites/all/modules folder for you. From there you can run your version control magic or move it manually to another site. Simply enable your feature like you would a regular module. I bet you’re starting to see the possibilities already.
What about changes?
They’re pretty easy: make changes to your development site just like you would before you started using Features. When you’re done, run the export command from above and be sure to change your version number accordingly. Alternatively, if you’re working on a site that has the feature module already enabled, use the
fu for short.
$ drush fu mycoolblog --version-increment
This command will export the changes you made from the database to your features code and bump your version number up by one. From there, you can jump into your normal deployment workflow.
Keep in mind that if someone else overrides your feature on the site you are deploying to, their feature won’t fully enable; it will hold back the overridden part(s). You can tell which features on a site have been overridden using
drush features-list. That will list all the available features and which ones are overridden. Once you know which features have conflicts, you can dive in and start resolving them. I'll leave conflict resolution to you with this bit of help: find extra Drush commands for Features in the documentation section of the project.
If you do choose to use Features to manage your site's configuration, be sure to test everything first. It’s easy to miss a component and deploy with a half functional feature. You’ll also want to break down your features into common components. For example, keep all the components related to the blog in its own distinct feature. This will require planning, especially on larger sites, but it’s completely feasible. On some of the more complex sites. I tend to use the Feature UI instead, and make sure I get the feature right before I export, but don't tell anyone I admitted to that.
The Configuration module is different in its approach. It's actually more like what you'll get with Drupal 8. Features works around the concept of a packaged module, where Configuration exports the config as PHP arrays to file. It doesn't try to make modules or anything like that, it just dumps out code.
When you start using this module, there are two new terms to learn: activestore and datastore. The activestore is another way of referring to your live configuration, or what's in the database. The datastore is the exported configuration stored on the server's filesystem. If you end up using the Configuration module, make sure you understand the difference between these two terms.
Out of the box, this module doesn't assume anything for you, it only creates a folder named “config” in your public files folder. To get started with the module, you need to explicitly tell it what you want to track. Don't worry, you can change that config folder location to anywhere the web server has write permissions. For simplicity, as we proceed I'm going to leave that config folder right where it is. BTW, like Features, the Configuration module, too, has Drush commands as well as an administrative UI.
Now I’ll get you up to speed with the Drush commands.
Using our previous example, let's export the Blog to code. You’ll need to figure out the machine names of each component you want to track. Start by listing them with the command
What's nice about this output is that it shows both the human readable and the machine name. From this list, we can ask Drush to show us all the identifiers of a component. (An identifier is the same as the source from Features.) Using the component
content_type we can get its identifiers with the following command.
For simple sites, assembling your list of components and identifiers should be pretty easy. In most cases you won't need to look anything up, particularly if you are the one who built the site. To export the Blog you would use a command similar to this:
$ drush config-start-tracking content_type.article views_view.blog
The above command,
config-start-tracking , short for
csta, will export the configuration for the view and content type and all the dependencies associated with them, such as permissions and image styles. Don't believe me? Try it! I'll wait…
Now for changes. Let's say you need to add a block display to the view. Just as you did with Features, make your changes to your development site like you always have. Then, you can export those changes to the datastore with the
config-export command. Assuming you only changed the view, your command would look like this:
$ drush config-export views_view.blog
That should export all the items from the activestore (the stuff in the database), that are different from what it finds in the datastore (the stuff in code). Once your configuration has been exported to the datastore you can move it to another site and activate it. You can do this via some kind of version control or the old fashioned way, by manually moving it yourself.
Getting this tracked code to import into another site is pretty easy. First, turn on the configuration module, then move the new files into the config folder that the module generates. Once the files are in place, you can run this sync command.
$ drush config-sync
This will look in your default config folder and import anything that exists in the datastore but not in the activestore. It will turn on modules, create views, and set variables that weren't there before.
If you’re moving changes into a site that is already tracking configuration, the method is the same. Copy your new or changed configuration files into the config folder and run the sync command.
BONUS LEVEL: If you want to be more like Drupal 8, you can create a second folder called “staging” and place your new configuration files there. Run the same sync command but add a
--source like this:
$ drush config-sync --source=path/to/staging
This command will read the configuration from the staging folder and import it into the default config folder and activate all your new config at the same time.
Should you choose to use this module, remember: If you remove something, say a field, you will need to manually stop tracking that field and then delete the include file from the datastore on both the development site and your target. Otherwise your deleted items will just keep getting imported, even though they were removed in development.
For a few more commands that I didn't cover here, refer to the module documentation.
Both of these modules are powerful. They overlap in a lot of areas but each has its own strengths.
The great thing about Features is that it's easier to start using, even if you are not a power user. The admin interface is a little easier to work with than the Configuration module and there isn't confusing verbiage like datastore and activestore. Plus, I feel that moving code to another site in the form of a module is much easier to wrap your mind around.
As for the Configuration module, it's a little less friendly to the non-power user. However, with some careful trial runs and testing, anyone can get the hang of it. Ultimately, it's a little unfair to compare these two since it’s not apples to apples. You would likely want to use this module in combination with Features, tracking certain variables and settings in one place while creating feature modules elsewhere. For example, a simple blog makes a great feature and perhaps is unnecessary to track with the Configuration module, since all its settings are already stored in code as a module.
How you end up using these two modules will depend largely on your project. Plan ahead and always run tests, even if it's a manual test where you're the one clicking and loading pages. Make sure you obtain the exact result expected before you give either of these a go on any production site.
Once you find the sweet spot, I'm pretty sure you will be living the dream, the Dream of Drupal 8.
On that note, I leave you with one last thought. It doesn't come in my words but rather John Lennon’s:
“You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us. And the world will be as one.”
Image: "Far Away Thoughts" by John William Godward is Public Domain
Disclosure: I'm jaded by a few bad experiences with configuration.module in D7.
I do not think configuration is ready for prime-time yet in D7. I've used it to store overrides from several commons sites and wished I hadn't every time. I cannot trust it will always export the configuration and it is constantly reverting to an overridden status. Even when a config item hasn't changed. And it is really slow. You're much better off in D7 using features_override.
At the time of writing the article, the Configuration module was very promising for me. It solved a handful of problems in a particular workflow. But, I too had some troubles with it and eventually stopped using it. Now I primarily use Features for D7.
I have not looked at Features Override yet, but will do so based on your suggestion. Thanks!