Drupal: Creating Beans Programatically
Building great (Drupal) websites can often be made more difficult than it needs to be when your site builders, developers and themers haven't got the same content as each other.
Creating dummy content is fine up to a point: it lets you test your work to make sure you are going in the right direction. At Annertech we use devel generate all the time and it's a fantastic tool but as it generates content randomly, results can be very varied - for example, a phone number field could end up with 60 integers for example (fine for the developer, but a hindrance to the themer).
The best solution is to have the final site content prior to beginning development, but this rarely happens. If final content is not available, it's beneficial to at least have meaningful content that is relevant to the site. If you build this content into your development plan, it can be used right up to and post site deployment - saving you time and your clients money in the long run.
The Glossary
Bean: A Drupal module to makes blocks fieldable - it stands for "block entities aren't nodes"
Devel Generate: A sub-module of the devel module, used for generating dummy content, users, menus, etc.
Field collection: A module that allows you to group collections of fields and make them repeatable on Drupal entities such as nodes
Features: A module that allows you to export your configuration to code files
Drush: A Drupal shell command tool - the Swiss Army Knife of Drupal tools
The Problem
I'm using the excellent bean module to build a slideshow; its got a field collection for slides and each slide has a number of text fields and an image. We are using features to store the configuration. Each time we rebuild the site we would need to repopulate our bean with our lovely content which after 2 rebuilds could expose a problem in the form of RSI (Really Sore I) or something along those lines. Not an ideal workflow!
The Solution
So, here we are going to build a small PHP script that we can call via drush which will populate a bean with some content programatically, and here's how it looks:
This array contains the 'content' for our bean slideshow. We will loop through this to create each bean.
We will use something like this for each field collection: We are creating an instance of the entity we wish to create, in this case a field collection:
We then attach it to our bean entity. And the whole picture looks like so:
There is a bit more logic added to deal with image files and this script could be improved with a little bit of error checking, but it's a really simple approach and can be easily adapted to suit a number of scenarios.
To call the script with drush simply `drush scr sites/all/scripts/create_bean_slideshow.php` or what ever the path to the script is. For bonus points you can call this through a shell script or build tool like Phing.
In terms of a decent continuous integration workflow, if you're adding new features to a website, this method means:
-
Streamline deployments
-
Verbatim content across environments
-
Contexts, rules and other site elements can use your beans.
-
Less chance of human error
-
A repeatable and reusable process
Also it cuts down on the needless exposure to Really Sore I. And has improved our workflow for new website builds and migrations.
I'd love hear your thoughts in the comments below on how you've solved similar problems for site building.
Gavin Hughes Senior Support Engineer
With a great interest in test-driven development, Gavin is a senior support engineer, tasked with resolving some of our more complex support requests.