Skip to main content

A lightweight default content solution for Drupal 7 install profiles

As you may have read last week, we're starting up a Drupal 8 CX initiative which will feature a site for tracking the status of Drupal 8 module ports.

We'll be displaying a curated list of modules that we've identified as priorities for Drupal 8. But in order for others to build their own site to track their own priorities, we're building the site using an install profile.

Because I'm using an automated phing task to 'burn and reinstall' the site on a regular basis, I needed a simple lightweight solution for default content - for things like blocks (using bean) and basic nodes.

Read-on to see my approach.

by lee.rowlands /

The solution

So inspired by Drupal 8, I wanted to use yml to define the default entities. So I started with a folder inside my install profile called 'content' and then inside there I created a file for each entity type like so

Next I need something to parse the yaml, so I fired up my terminal and added a composer dependency

composer require symfony/yaml

Then it prompts me for a version, now I already had require-dev for drush, so I needed to pick a compatible version of symfony/yaml - ~2.2 will suffice

The whole thing looks like this:

Next I need to make sure that PHP can find the new classes, so in my profile I added an include for the autoloader

// Load composer autoloader.
include_once dirname(DRUPAL_ROOT) . '/vendor/autoload.php';

Next I need to ensure that the entity api module is enabled, but thats a one-liner in my profile's .info file

dependencies[] = entity

Then I added a small snippet to my install profile's hook_install() like so:

// Create default content.
  try {
    foreach (file_scan_directory(__DIR__ . '/content', '/\.yml$/') as $file) {
      // Files are named {entity_type}s.yml.
      $entity_type = substr($file->name, 0, -1);
      $entities = Yaml::parse(file_get_contents(__DIR__ . '/content/' . $file->filename));
      foreach ($entities as $values) {
        $entity = entity_create($entity_type, $values);
        entity_save($entity_type, $entity);
      }
    }
  }
  catch (Exception $e) {
    watchdog_exception('drupalinfo', $e);
  }

So what does the yml file look like? Here is a snippet from nodes.yml

credits:
  title: Credits
  body:
    und:
      -
        value: |
          Sometimes there is a need for strings to wrap over multiple lines for
          readability
        format: rich_text
  type: page
  uid: 1

Conclusion

So this is a pretty simple and lightweight method for shipping default content. Sure it doesn't support images or references, but if all you need is some simple data, or data to test your build process - its a satisfactory solution

Posted by lee.rowlands
Senior Drupal Developer

Dated

Comments

Comment by Your title is wrong

Dated

The article is about Drupal 8, but at the title states for Drupal 7.

Comment by Anonymous

Dated

An interesting approach :) I had just skimmed the article and seeing YAML files and composer, thought it was for D8.

Comment by ehhh

Dated

ehhh, Drupal 8!

Comment by kreynen

Dated

YML isn't something that is specific to D8, composer, or symphony, but it is not included with PHP by default in most builds and isn't available on many hosts. This method assumes a lot about the user's hosting environment. It is really only "lightweight" if composer and symphony are already configured. The YML PECL extension can be installed without composer by following the steps found at http://www.php.net/manual/en/yaml.installation.php. Other than to get more familiar with YML, there is really no advantage in using YML over XML (or even arrays... can be parsed by PHP "out of the box") to import simple nodes.

Instead of a "lightweight approach", a more appropriate title might have been something like Get Familiar with Composer, Symfony and YML to Import Nodes in D7.

Comment by jhedstrom

Dated

Would be great to see this functionality added to the Profiler library (https://www.drupal.org/project/profiler), which already allows creating things like users and nodes via .info files. From your code snippets it doesn't look like it'd be too much of a lift.

Comment by Sam

Dated

An interesting approach. We've had similar success with features_uuid which can handle things like images, however it definitely is heavier and isn't free from various problems and annoyances.

Pagination