Hard and Soft configuration in Drupal Distributions

Antonio De Marco
7 Feb 2012
5 Comments
Antonio De Marco
7 Feb 2012
5 Comments
Antonio De Marco, 7 Feb 2012 - 5 Comments

Hard and Soft configuration in Drupal Distributions

Features, taxonomy and other beasts

An extract from the new teaching materials we are preparing for our DrupalCon Denver 2012 pre-conference training, Code-Driven Development: Use Features Effectively.

By now the advantages of a clean Code-Driven Development workflow are clear to the majority of Drupal developers; things like separation between configuration and content, packaging and deployment of new site functionalities or sharing changes in a distributed team don't look that scary anymore.

Still not everything in Drupal can be clearly classified into configuration or content, such as Taxonomy terms. Taxonomy terms are mostly used to categorize our content so, naturally, they are often used in site configuration: a context that reacts to a given taxonomy term is a fairly common scenario. Taxonomy terms can be generated by users (think about free-tagging), which makes them fall into the "Content realm". Drupal, in fact, considers them as such, assigning to each term a unique numeric identifier, and that's the problem.

Each component has its own name

One of the turning points in making configuration exportable in code was the introduction of a unique string identifier for each component: this way it's easy to share configuration and to avoid conflicts. So what happens with taxonomy terms? If they appear in our context conditions then we'd better bundle them together: no matter where we are going to deploy our feature, they will always have to have the same values. That's simply not possible: they have numeric IDs, forget about easy life here.

Various attempts have been made to export numerically identified components, such as UUID Features Integration or the handy Default Content module, but they only solve part of the problem: we want other components to know the unique name of our terms.

Hard and Soft configuration

At Nuvole we adopted the following terminology to classify the two kind of settings that we need to deal with everyday:

  • Hard configuration includes the settings under the distribution developer's control (e.g., Views or Contexts); it has a machine name, it is easy to export, it gives no headache. We store it in Features.
  • Soft configuration includes the settings that are meant to be overridden by the site administrator (e.g., the default theme, or the initial terms of a vocabulary); it often gets a unique numeric ID from Drupal, it is impossible to export safely, it is painful to handle. We store it in the Installation profile.

This distinction becomes fundamental when the configuration is altered or (if you are dealing with a distribution) when the underlying distribution is upgraded. In the case of Hard configuration, altering it results in an overridden feature, which is upgrade-unsafe. In the case of Soft configuration, altering it does not change the Features state, since the corresponding settings are stored in the Installation profile, and changes are upgrade-safe.

Not only taxonomy terms

The distinction between Hard and Soft configuration goes beyond how to conveniently export taxonomy terms: it is more a design decision, especially important when dealing with distributions. We consider everything that the site builder might be entitled to change as Soft configuration. The place where to usually store Soft configuration is your hook_install(); this guarantees a safe upgrade path to the next version of the distribution. An example could be the default theme: you may ship your distribution with a specific theme but the site owner might want to change it and subsequent updates shouldn't alter it.

Here is how our profile hook_install() might look like in a Drupal 7 distribution:

<?php

/**

* Implements hook_install()
*/
function example_install() {
 
   $terms
= array();  
 
   $vocabulary
= taxonomy_vocabulary_machine_name_load('category');

 
   $terms
[] = 'Solution';
 
   $terms
[] = 'Client';
 
   $terms
[] = 'Use case';

 
  
foreach ($terms as $name) {
    
$term = new stdClass();
    
$term->vid = $vocabulary->vid;
    
$term->name = $name;
    
taxonomy_term_save($term);
   }
  
 
// Enable custom theme
 
 
theme_enable(array('example_theme'));
 
variable_set('theme_default', 'example_theme');  
}

?>

Reference for site builders

If you are customizing a distribution and you need to override some of its default Hard configuration you might want to have a look at the Features Override module and at these two related articles from Phase2 Technology:

Comments

Comments

Pasqualle
8 Feb 2012

When I have to use a taxonomy id in code, I use codes instead.

When I have to use a taxonomy id in code, I use codes instead.

Pasqualle, 8 Feb 2012

When I have to use a taxonomy id in code, I use codes instead.

Pasqualle, 8 Feb 2012
Antonio De Marco
8 Feb 2012

Thanks for the tip! The module looks great and in certain use cases it could definitely represent a good alternative to taxonomy terms, although the method described in the post could still be preferable if using taxonomies is an hard requirement in developing a distribution.

Thanks for the tip! The module looks great and in certain use cases it could definitely represent a good alternative to taxonomy terms, although the method described in the post could still be preferable if using taxonomies is an hard requirement in developing a distribution.

Antonio De Marco, 8 Feb 2012

Thanks for the tip! The module looks great and in certain use cases it could definitely represent a good alternative to taxonomy terms, although the method described in the post could still be preferable if using taxonomies is an hard requirement in developing a distribution.

Antonio De Marco, 8 Feb 2012
carsonblack
13 Feb 2013

Ciao Antonio!

Helpful post. It should not be an issue putting the hook_install() or hook_enable in the Feature's .module, correct? As long as you clean up with hook_uninstall or hook_disable?

Also that codes module looks pretty useful as well.

Bellissima! ;-)

Ciao Antonio!

Helpful post. It should not be an issue putting the hook_install() or hook_enable in the Feature's .module, correct? As long as you clean up with hook_uninstall or hook_disable?

Also that codes module looks pretty useful as well.

Bellissima! ;-)

carsonblack, 13 Feb 2013

Ciao Antonio!

Helpful post. It should not be an issue putting the hook_install() or hook_enable in the Feature's .module, correct? As long as you clean up with hook_uninstall or hook_disable?

Also that codes module looks pretty useful as well.

Bellissima! ;-)

carsonblack, 13 Feb 2013
carsonblack
13 Feb 2013

But the real issue after that, when you're using the term in a view, is the changing term id right? So what is the module(s) that are the current best solution for that (UUID)?

But the real issue after that, when you're using the term in a view, is the changing term id right? So what is the module(s) that are the current best solution for that (UUID)?

carsonblack, 13 Feb 2013

But the real issue after that, when you're using the term in a view, is the changing term id right? So what is the module(s) that are the current best solution for that (UUID)?

carsonblack, 13 Feb 2013
Andrea Pescetti
17 Feb 2013

You can surely put a hook_install() in the specific files of a feature (I would recommend the feature's .install file to follow the Drupal conventions, though) but a big benefit of "Soft Configuration" is the ability to apply configuration in a controlled environment, i.e., when you are able to make assumption since you know the status of the website.

To exemplify (and answer your other question too): if we create three terms as "Soft configuration" in hook_install() in the profile, we can make assumptions on their TIDs, since we are in a repeatable situation. The same does not hold when creating the terms in hook_install() of the specific feature, since if you enable it at a later stage or you uninstall/reinstall it you won't be able to make assumptions. But it surely makes sense to use hook_install() in the feature's .install file, so long as you can make assumptions.

You can surely put a hook_install() in the specific files of a feature (I would recommend the feature's .install file to follow the Drupal conventions, though) but a big benefit of "Soft Configuration" is the ability to apply configuration in a controlled environment, i.e., when you are able to make assumption since you know the status of the website.

To exemplify (and answer your other question too): if we create three terms as "Soft configuration" in hook_install() in the profile, we can make assumptions on their TIDs, since we are in a repeatable situation. The same does not hold when creating the terms in hook_install() of the specific feature, since if you enable it at a later stage or you uninstall/reinstall it you won't be able to make assumptions. But it surely makes sense to use hook_install() in the feature's .install file, so long as you can make assumptions.

Andrea Pescetti, 17 Feb 2013

You can surely put a hook_install() in the specific files of a feature (I would recommend the feature's .install file to follow the Drupal conventions, though) but a big benefit of "Soft Configuration" is the ability to apply configuration in a controlled environment, i.e., when you are able to make assumption since you know the status of the website.

To exemplify (and answer your other question too): if we create three terms as "Soft configuration" in hook_install() in the profile, we can make assumptions on their TIDs, since we are in a repeatable situation. The same does not hold when creating the terms in hook_install() of the specific feature, since if you enable it at a later stage or you uninstall/reinstall it you won't be able to make assumptions. But it surely makes sense to use hook_install() in the feature's .install file, so long as you can make assumptions.

Andrea Pescetti, 17 Feb 2013

Comments

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Get your project started today!

Contact us