I’ve recently blogged about how we use Drupal as a Content Repository. I wanted to write a lessons learned follow up post to see what worked out and what we needed to adjust.
We still use Drupal as a Content Repository and just consume it’s content data via webservices to let our application do the complicated rendering. We launched the external part of our content in November 2011 (see our Expat Magazine and our Country & City Guides) and the internal part in December (you need to request an account to see it). Development of both parts was smooth, but we reached some limits of what one can do with Drupal’s view module and we needed to adjust our “no custom code” to “as little custom code as possible”.
It became unpractical over time to manually add new fields to taxonomy- and node types. The cycle Add field in Development → Commit → Deploy to Staging → Add field on Staging → Deploy to Production → Add field on Production was too clumsy. We now have a single module called, well, “internations” where we add fields programmatically using the field API and execute them using the Drupal module migrations (more or less like described over at Steindom LLC). So our new cycles is Add field in Development → Export to GIT → Commit → Deploy to Staging → Deploy to Production. Much better.
To execute schema updates automatically after deployment I’ve hacked together a reduced version of Drupal’s update.php which executes all pending schema updates in one go without user interaction. This script is executed after the new version is deployed to a certain stage so all pending migrations are executed. Disclaimer: it works for us and it may hurt you badly as it’s just not thoroughly tested.
We had a similar problem with views as we had with new fields: it was clumsy creating them on all stages (nevertheless there is an export functionality, which we use but in a different way). To allow us to be more stupid and to forget about more things, we use the view export functionality to include our views in our module. The development cycle of new views is now Add new view in Development with the Drupal UI → Export View to GIT → Commit → Deploy to Staging → Deploy to Production. Well enough. It would be cool to get rid of the export step but until now it’s not worth the trouble.
Views were also the area we hit the limits of what we can do with Drupal. We needed to implement more complex requirements where the standard view-queries weren’t flexible enough. I’ve mentioned our internations module above and that’s also the place where we alter some view queries to fullfil more complex use cases. The hook
hook_views_pre_execute() allows you to override queries with Drupal’s query API (which is most likely the weirdest query API I’ve came across, but you too will get used to it).
We also reached a point where the default remote calls weren’t enough. The concept of “is content available for your community” is pretty central for our internal content integration as we decide a lot of things based on the answer to that question. Content Availability is a first class concept in our application’s content domain and we need to ask Drupal quickly what’s the matter with it. To do so, we added a custom API call to let Drupal answer that question. This can be done by extending the services modules using
hook_services_resources() to register a custom remote call.
We did two minor version upgrades since we started. Both went flawlessly, it’s really as simple as
git remote add upstream http://git.drupal.org/project/drupal.git && git fetch --all && git merge <upstream tag>. After committing the merge our build pipeline picks up and triggers our integration tests. The beauty of an untouched core.
We still do it more or less like I’ve said before, but to make deployment easier we automatically deploy schema changes. To deliver more complex features we now have a custom module to customize view queries and to provide a custom API call.