3

If I release a new version of a module, and want to include new configuration in the new version (particularly new fields, and updates to views to rely on those fields) by either making Drupal update the config.whatever.yml files, or writing something in hook_update_N() that will install them, how could I do it? I would want to make sure it only installs the new fields if they don't already exist, since I would want to include the fields' yaml files.

Or, should I require features and use that for adding new fields?

It's confusing to me, because I want to include a config.yml that has the most recent config information, right? Yet, I want to update anyone already using the module by installing the new fields that they don't have.

EDIT 2:

Okay, no, never mind. Don't use the below code. I thought it worked, but really the fields were just installed via the yml files when I installed the module. I don't know why I didn't realize that would happen. My update function never really ran. When I retried it the correct way, it failed, because FieldConfigStorage can't be loaded in this way. I still don't know how to install fields in a way that will create the tables.

EDIT:

The code resulting from Berdir's example:

// Don't forget to include a use-statement if you haven't already:
use Symfony\Component\Yaml\Yaml;

function some_module_update_8101() {
  $message = "";
  if ( !FieldConfig::load('example_field') ){
    $config_path = drupal_get_path('module', 'some_module') . '/config/install/field.field.node.some_node_type.field_example_field.yml';
    $data = Yaml::parse($config_path);
    \Drupal::configFactory()->getEditable('field.field.node.some_node_type.field_example_field')->setData($data)->save(TRUE);
    $message .= "FieldConfig installed for module some_module.\n";
  }
  else {
    $message .= "It didn't work!\n";
  }
  if( !FieldConfigStorage::load('example_field') ){
    $config_path = drupal_get_path('module', 'some_module') . '/config/install/field.storage.node.field_example_field.yml';
    $data = Yaml::parse($config_path);
    \Drupal::configFactory()->getEditable('field.storage.node.field_example_field')->setData($data)->save(TRUE);
    $message .= "FieldConfigStorage installed for module some_module.\n";
  }
  else{
    $message .= "That didn't work either!\n";
  }
  return $message;
}
  • 1
    edited to include "use Symfony\Component\Yaml\Yaml;" statement – aaronbauman Mar 1 '17 at 20:32
4

You can parse and load the yaml file yourself, something like redirect_update_8003:

/**
 * Creates the new default redirect view.
 */
function redirect_update_8103() {
  $message = NULL;

  // Only create if the redirect view doesn't exist and views is enabled.
  if (\Drupal::moduleHandler()->moduleExists('views') && !View::load('redirect')) {
    $config_path = drupal_get_path('module', 'redirect') . '/config/install/views.view.redirect.yml';
    $data = Yaml::parse($config_path);
    \Drupal::configFactory()->getEditable('views.view.redirect')->setData($data)->save(TRUE);
    $message = 'The new redirect view has been created.';
  }
  else {
    $message = 'Not creating a redirect view since it already exists.';
  }
  return $message;
}
  • Woah! That worked! Not only did it put the config in the DB, but it also created the necessary tables for the Field. I guess I was surprised because when doing drush config-import on new fields, it doesn't do that. I logged an issue just in case they aren't avoiding doing that on purpose for some reason. link to issue And, I've edited my question to include the code I used. – RaisinBranCrunch Mar 15 '16 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.