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.
Commenti
Great post!!! Thank you for
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
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,
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
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
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
updating to the latest dev of entity_dependency fixed the issue of empty .features.uuid_entities.inc array for me.
Invia nuovo commento