Export content to CSV with Drupal 8

The need to export the contents of a Drupal 8 project is a recurring need, whether for analysis purposes or for mass updating with a concomitant import process. We have several solutions with Drupal 8, each of which has advantages and disadvantages, whether in terms of the content types that can be exported, the options for exporting column headers and values, the level of access rights required and the highly variable configuration options. We will present here a new Entity Export CSV module that seems to be able to respond to many use cases.

Another new CSV export module?

We have many solutions to set up a CSV export on a project. Let's try to list some of them without wanting to be exhaustive.

The Views Data Export module, as its name indicates, is based on the Core Views module to configure and set up CSV exports. Using Views we can then configure an export for any Drupal 8 entities, usually for a particular bundle. We then need to configure as many views as we need to export and some limitations may appear when it comes to exporting multiple fields. Setting up CSV export with this module requires administrative rights to create and manage views of a Drupal 8 project, with some understanding of how Views works. It is therefore not really intended for end users.

The Content Export CSV module allows you to quickly export the nodes of a Drupal 8 site. Its configuration options are very limited, especially the choice of exported fields and their values, in addition to the fact that only nodes can be exported with this module. Conversely, this module can be used directly by end users.

The Entity Content Export module allows many configuration options. It can export all Drupal 8 content entities and the exports of each entity can be configured based on the entity view modes, including field formatters that we can select and configure for a given content export. However, it requires a consequent initial configuration, with very high administrative access rights, at the level of each entity bundle that we want to make exportable.

For the needs of a Drupal web factory project, each of its solutions could partially but not totally meet these requirements. In particular because it was not possible to know in advance what content types or what entity type it was necessary to be able to export, how the content type was configured and used (in the case of generic content types customizable by instance of the web factory) and especially because any configuration and implementation of these CSV exports had to be able to be done by end users, without any particular knowledge of Drupal, nor any access rights on the configuration of a Drupal 8 project.

Introduction of the Entity Export CSV module

The Entity Export CSV module was created to meet these challenges.

  • Be able to export any content entity from Drupal 8
  • Be able to select which fields are exportable for each entity and each bundle
  • Be able to configure how each field of an entity is exported
  • Be able to configure field by field their export behavior when multiple fields are involved (export in a single column with separator and export of each value in a separate column)
  • Be easily customizable for the export of a particular field, with a specific business need
  • Be usable by an end user without special administrative rights on the configuration of a Drupal 8 project (Views, Entity View Mode, etc.).

In terms of architecture, in order to meet these challenges, Entity Export CSV relies on :

  • A simple configuration page that allows you to select which content entities will be exportable from among the content entities present in a project and, if necessary, to limit them to one or more bundles, and also to limit (or not) the fields of these entity bundles that will be exportable.
  • A simple export page allowing, on the basis of the initial selection configuration, the entity to be exported, then to configure for each field whether it should be included in the export and if so how it should be exported

Detailed presentation of how Entity Export CSV works

Once the module is installed, as indicated above, the first step is to configure the exportable entities, which will be accessible in the export page.

The configuration is quite simple. For each entity type available on the project we select the ones we want to make exportable, and we can limit the bundles by entity type that will be exportable.

Entity Export CSV settings

Then for each entity and bundles enabled, we can also limit the fields that will be exportable, this for example in order to not overload the export page with the so-called technical fields of an entity (uuid, revision, or any other field added on the entity that does not contain any content as such).

Entity Export CSV settigns details

Then just go to the actual CSV export page.

page export CSV

Users can configure for each field, if it is to be included in the export, how the column header will be populated (field readable name or system name), the number of columns to be used for multiple fields as well as the export format to be used for each field.

Entity Export CSV page export

Once the configuration is finished, the user can save this configuration so that he does not have to make another configuration during a next export. Each configuration is saved for an entity type, a bundle and per user. A programmed evolution will be to be able to configure configuration exports for each entity type and bundle, in an unlimited way, and then use these export configurations here as a reusable template.

Entity Export CSV save export settings

Each field can be configured differently at the level of the column header used for its export, and at the level of the exported value. To do this, the module has a FieldTypeExport Plugin system that allows you to easily create configurable and/or specific field exports. For example below the "Modified" field is configured with the Timestamp export plugin which exposes as an option the date formatting.

Entity Export CSV timestamp export

Another basic plugin provided by the module allows to configure how Entity Reference type fields are exported. For example if we want to export the ID of the referenced entity or its label, and for the case of a multiple field the number of columns to be used to export the values.

Entity Export CSV entity reference export

Extension of the module Entity Export CSV

One of the challenges the module meets is to be easily extensible and/or customizable. Rare are the Drupal 8 projects where a field does not fit into a generic box and requires special treatment.

The Entity Export CSV module relies on a Plugin system to export all fields and can therefore be easily extended by a Drupal 8 developer to support any type of special case or fields created by contributed modules (for example, the module includes a Plugin for the fields of the Geolocation module and the Address module).

To create a Field Export Plugin, a FieldTypeExport Plugin must therefore be created in the src/Plugin/FieldTypeExport namespace of any Drupal 8 module.

The annotations of this plugin allow you to control certain behaviors of the Plugin and its availability. Let's look at these annotations with the example of the Geolocation plugin included in the module.

namespace Drupal\entity_export_csv\Plugin\FieldTypeExport;

use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\entity_export_csv\Plugin\FieldTypeExportBase;
use Drupal\Core\Field\FieldItemInterface;

/**
 * Defines a Geolocation field type export plugin.
 *
 * @FieldTypeExport(
 *   id = "geolocation_export",
 *   label = @Translation("Geolocation export"),
 *   description = @Translation("Geolocation export"),
 *   weight = 0,
 *   field_type = {
 *     "geolocation",
 *   },
 *   entity_type = {},
 *   bundle = {},
 *   field_name = {},
 *   exclusive = FALSE,
 * )
 */
class GeolocationExport extends FieldTypeExportBase {

  /**
   * {@inheritdoc}
   */
  public function getSummary() {
    return [
      'message' => [
        '#markup' => $this->t('Geolocation field type exporter.'),
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state, FieldDefinitionInterface $field_definition) {
    $configuration = $this->getConfiguration();
    $build = parent::buildConfigurationForm($form, $form_state, $field_definition);
    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function massageExportPropertyValue(FieldItemInterface $field_item, $property_name, FieldDefinitionInterface $field_definition, $options = []) {
    // Stuff to format field item value.
  }

  /**
   * {@inheritdoc}
   */
  protected function getFormatExportOptions(FieldDefinitionInterface $field_definition) {
    $options = parent::getFormatExportOptions($field_definition);
    return $options;
  }

}

The annotations of a FieldTypeExport plugin are :

  • weight: the weight of the plugin. The plugin with the highest weight will be the plugin selected by default if more than one plugin is available for a field.
  • field_type: the type of field to which the plugin applies. Multiple field types can be specified if necessary. This option is mandatory.
  • entity_type: it is possible here to limit the plugin to only certain entity types. Leave empty and the plugin will be available for the field type on any entity type.
  • bundle: it is possible here to limit the plugin to only certain entity bundles. Leave empty and the plugin will be available for the field type on any bundles
  • field_name: here it is possible to limit the plugin to one particular field. Leave empty and the plugin will be available for the field type on all fields of that type.
  • exclusive: this option if set to TRUE will make this plugin exclusive, i.e. all other plugins available for this field type will no longer be visible. Useful if you want to limit the options available to export a specific field by a particular field. Default value is FALSE.

You can then override all the methods available on the Base Plugin in order to customize the export rendering of the field. In particular you can expose new configuration options, and of course implement the massageExportPropertyValue() method which is in charge of formatting the export of a field instance.

To you exports

The Entity Export CSV module provides access to advanced export features for end users who may not have extensive knowledge of Drupal or advanced configuration rights. It allows you to quickly provide export functions on any entity type, while remaining completely independent of a project configuration and as such can be integrated on any type of project, including webfactory projects. The simplified interface that it provides to users is not to the detriment of more or less complex use cases, thanks to its Plugin system that allows all business needs that are a little specific to be handled at very little cost.

Need a CSV export? Think about Entity Export CSV!

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web