4

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
  • 1
    edited to include "use Symfony\Component\Yaml\Yaml;" statement Commented Mar 1, 2017 at 20:32

1 Answer 1

7

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

use Symfony\Component\Yaml\Yaml;

/**
 * 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::parseFile($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;
}
2
  • 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. Commented Mar 15, 2016 at 22:18
  • 1
    Yaml::parse works differently in newer version of the Symfony Yaml Component (symfony/yaml). This parse method waits for a yaml string as a parameter. This can be used on the following way: $data = Yaml::parse(file_get_contents($config_path)); There is another method, which works with file path: $data = Yaml::parseFile($config_path); Commented Oct 8, 2019 at 12:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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