Jun 11 2018
Jun 11

I volunteered to carry out the migration for the new ComputerMinds site as migration was one of the very few areas of Drupal that I hadn’t delved into thus far. With Drupal 8 becoming more and more popular, now was a great opportunity to learn the migration ropes. Luckily, Drupal 8’s migration has greatly improved since Drupal 7 so my life was made somewhat a little “easier”!

This article will be aimed at some of my finds and processes, rather than a “How to do a D8 migration”.

Since our new site was very different to our old one in terms of content, we had to be quite choosey in exactly what was needed. We decided that we only really needed the articles; pretty much everything else was a fresh start. We would be manually carrying over users; as that would be too little work to warrant writing a migration for.

In order for us to get our articles over from the old site, we would need to migrate the current taxonomy terms, URL aliases (this would come back to bite me hard!), files and last but not least, the article nodes themselves. Migrating just a node seemed simple enough, but you quickly forget that it is more than just a node. All the stuff attached to the node has to be carried over.

Modules like Migrate plus and Migrate tools are great additions to the migration family and I can highly recommend them; they make life so much easier! Migrate plus “basically” writes the migration for you :)

With Migrate plus doing the bulk of the work for me, the only PHP code I needed to write was to map our old User ID’s to the new ones, so original authors would be retained. Otherwise I could take all the credit for every single article ComputerMinds has ever written in the past (mwahah!). This can be easily achieved using a simple process plugin.

/**
 * This plugin will tie a piece of content with an existing user.
 *
 * @migrateProcessPlugin(
 *   id = "user_id_mapper"
 * )
 */
class UserIdMapper extends ProcessPluginBase {
  
  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    
    $mapping = [
      'oldID' => 'newID',
    ];
    
    if (!empty($value)) {
      $value = $mapping[$value];
    }
    
    return $value;
  }
}

We had some term reference fields, and like Drupal 7, Drupal 8 will reduce your potential workload - it creates taxonomy terms for you if those terms are missing from your new site. Nice and easy.

The biggest remaining hitch was extracting the three components from a body field. These are value, summary and format. Summary and format were fairly straight forward, but attaining the value component was a real pain (the code below will show you otherwise). Straight away you’ll notice inconsistencies with the “keys”. I would have expected the format to have been body/value, body/summary and body/format, but alas this was not the case.

body: body
body/summary:
  source: teaser
body/0/format:
  plugin: static_map
  source: body/0/format
  map:
    markdown: markdown
    full_html: basic_html
    filtered_html: restricted_html

This took a few painful hours to debug and figure out, to this day I still do not know why! At least this being documented here can save others some pain and time.

With all migration finished and the site ready to be shipped out, what came apparent is that (as mentioned very briefly earlier) I had not accounted for some URL aliases (I had used a process plugin to pinch only the aliases we needed). I’d assumed, yes assumed (naughty developer), that ALL articles had the SAME URL path auto pattern. Big, big boo boo. What I didn’t know was that some articles on our old side had been migrated from an even older site and these article URLs came in all shapes and sizes; shapes and sizes that do not match our current path auto pattern. I’ve been fixing redirects and 404’s since :)

Lesson of the day

Do not ASSUME everything is the same. Do go check everything is how you expect it to be before migrating content.

May 04 2018
May 04

A super quick blast from the past today; a Drupal 7 based article!

I had some work recently to create a new "setting" variable for one our Drupal 7 multilingual sites, which meant creating multilingual versions of those variables. I soon found out that there is very much a correct way - or order - to achieve this as I got this one very wrong (I had to re-instate my DB!). So here I am writing a very quick guide to help those from my wrong doings.

(This guide assumes you have a multilingual site setup with i18n's Variable translation module.)

Four simple steps to achieve a multilingual variable:

  1. Declare your new variables via hook_variable_info
function your_module_name_variable_info($options = array()) {
  $variables['your_variable_name'] = array(
    'title' => t('Foo'),
    'description' => t('A multi-lingual variable'),
    'type' => 'string',
    'default' => t('Bar'),
    'localize' => TRUE,
  );
}

The options you can set in this hook are well documented - start reading from the Variable module's project page.

  1. Flush the variable cache and get your new variables registered using an update hook. The meat of the update hook is below -- note that this assumes you want all of the possibly-localizable variables to be made translatable:
  variable_cache_clear();
  /** @var VariableRealmControllerInterface $controller */
  if ($controller = variable_realm_controller('language')) {
    $variables = $controller->getAvailableVariables();
    $controller->setRealmVariable('list', $variables);
  }
  else {
    throw new DrupalUpdateException('Could not set up translatable variables. Try manually setting them.');
  }

  1. Create or alter your settings form (I'm assuming it uses system_settings_form() or is already recognised by the i18n/variable systems as a form containing translatable variables) and add your new form elements. Make sure the element(s) are the same as your newly created variable(s) - I use a $key variable to avoid any mistakes there!
$key = 'your_variable_name';
$form[$key] = array(
  '#type' => 'textfield',
  '#title' => t('Foo'),
  '#default_value' => variable_get($key, 'Bar'),
);

Head over to /admin/config/regional/i18n/variable or your settings form to see your new multilingual variable in all it's glory!

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