Exporting content to code with Drupal

There are cases when you want to export some content from a website, in order to import the same content at some later point into a similar website in an automated fashion.

In my case I want some “default content” to be imported every time I rebuild a Drupal site with drush make, this is particularly useful if you are building a Drupal distribution or a Drupal installation profile, or basing your product on these concepts.

I am going to show how to set up a source site and a destination site, and one possible way to export and import the content from and into Drupal.

In the following text there are some assumptions:

  • The Operating System is Debian GNU/Linux, in particular the group of the web server is www-data.
  • The web server has per-user web directories configured, and the user name is username; you have to substitute your own in URLs when you follow the instructions below.
  • The DBMS is MySQL (BTW, when drush sql-create becomes available I may update the article and drop this assumption).
  • In the code sections below, lines starting with $ are supposed to be commands to be written in a command line shell.
  • The reader has some Drupal knowledge, especially with regard to modules installation and content creation, knowing what the Features and Deploy modules do is a plus.

I used the OpenOutreach distribution because it is simple enough and provides a default content type which supports images, which are not trivial to export.

Let's get started.

A script to set up test sites

Here is a script to make it easier to build test sites under $HOME/public_html/, let's call it create_test_site.sh:

#!/bin/sh
 
set -e
 
[ $# -eq 5 ] || { echo "usage: $(basename $0) <db_name> <db_user> <db_password> <site_path> <site_name>" 1>&2; exit 1; }
 
DB_NAME="$1"
DB_USER="$2"
DB_PASS="$3"
 
echo -n "MySQL root user. "
mysql -u root -p <<EOM
CREATE DATABASE IF NOT EXISTS ${DB_NAME};
USE ${DB_NAME};
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES \
ON ${DB_NAME}.*
TO '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
FLUSH PRIVILEGES;
EOM
 
SITE_PATH="$4"
SITE_NAME="$5"
 
DISTRIBUTION=openoutreach
INSTALLATION_PROFILE=standard
WEB_SERVER_GROUP="www-data"
 
(
  cd $HOME/public_html
  drush dl "$DISTRIBUTION" --drupal-project-rename="$SITE_PATH"
  cd "$SITE_PATH"
  drush site-install "$INSTALLATION_PROFILE" \
    --site-name="$SITE_NAME" \
    --db-url="mysql://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}"
  sed -i "s@# RewriteBase /drupal\$@RewriteBase /~${USER}/${SITE_PATH}@" .htaccess
  chmod 775 sites/default/files && \
  sudo chgrp -R "$WEB_SERVER_GROUP" sites/default/files
)

Set up the source site, create and export some content

Creating a new site is as simple as:

$ cd ~/public_html/
$ ./create_test_site.sh drupal_test_src user_test_src pass_test_src openoutreach_src "Source site"

The admin password will be printed on the standard output.

Log in to http://localhost/~username/openoutreach_src, go to node/add and create some contents with images.

Install the modules needed to export the content (NOTE: development versions are needed for now):

$ cd ~/public_html/openoutreach_src
$ drush dl --dev ctools deploy entity entity_dependency features uuid
$ drush en deploy deploy_ui entity entity_dependency features uuid
$ drush cc all

Go to admin/structure/deploy/plans/add and create a new deployment plan selecting these options:

  • Managed aggregator
  • Fetch-only

Go to admin/content, select some content and add it to the deployment plan using the “Update Options” dropdown menu.

Go to admin/structure/features/create in order to export the content to a Feature:

  1. Choose a name (e.g. Default Content) and a version (e.g. 7.x-0.1)
  2. select the option “Deployment: deploy_plans” from the “Edit components” dropdown menu, and you will see the deployment plan defined before;
  3. check it;
  4. select the option “UUID entities: uuid_entities” from the “Edit components” dropdown menu, and you will see an entry with the same name of the deployment plan defined before;
  5. check the entry with the same name of the deployment plan;
  6. then click on “Download feature”.

Let's say that the new feature module is called default_content-7.x-0.1.tar

NOTE

The resulting feature seems to be lacking dependencies, not only the needed modules from above are missing, but for instance the content type of the exported nodes is not mentioned anywhere either.

Anyhow, as long as you move contents between site installations with the same configuration the default_content feature will work fine.

Let's verify that, let's install a destination site.

Set up a destination site and import the content

$ cd ~/public_html/
$ ./create_test_site.sh drupal_test_dest user_test_dest pass_test_dest openoutreach_dest "Destination site"
$ cd ~/public_html/openoutreach_dest
$ drush dl --dev ctools deploy entity entity_dependency features uuid
$ drush en deploy entity entity_dependency features uuid
$ drush cc all

Install the exported feature and enable it:

$ cp default_content-7.x-0.1.tar ~/public_html/openoutreach_dest/sites/all/modules
$ cd ~/public_html/openoutreach_dest/sites/all/modules
$ tar xvf default_content-7.x-0.1.tar
$ cd ~/public_html/openoutreach_dest/
$ drush en default_content
$ drush cc all

Enjoy the imported content at http://localhost/~username/openoutreach_dest.

Final words

I know that a push deployment plan can be used to exchange content between two actual sites, but remember that I aim to import the content from code when rebuilding a site from scratch, that's why I exported the content to a “feature module”; in my use case, the destination site in this article can easily be seen as a future incarnation of the source site itself.

Someone may also wonder if it is right at all to export content as code; well, in my case I really see this “default content” as configuration so having it stored as PHP code in a feature module makes totally sense to me.


CommentsSyndicate content

Great post!!! Thank you for

nlambert's picture

Great post!!! Thank you for this invaluable information.

You mention as long as you move contents between site installations with the same configuration the default_content feature will work fine

Would it work if someone was to add the missing dependencies to the feature directly?

Hi nlambert, using the

ao2's picture

Hi nlambert, using the Features interface you can manually add dependencies, so yes that may work, but it is an error prone process.

BTW if the post looks useful to you maybe you can comment on the issue about adding ao2.it to Planet Drupal?

Thanks, Antonio

Great post! thanks. However,

Anonymous's picture

Great post! thanks. However, Im having trouble with the features part. When I export the entities, the $entites array my .features.uuid_entities.inc is empty. Im sure I see the contents in the deployment plan though, do you have any tips?

I think I have run into a

Andrew Cant's picture

I think I have run into a similar problem.
I am attempting to export a Webform into a Feature and this post described just what I want to do. (Thank you!)
All the steps in this tutorial work....but I have the same problem as described above where the my.features.uuid_entities.inc array is empty.

And suggestions would be appreciated.

Andrew

(P.S.: I did try re-generate the UUIDs, as guess at what might be missing, but no change when re-downloading the Feature.)

I followed the tutorial again

ao2's picture

I followed the tutorial again with recent versions of the modules involved and, even if the Features UI has changed a bit, I am still able to export nodes with images with no problems.

Would you guys give me step-to-step instructions about how to create the content you would like to export? So I can replicate what you are experiencing.

updating to the latest dev of

drasgardian's picture

updating to the latest dev of entity_dependency fixed the issue of empty .features.uuid_entities.inc array for me.

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
1
h
F
C
D
X
Enter the code without spaces.