Skip to main content

We could add default content to Drupal core, but what would that mean?

There has been some movement of late around adding some default content to the standard profile.

This was originally reignited by Roy Scholten in his getting something in the box post.

As author and co-maintainer of the default content module for Drupal 8, I wanted to share my thoughts on the potential of adding it to Drupal core.

by lee.rowlands /

The Snowman initiative is not a new one. And no-one would dispute that the 'You haven't got any content' message you see as soon as you install Drupal is a fairly ordinary first experience.

So it makes sense to try and improve that experience by adding some sample content.

We've been talking about it for ten years (yes that is a 5 digit issue number).

However it's not as simple as 'adding default content module to core as an experimental module' and away we go.

Default content is great insofar as it doesn't rely on any modules other than those provided by core.

But it's a two-edged sword.

It works by looking for default content in the form of json files inside a module's folder structure. These files live in content/{entity type} inside the module.

This content is stored in hal+json format as output by core's Rest and HAL modules.

The content is imported during hook_modules_installed which fires when a module is installed, but before its configuration is imported.

Issue 1

This is one of the first hard problems. Adding default content to standard profile would mean that none of the profile's configuration would have been imported yet. Which would result in exceptions/partial imports. You cannot import content into the page content type if it does not exist.

Profiles that make use of default content do things a little differently.

They put their configuration in a module which the profile depends on.

They put their default content in another module, which depends on the configuration module. For an example, see how aGov does it.

That way the install order happens like this:

  1. The configuration module is enabled and all the content types and fields etc are created
  2. The default content module is enabled, creating the content as required. An option to disable this can be added to the installer screen steps, since not everyone wants to start with default content.
  3. The install profile is enabled. It is always enabled last - this is non-negotiable.

This isn't how the current standard profile is structured - so there is considerable work to be done to reorganize how the configuration is structured.

Issue 2

The second issue here is that the default content module relies on the Rest, HAL and serialization modules in core. The HAL module provides the hal+json format. The Rest module provides the link managers that allow reverse resolving of embedded links to entity types and fields. The serialization module provides the serializer service which handles normalizing entities to arrays and then serializing them to a given format - in this case hal+json.

The issue is that you shouldn't need to enable these three modules just to import default content. If your site isn't providing an API in the form of Rest endpoints, you shouldn't need to have them available just to install default content. Those who build Drupal sites for a living normally steer clear of enabling modules they don't need. Comment module in standard profile is a good example of something that core enables by default but many sites don't use. Its the same issue here.

To resolve this, we need to do a lot of shuffling.

There is a valid argument that the serialization module is critical to core's functionality and hence should be disolved into the \Drupal\Core namespace instead of \Drupal\serialization. Being able to turn our data objects such as entities, field item lists and field items into arrays and back is a genuine core piece of Drupal functionality. We should support this in the low-level plumbing. Particularly for things like the MapItem typed data type. Using PHPs built in serialize/unserialize to convert our objects to and from arrays is a bad idea - just ask the PHP maintainers - this functionality was added to support user sessions and was never meant to be used the way it is.

So bringing serialization services into core resolves one of the three dependencies. The issue for that is here.

The next dependency is the HAL module. The key piece of functionality it provides is the embedding of entity references in the body of the serialized entities during normalizing. For example, if you normalize a node, you also get a reference to the author embedded - with the link done by UUID so it can be de-referenced. The large parts of default content module are concerned with sorting this dependency tree so that content is imported in the right order, with the dependencies intact. This is probably the easiest bit to swap out - and support for this has existed in the serialization module since Drupal 8.1.x - Default content module hasn't been updated to support it yet - because we don't want to break people's existing exports.

This leaves the Rest module as the final dependency. The main pieces it provides are the link manager services that allow generating canonical links to referenced/embedded entities and then de-referencing these into entity type, field name and bundle information during denormalizing. E.g. When you normalize a node, the author reference is stored using a URI that contains information about the entity type, the bundle and the field name. During denormalizing (which happens on content import) this information can be extrapolated so things end up in the right place. Fortunately we have an issue to move these out of the Rest module.

Issue 3

The next issue is perhaps the biggest one. There are shortcomings in core's normalizers. The main ones are around fields that resemble entity references but really aren't and fields with calculated values. And then there's normalizing files and images. The issues here are as follows:

Issue 4

The final issue is probably the most contentious. Just because we could add default content to the standard profile - does that mean we should? The standard profile isn't a product. A product is created to solve a problem or fill a need. The standard profile does not do that. It is a random assortment of features that once resembled a blogging site but no longer does.

We need a real product. Or several products. This was the basis of the platform initiative and also the Snowman group. Personally I feel that is a better use of our limited time and resources. Much of the platform initiative was put on hold while we focussed on the unofficial framework initiative. This was a five-year effort focussed on untangling the spaghetti like nature of core. We got a long way towards that goal.

Perhaps now its time to revisit the platform initiative.

I have some thoughts around how this might look - but will cover those in a future post.

Posted by lee.rowlands
Senior Drupal Developer



Comment by Jeff Eaton


I agree that default content in the Standard Profile is a bad idea — and the complexities that you've outlined are important ones to consider.

The use case for "default content" is actually pretty narrow, but it's also high-profile. Simply forklifting Default Content Module into core won't solve our problem; ultimately, what we need is a tool that allows modules *or* profiles to optionally install content after their other setup steps. That was where Snowman stalled — that, and the difficulty of chasing Core 8's rapidly changing APIs circa 2014.

Comment by James Williams


I'm confused. In issue 1, you say "Adding default content to standard profile would mean that none of the profile's configuration would have been imported yet. ". But, from looking at the code in core's ModuleInstaller, default config from a module's config/install directory is imported _before_ invoking hook_modules_installed() and therefore prompting default_content to import content from the module being installed.
Having given it a go, this seems to be the case in practise anyway, so I don't think 'Issue 1' is an issue at all?

Next up, issue 3... seems to solve the point about term parents?

Comment by Daniel


Personally I think this is what distributions should do if people want something that works out of the box. Core doesn't showcase what is good about drupal and this is what the first critisism would be.

Comment by Wim Leers


Thanks for calling out those serialization/normalization/REST issues. I made them top priorities to fix for Drupal 8.3: (And hopefully some of them can be backported, if they're straight bugfixes that don't require API changes/additions.)

Comment by lee.rowlands


No worries, I will try and keep them moving along

Comment by Alec Eiffel


It's seems so obvious that I'm surely missing something, but here's my 2c : why don't add a new hook_profile_post_install (or hook_module_post_install) and use the migrate module to import content ?

Comment by lee.rowlands


Same sorts of reasons as shown here. We don't want additional dependencies if possible. It needs to be lower level. Also, migrate is experimental.

However, if we could enable migrate, import and disable migrate in the install process, that'd be a fine approach.

Comment by Ramon Vilar


Hi Lee
We have just published a Drupal 8 version of our Migrate dfault content module ( We use it actively in all of our developments to provide default content for testing purposes on every demo we do with our clients. It is as simply as enable this module (and some dependencies) and execute a drush command. Maybe can help in your investigation.

Comment by Drupleg


Example "default content" is the ONLY reason I went with Joomla over Drupal in 2007. I ran into much pain and frustration with Joomla over the years, eventually coming back and reevaluating Drupal in late 2010 (and never looking back).

The point being - I don't think I'm alone in having begun with Joomla because it offered an example "website out of the box". I so wish Drupal at that time would have had example content, then I'd have never had these Joomla battle scars, and my web development career would have been that much further along had I started with Drupal way back when.

--Tony G.

Comment by lee.rowlands


We had a meeting during Drupalcon to hatch a battle plan. More to come shortly.

Comment by Moshe


Any URL for that battle plan? Please?