Latest Blog Posts

Drupal Deploy demos

Submitted by timmillwood on Fri, 06/05/2016 - 08:32

Single site content staging with Deploy

This demo shows creating content on a stage workspace then deploying it to live. Once deployed an edit is made on the live workspace and an update is done on stage to pull from live.

Cross site content staging with Deploy

Now with RELAXed Web Services installed cross-site deployments can be done. First replicator users are setup with the permissions to replicate content. These users are added to the Relaxed settings on Drupal 1. A remote is added to Drupal 1 for Drupal 2. The live workspace is updated to set the upstream workspace to Live on Drupal 2. Content is created on Drupal 1 and deployed to Drupal 2. A change is then made on Drupal 2, and Drupal 1 is updated to pull the changes from Drupal 2.

DrupalCon New Orleans 2016 - Proposed sessions

Submitted by timmillwood on Mon, 29/02/2016 - 10:53

This year I have proposed three sessions for the North American DrupalCon based on the topics I have been working on for the last 9 months.

Please take a look, ask questions, make comments, and share.

Building sites with Composer
If you have been keeping up to date with by blog you will notice I have been working a lot with Drupal and Composer. In this session I will share this knowledge and look from a site builders perspective.

Managing and staging your content
In Barcelona and Mumbai, Dick Olsson and I, presented on content management and content staging solutions. We have been continuing to work on improving these solutions and wish to give an updated session in New Orleans.

Drupal is a CMS, so how can we better manage content?
This session will discuss many of the same topic as the earlier session “Managing and staging your content” however from a much more technical point of view, and with the goal of, how do we get this into Drupal core. Drupal 8 now has configuration management, it’s time we also focussed on content management.

Where have the dependencies gone?

Submitted by Anonymous (not verified) on Wed, 03/02/2016 - 14:40

<p>As of <a href="; target="_blank">1:23pm GMT on Febuary 3rd 2016</a> there are no dependencies in the Drupal 8.1.x git branch.</p>


<p>There was no reason to have them there. It makes the repository bigger, and therefore takes longer to download. <a href="; target="_blank">No one</a> <a href="; target="_blank">else</a> <a href="; target="_blank">does it</a>.</p>

<h2>What does it mean?</h2>

<p>Not much really.</p>

<p>If you download Drupal via the zip file or tarball then the packager will run <code>composer</code> so the dependencies will be there for you.</p>

<p>If you submit a Drupal core patch on then DrupalCi testbot will run <code>composer install</code>.</p>

<p>It’s only if you clone Drupal 8.1.x or higher directly from git, you will need to run <code>composer install</code> in the Drupal root directory</p>

<p>Top tip: <code>composer install --prefer-source --no-interaction</code> can often be quicker.</p>

Composer dependencies in Drupal contrib

Submitted by Anonymous (not verified) on Fri, 22/01/2016 - 11:51

<p>Drupal 8 is out, Drupal 8.1 will be out before we know it, but it seems contrib is still catching up. One question that seems to keep coming up is around installing a Drupal 8 module. In this post I will look at the different ways to install a module and resolving dependencies.</p>

<p><a href="; target="_blank">Deploy</a>, <a href="; target="_blank">Search API Solr Search</a>, and <a href="; target="_blank">Commerce</a> are just a few of the modules with Drupal 8 releases that require dependencies loaded via composer. This means you can’t just download the module’s ZIP file, unzip it in your modules directory, and enable it. You need to install the dependencies.</p>

<p>One simple way to do this is the <a href="; target="_blank">Composer Manager</a> module. This module has <a href="; target="_blank">extensive documentation</a> on how to use it. Essentially what it does it merge the composer.json that ships with core and the composer.json files from all the contrib module you have, then downloads the dependencies. You may notice that this will also update core dependencies, but this is a good thing! The core composer.json has been written in such a way that it won’t introduce API breaking dependencies and only uses stable releases. So you will benefit from any bug fixes or security fixes rolled out in these dependencies before they’re rolled out with Drupal.</p>

<p>The two other ways we’re going to look at involve directly using Composer.</p>

<p><strong>Just the dependencies</strong><br/>
It’s possible to carry on installing Drupal modules exactly as you always have, download the zip or tarball, then unzip it into your modules directory. As mentioned earlier this will not install the dependencies, therefore you will need to look inside the module’s composer.json file, see what the dependencies are, and install them manually. Let’s take Deploy module as an example, this depends on the dev-master version of <a href="; target="_blank">relaxedws/replicator</a>. So, go to your Drupal docroot and run the command <code>composer require relaxedws/replicator:dev-master</code>. This will add relaxedws/replicator to Drupal’s composer.json, download it, and put it in the vendor directory ready for the module to make use of. This will not change any other other dependencies you have. Then to update the dependencies you can either run <code>composer update</code> to update relaxedws/replicator and all core dependencies or <code>composer update relaxedws/replicator</code> to just update the relaxedws/replicator package.</p>

<p><strong>The module too</strong><br/>
If you install all you Drupal modules via composer, all of the dependencies will automatically be installed too. First you will need to add a new repository, so run <code>composer config repositories.drupal composer <a href="; target="_blank"></a></code&gt; in your Drupal docroot, this will add the <a href="; target="_blank"></a&gt; repository to your drupal composer.json. Now you can install any module from via composer. So going back to the example of Deploy you can run <code>composer require drupal/deploy:8.1.0-alpha5</code> in your Drupal docroot and it will install Deploy in the modules directory. It will also install key_value, multiversion, and relaxed, which are all Drupal modules required by Deploy. Furthermore it will install relaxedws/replicator as we know is a PHP package needed for Deploy, and doctrine/couchdb which is a PHP package needed for releaxedws/replicator.</p>

<p>I hope this helps those confused what to do with Drupal 8 modules that have composer dependencies. Now go do the smart thing, rebuild your site using Composer!</p>

Putting the M back in CMS

Submitted by Anonymous (not verified) on Mon, 21/12/2015 - 14:16

<p>For the last 6 months I’ve been helping <a href="; target="_blank">Dick</a> and <a href="; target="_blank">Andrei</a> with a number of Drupal modules to enhance the management of content.</p><p><b><a href="; target="_blank">Multiversion</a></b></p><p>This module enhances the Drupal core Entity API by making all content entities revisionable. Revisions are enabled by default and not optional. This means that edits to users, comments, taxonomy terms etc are created as new revisions.</p><p>Another ground breaking advance is that deleting any of these entities now just archives it. Delete is a flag in the entity object, and just like any other update, it creates a new revision.</p><p>The concept of workspaces has also been added, this allows for a new instance of the site, from a content perspective, can be created. An example use case for workspaces would be to have a dev, stage and production workspace, and move content between them as it gets promoted through the workflow.</p><p><b><a href="; target="_blank">Trash</a></b></p><p>Now that deleting content entities just means a new revision marked as deleted we need a way to recover or purge them. The trash module is a UI on top of Multiversion allowing users to do just this.</p><figure class="tmblr-full" data-orig-height="707" data-orig-width="995"><img src="…; data-orig-height="707" data-orig-width="995"/></figure><p><a href="; target="_blank"><b>Relaxed Web Services</b></a></p><p>Drupal 8 has always been about <a href="; target="_blank">getting off the island</a>, Relaxed Web Services furthers this by getting content off the island. It uses Drupal core’s REST API to expose CouchDB compatible endpoints. This means that replicating content is just a case of using CouchDBs replicator. Then creating a <a href="; target="_blank">decoupled Drupal site</a> is as simple as using <a href="; target="_blank">PouchDB</a>.</p><p>This works really well with Multiversion’s Workspaces, where each workspace is exposed as a separate CouchDB database.</p><p><a href="; target="_blank"><b>CouchDB Replicator</b></a></p><p>So that we don’t need to depend on CouchDB for replication, the replicator has been rewritten in PHP. This will allow us replicator content from within Drupal or even via Drush.</p><p><b><a href="; target="_blank">Deploy</a></b></p><p>There is a long history for Deploy in Drupal, but now in Drupal 8 it’s little more than a UI for the PHP based CouchDB replicator. It allows replication of content between workspaces, between Drupal sites, and between CouchDB databases.</p><p><a href="; target="_blank"><b>Mango</b></a></p><p>Something we’re currently working on is Mango, inspired by MongoDB and based on <a href="; target="_blank">Cloudant’s implementation for CouchDB</a>. Mango will allow querying for content entities over the Relaxed Web Services API. This is going to be very interesting to those creating decoupled sites because PouchDB supports the same querying API.</p>

Deploy: How it'll work in D8

Submitted by Anonymous (not verified) on Tue, 20/10/2015 - 16:40

<p>Over the last 7+ years working with Drupal, one question always asked by clients is, how do I copy my content from staging to production? Generally the answer has been, “Don’t! Just add it on production”. Another option is to use the deploy module, which allows for the deployment of content between environments. </p><!-- more -->

<p>Drupal core has changed greatly in Drupal 8, the deploy module is following suit.</p><p><b><a href="; target="_blank">Multiversion</a><br/></b>The multiversion module will be the foundation of all this change. It introduces three big changes to the way content is managed in Drupal.<br/>Workspaces - All content is associated with a workspace, you can have multiple workspaces and switch between them. Think of them much like branches in version control systems such as git.<br/>CRAP - Create, Read, Archive, and Purge. This is an alternative to CRUD (Create, Read, Update, and Delete). It means that in multiversion no content is deleted and everything is a new revision. Deleting an entity will just archive it, flagging it as deleted.<br/>Revisions for everything - All content entities are revisionable with multiversion module. This means blocks, user, comments etc all have revisions.</p><p><b><a href="; target="_blank">Relaxed</a></b><br/>The relaxed module is a RESTful API which is aligned to the CouchDB API. It exposes each workspace as a Couch database. This allows it to be replicated to another Drupal site running relaxed, to a native CouchDB database, or to something else that uses the same API, such as PouchDB.</p><p><b><a href="; target="_blank">Deploy</a></b><br/>Finally the deploy module. This is now just a UI module as all the the content deployment is handed with external projects. The relaxed module exposes the API needed, a PHP based <a href="; target="_blank">CouchDB replicator</a> uses a PHP based <a href="; target="_blank">CouchDB client</a> to replicate / deploy the content.</p><p>The current plan is to have a “Deploy” button in the Drupal toolbar, this will open a modal where you can choose which site you want to deploy to and which workspace you want to merge into. It will be possible to deploy to a workspace on the current site. For example, a staging site may have two content editors, both working on different workspaces, then can then deploy / merge their content to the default workspace. This default workspace can then be merged up to the production site’s default workspace.</p><p>Tagging is also an idea being worked on. It will allow you to tag a workspace at a current point in time, then continue to edit content. When deploying from a tag it will only merge up changed until the tag was created.</p><p>These are big changes for the deploy module, but something that will make the content workflow a lot easier.</p>

How can we know if a page in Drupal 8 has changed?

Submitted by Anonymous (not verified) on Fri, 02/10/2015 - 15:27

<p>This was a question I got from a client. So I set to work on finding a solution to alert the team who needed to know when a page has changed.</p><p><b>TL;DR</b>: <a href="; target="_blank">CacheTags</a>.</p><!-- more --><p>Drupal has an awesome caching layer. It makes use of cache tags, these tags can be invalidated when something changes. For example if this is a view called “frontpage”, it would output the cache tag &ldquo;view:frontpage&rdquo;. This view lists a bunch of nodes, each with their own cache tag, &ldquo;node:1&rdquo;, &ldquo;node:2&rdquo; etc. When node 2 is edited, it’s cache tag and the frontpage view cache tag would be invalidated.</p><p>Taking this into account if we want to know what pages have changed, we need to know what cache tags the page has, then what cache tags have been invalidated.</p><p>The client already has a crawler to check their sites, this can look at the <code>X-Drupal-Cache-Tags</code> header and capture the cache tags the page has. So all we need now is a way of telling the crawler what cache tags have been invalidated.</p><p>Welcome to the <a href="; target="_blank">CacheTag Notify</a> module. This has a simple settings page where an endpoint URL can be added. Then every time a cache tag is invalidated it gets POSTed to the endpoint as a JSON string. The crawler will then need to to lookup which pages are using the invalidated cache tags, then it knows which have changed.</p><p>The CacheTag Notify module works by adding <code>CacheTagsInvalidator</code> service. The <code>invalidateTags</code> method is passed an array of invalited tags, this is then POSTed to the endpoint url using Guzzle. Overall a very, very simple, but effective solution.</p>

Planning for CRAP and entity revisions everywhere in core

Submitted by Anonymous (not verified) on Wed, 23/09/2015 - 07:46

<figure class="tmblr-embed tmblr-full" data-provider="youtube" data-orig-width="459" data-orig-height="344" data-url=""><iframe width="540" height="405" id="youtube_iframe" src=";enablejsap…; frameborder="0"></iframe></figure><p>At DrupalCon Barcelona this year I presented with <a href="; target="_blank">Dick Olsson</a> outlining a plan for CRAP (Create Read Archive Purge) and revisions (on all content entities) in core.</p><!-- more --><h2>Phase 0</h2><p><b>For Drupal 8.0.0</b><br/>Enable revisions by default (<a href="; target="_blank"></a&gt;) on content types in the standard install profile and when creating new content types.</p><h2>Phase 1</h2><p><b>For Drupal 8.1.0</b></p><ul><li>Improve the Revisions API performance, some of this will come from moving elements from the multiversion module into the entity API.<br/></li><li>Enable revisions by default for all content entity types. So not just nodes anymore but blocks, comments, taxonomy terms etc.</li><li>Introduce a revision hash, parents and tree. Each revision needs to have a parent so you know where it’s come from, each parent can have multiple child revisions.</li><li>Data migration - Moving all 8.0.0 sites to 8.1.0 will mean moving their data to the new revision system.</li></ul><h2>Phase 2</h2><p><b>For Drupal 8.2.0</b></p><ul><li>Remove the ability to not have revisions. To simplify the API and the data stored it makes sense to remove the ability to disable revisions. This will allow us to remove all the conditional code around if an entity has a revision or not.<br/></li><li>Delete is a new flagged revision. When deleting an entity a new revision will be created and this revision will be flagged as deleted. This is the archive element of the CRAP workflow.</li><li>Introduce purge functionality. There may be times when an entity needs to be completely deleted.</li><li>Commit trash module to core. Trash is just a UI for the delete flag. It displays all entities marked as deleted. It then allows these to be restored by creating a new revision not flagged deleted, or purged by removing the entity.</li></ul><p>Simple right?</p>