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:
- Choose a name (e.g. Default Content) and a version (e.g. 7.x-0.1)
- select the option “Deployment: deploy_plans” from the “Edit components” dropdown menu, and you will see the deployment plan defined before;
- check it;
- 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;
- check the entry with the same name of the deployment plan;
- 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.