title: How to troubleshoot entity error

text:
# Question
Title: How to troubleshoot entity error
How can I tell which entity is throwing this error (on all pages)?

> TypeError: Argument 4 passed to Drupal\views\Plugin\views\display\Block::\__construct() must implement interface Drupal\Core\Entity\EntityManagerInterface, instance of Drupal\Core\Entity\EntityTypeManager given, called in /usr/local/var/www/hifldlive/web/modules/contrib/ctools/modules/ctools\_views/src/Plugin/Display/Block.php on line 54 in Drupal\views\Plugin\views\display\Block-\>\__construct() (line 69 of core/modules/views/src/Plugin/views/display/Block.php).

I have run composer update on an un-familiar site.
Composer update, `drush updb` and `drush cr` all run without errors.
There are about 20 migration tables generated.

I'm guessing I need to roll back the composer update (since it trashes the site), fix the data, then re-run the composer update.
I stuck on how to identify what to fix.
It is no problem to roll back.

I can't where entities are stored in the database. I also don't see entities in the admin pages.

I can use Drupal Entity API in a custom module, but the site won't load on any page.

# Answer
> 2 votes
This is not a problem with entities stored in the database, it is is a version conflict between the module Ctools and Drupal core.

When you install the current version of Ctools with `composer require 'drupal/ctools:^3.4'` you see that \__construct() is calling the parent constructor providing a parameter EntityTypeManagerInterface.

*modules/contrib/ctools/modules/ctools\_views/src/Plugin/Display/Block.php*

```
  /**
   * Constructs a new Block instance.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity manager.
   * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
   *   The block manager.
   * @param \Drupal\views\Plugin\ViewsHandlerManager $filter_manager
   *   The views filter plugin manager.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The current request.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, BlockManagerInterface $block_manager, ViewsHandlerManager $filter_manager, Request $request) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $block_manager);

    $this->filterManager = $filter_manager;
    $this->request = $request;
  }

```

This requires that your core version has this code change:

https://git.drupalcode.org/project/drupal/-/commit/12d7ed53087a469ef8f87476c2849f7b24bfbbb7#140e79af0797f7f25fd1f20e2ebc697be118fea6

So you have to make sure you are using a current core version 8.8.x or you have to downgrade Ctools to a version not having this change.

---
Tags: views, 8, composer
---


# Question
Title: How can I prevent user data being cached and showing the wrong username?
I have built a Drupal 8 site, we are showing the user name and last name on a block, this is my code on preprocess from .theme file:

```
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

$firstname = $user->get('field_firstname')->value;

$firstname = $firstname;
$variables['firstname'] = $firstname;

```

Then in the block im doing: `Hello {{ firstname }}`

And it shows the last user, not mine. When I do `drush cr` then I get the correct name, why? How can I fix this and already display the right username?

# Answer
You are retrieving the user name from the current context and the user entity, but then you make it a dumb string value to pass it to the template. Include the cache metadata to define where this value is coming from and under which circumstances it could change:

```
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
$firstname = $user->get('field_firstname')->value;

$variables['firstname'] = [
  '#plain_text' => $firstname,
  '#cache' => [
    'contexts' => ['user'],
    'tags' => $user->getCacheTags(),
  ],
];

```

More info https://www.drupal.org/docs/8/api/render-api/cacheability-of-render-arrays
> 2 votes

---
Tags: 8, theming, users
---


# Question
Title: Compare a single value entity reference field to a multi-value entity reference field
The article entity has an unlimited multi-value Taxonomy reference field `field_article_countries` referencing the Taxonomy vocabulary `Countries`and the User entity has a single value Taxonomy reference field `field_user_countries` which referencing the same taxonomy vocabulary `Countries`.

Programmatically, and comparing to one specific Article, I want to load all users that has have their `field_user_countries` value = to one of the values available inside the multi-value Taxonomy reference field `field_article_countries`.

**Example:** Say **Article "ABC"** has the `field_article_countries` with values:

* Paris
* Spain
* London
* Italy

**User "A"** has `field_user_countries` set to:

* Spain

**User "B"** has `field_user_countries` set to:

* Italy

and **User "C"** has `field_user_countries` set to:

* Turkey

I want programmatically, and based on **Article "ABC"**, to load only User A & User B.

**Below is my code:**

```
// Get in array, a list of all "Article Countries" available for the loaded article.
$Article_Countries = $article->field_article_countries->getString();

    // Get Entity Manager to build your query
    $storage = \Drupal::entityTypeManager()
      ->getStorage('user');

    // Get all Users satisfing your conditions
    // For Condition Parameters @See: https://www.drupal.org/docs/8/api/database-api/dynamic-queries/conditions
    $uids = $storage->getQuery()
      ->accessCheck(FALSE)
      //->condition1
      //->condition2
      ->condition('field_user_countries', $Article_Countries, 'IN')
      ->execute();

    // Load all User entities according to their IDs
    $users = \Drupal\user\Entity\User::loadMultiple($uids);

    // Loop through loaded users.
    foreach ($users as $user) {

    // Do something here.

}

```

**The problem** is that only one user is being loaded and not all users !

Any idea what is wrong with my code ?

# Answer
> 2 votes
`$Article_Countries = $article->field_article_countries->getString();`

This returns a string

`->condition('field_user_countries', $Article_Countries, 'IN')`

From the docs, `condition` with `IN` accepts an array.

So, you need `$Article_Countries` to be an array of entity IDs. My first thought was `$article->field_article_countries->referencedEntities()` to get an array of objects, and then foreach them to build an array of IDs, but that's a bit round-the-houses. So I searched for a neater way and found this: http://drupal.stackexchange.com/a/207715/89581 which suggests:

`$ids = array_column($entity->field->getValue(), 'target_id');`

---
Tags: 8, users
---


# Question
Title: Cron error: LogicException : Render context is empty
In a custom module (sel), I have this code:

```
function sel_cron()
{
  $accountSwitcher = Drupal::service('account_switcher');
  $account = \Drupal\user\Entity\User::load(1);
  $accountSwitcher->switchTo($account);

  $query = \Drupal::entityQuery('service_category');
  $dLastExtractionDate = strftime("%Y-%m-%d", strtotime("- 1 week", strtotime(\Drupal::state()->get('sel.NextEmailForNewServices'))));
  $view = views_embed_view('sel_services', 'embed_2', $dLastExtractionDate);
  $view = \Drupal::service('renderer')->render($view);   <--------------------- problem here

  $accountSwitcher->switchBack();
}

```

The expected result of the view is a table but when the result is empty (because of the value of the contextual filter), an unfiltered text ("Nothing to display today. Too bad!") should be displayed instead.
But in this case, I get this error logged:

> LogicException: Render context is empty, because render() was called outside of a renderRoot() or renderPlain() call. Use renderPlain()/renderRoot() or #lazy\_builder/#pre\_render instead. in Drupal\Core\Render\Renderer-\>doRender() (line 243 of /Users/efalzon/Sites/JdP8/web/core/lib/Drupal/Core/Render/Renderer.php).

How to fix that?

# Answer
```
$view = \Drupal::service('renderer')->renderPlain($view);

```

instead of

```
$view = \Drupal::service('renderer')->render($view);

```

was the solution!
Thanks to @Clive
> 3 votes

---
Tags: views, 8, cron
---


# Question
Title: Why are existing entity reference fields not available to add to a media type?
I have a number of existing entity reference fields in my site. The key one is a taxonomy reference field called `field_search_terms`. I would like to add this field to the `Document` media type. However when I go to manage fields for the media type my existing fields are not available.

It looks like I need to create a new field and any search that mixes content and media will need to have two filters.

Why is this limitation in place? Is there an issue I can follow to learn more?

# Answer
I found the resources I was looking for with help from a comment by Clive:

A field can only be used on the same entity type. There is an open issue for this in the queue. According to the issue and my recollection this is a change from Drupal 7. If so it feels like a major regression.

The documentation is also incorrect at the time of this writing.
> 0 votes

---
Tags: media
---


# Question
Title: How do I implement access checks based on referring nodes in the grants system?
Following a suggestion in another thread here I'm trying to rewrite the access restrictions that I developed using `hook_node_access` (and that are working well, so far) in Drupal's grant system (i.e. using `hook_node_access_records` and `hook_node_grants`). I would like to do that for two reasons:

1. I'm worried that the current access checks might become a performance bottleneck, when the number of users grows.
2. I need to use the results of access checks as a filter in views.

Here's a truncated version of my current access checks:

```
function mymodule_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account){
  $type = $node->bundle();
  $user = $account->getAccount();
  $uid = $user->id();

  // only handle the lesson content type
  if ($type === 'lesson') {

    // ...

    // check the user's access to the referring courses
    $courseaccess = FALSE;
    if ($node->hasField('reverse_entity_reference')) {
      $parentcourses = $node->get('reverse_entity_reference')->getValue();
      foreach ($parentcourses as $course) {
        $coursenode = \Drupal\node\Entity\Node::load($course['target_id']);
        // perform access checks for the referring course
        $courseaccess = $courseaccess || ...
      }
    }

    // ...

    // return the result
    if ($courseaccess) {
      return AccessResult::allowed();
    } else {
      return AccessResult::forbidden();
    }
  }

  // ...

}

```

Note that, in essence, I need to **check, whether the current user has access to any of the nodes (*courses*) that are referring to the viewed node (*lessons*)**: That determines, whether the user may access the *lesson*. I'm using *reverse entity references* for that.

As I see it (I'm open to suggestions), there are fundamentally two ways for approaching this. Unfortunately, so far, I have been unable to solve the problems involved. So, in my understanding, I could...

1. Put (more or less) the full access logic into `hook_node_grants`: That would mean, I need to have access to the currently viewed node (*lesson*) in `hook_node_grants` to be able to follow its reverse references to check, whether the user has access to any of the referring nodes. Is that possible? There's no `$node` variable...
2. Put (more or less) the full access logic into `hook_node_access_records`: In that case, the problem is that the hook only gets called (and thus the *lesson* gets updated), whenever the node is saved. So, the access restrictions will be out of date, as soon as a lesson is included in another *course*.

I'm unsure how to proceed at this point. Is it even possible to rewrite this in the grant system? Any other ideas?

# Answer
> 1 votes
Given that we don't have an exhaustive list of requirements & Q&A isn't suited well for long discussions, it will be impossible to definitely say yes.

The grant system isn't designed around any sort idea of hierarchy. Is it possible to rewrite? It depends if you can refactor your existing logic around what the grant system supplies.

You've framed your question as a dilemma, but you really need both hooks to use the grant system:

* `hook_node_grants` need to assign `realm`/`gid` grants that correspond to the `$user` and the available lesson `nid` they can access.
* `hook_node_access_records` needs to fire against a lesson `$node`

So if you can:

* Map the `realm`/`gid` grant keys to match to courses the user has access to (e.g. `mymodule_course_realm`/`123` where `123` some group identifier that maps to a group of users that have course access, thus lesson `nid` access)
* Trigger *lesson* save events upon course updates (e.g. using `hook_node_update`, `hook_node_insert`, etc. to look for update courses, then doing dummy saves on the lesson nodes) so that `hook_node_access_records` can fire against *lesson* nodes that have a changed relationship. (or build custom logic where you insert grants directly via `NodeGrantDatabaseStorage::write()`)

You can probably refactor around the hooks the grant system provides.

---
Tags: views, users, hooks, security
---


# Question
Title: How can I programmatically set date field Month, Day, Year dropdowns in Paragraphs?
I'm setting a basic date field (and several other text fields) programmatically when creating a paragraph. The database is showing that it is getting my date, which is being stored in`Y-m-d\TH:i:s` format. All the other data is being saved as well. No errors.

However, when I edit the node my paragraph is attached to, all the data is there except for the date field. It's not set despite the data being in the database.

The date field is set to show MDY in dropdowns like so:

I've tried this: `$date = new DateTime('2015-06-01 23:45:52', new \DateTimeZone('UTC'));` This does get the date saved into the database, however, the dropdowns are not set.

So then I tried converting it to MDY: `$date->format('M-D-Y')` but no such luck. This doesn't work at all.

I have also seen that you have to reference the actual stored format using `$date->format(DATETIME_DATETIME_STORAGE_FORMAT)` but there doesn't seem to be other parameters for that to get it into the format that I need.

Is there some way I need to individually set the actual dropdown options in code?

Full paragraph code below. Almost all of these examples save data in the DB correctly, the date dropdowns do not reference it though.

```
use Drupal\Core\Url;
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeCustomFormatter;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\datetime_range\DateTimeRangeTrait;

  $date = new DateTime('2015-06-01 23:45:52', new \DateTimeZone('UTC'));
  //$date = $date->format('Y-m-d\TH:i:s');
  // if ($date instanceOf DrupalDateTime && !$date->hasErrors()) {
  //   $currentDate->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
  //   $db_friendly_value = $currentDate->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
  // }

  //$date->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE));
  //$date = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
  // $date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));

      $program_1 = Paragraph::create([
        'type' => 'programs',
        'field_program_name' => 'Program Name',
        'field_program_description' => 'Description',
        'field_program_year' => [
          'value' => $date,
        ],
      ]);
      $program_1->save();

```

Am I missing something somewhere? I've been hunting for the correct way to do this for a few days and have tried a number of different ways. I could probably get around this by just changing the field to be a text (date/time) date field instead of dropdowns.

I tried the suggestion here, but this doesn't seem to work either: Adding content to Paragraph Date Field Drupal 8

Any ideas here?

# Answer
> 1 votes
After trying just about every solution for the date I could find, I finally figured this out.

It seems that it doesn't even matter what the DB is wanting to save the date as. Looking in the DB, the date is being stored as `Y-m-d` without the trailing `H:i:s`. Most examples are saying that you need the full date in `Y-m-d\TH:i:s` format.

This particular dropdown widget for the date field wants only `Y-m-d` and I only found that out after trying to pass it all kinds of different date strings and it gave me an error message back about the format without the trailing `H:i:s`.

So all of that garbage that I tried to pass it earlier and formatting was way off. All I needed to do was this, and the paragraph saved properly and the form fields are reflecting the proper date now.

```
'field_program_year' => date('Y-m-d', strtotime('2011-11-12')),
'field_eligibility_range' => [
  'value'=> date('Y-m-d', strtotime('2011-11-12')),
  'end_value' => date('Y-m-d', strtotime('2011-11-12'))
],

```

---
Tags: 8, datetime, paragraphs
---


# Question
Title: Expose a filter to turn a different filter on or off
I have a view of items that have a due date, and I want to be able to expose a boolean filter "Is overdue by more than 30 days"

I can create a filter on this due date as a relative date filter "\<= today -30 days"; however this filter is always active on the view.

The best I've been able to come up with is to add a new boolean field on my content type "date\_filter" that is always null, and in the view create a new exposed filter "is not null" (i.e, when active, will always be false).
Then add this filter to a new OR filter group with the above relative date filter. This works, as when the filter is "off" it returns true and overrides the relative date filter. When on, only the rows that fit the date filter are returned.

However, is there a way to do this without adding dummy fields? Ideally a module I can use to do this. I'd prefer not to have to write a hook just for this filter.

# Answer
There is a module for that; you can use Views Dependent Filters which allows the presence of exposed filters on a view to being controlled by values in another exposed filter. Dependent filters are hidden when not relevant, and their values are not considered when the exposed form is submitted.
> 0 votes

---
Tags: 7, views
---


# Question
Title: Change exposed filter date format with Search API
We are using **Search API** for a customer website and we have a **View** with a start and end date exposed filter.

The view only filters correctly if we use the **m/d/Y** format, which is not valid in Brazil, as we use the **d/m/Y** format (with the day first).

I tried to search for solutions, but mostly use **custom code** or use **Better Exposed Filters**, which is not stable in **Drupal 8**. **Date Popup** also doesn't work with Search API fields. Although they fixed it, they didn't release a new version since 2017 (the fix is only available in the dev branch I guess).

I tried to create a new **Date Format** in "Date and Time Formats" and set the date field to this format, but that doesn't work too.

Using non-stable modules is **not** a choice and I would prefer to solve this using only **Drupal UI** (not any custom code)

**View Settings**

**Tried to filter from 18/04/2020 to 22/04/2020, there's a content written in 20/04/2020, but nothing is returned**

PS: The screenshots are in Portuguese (Brazil), sorry for that.

**Here's an export of the view, if that helps:**

```
    uuid: e60ffc0d-fa69-4581-8ee5-585f128ffcec
    langcode: pt-br
    status: true
    dependencies:
      config:
        - field.storage.node.body
        - field.storage.node.field_tags
        - search_api.index.conteudo
        - taxonomy.vocabulary.tags
      module:
        - search_api
        - text
        - views_infinite_scroll
    id: busca
    label: Busca
    module: views
    description: ''
    tag: ''
    base_table: search_api_index_conteudo
    base_field: search_api_id
    display:
      default:
        display_plugin: default
        id: default
        display_title: Master
        position: 0
        display_options:
          access:
            type: none
            options: {  }
          cache:
            type: tag
            options: {  }
          query:
            type: views_query
            options:
              bypass_access: false
              skip_access: false
              preserve_facet_query_args: false
          exposed_form:
            type: input_required
            options:
              submit_button: Buscar
              reset_button: true
              reset_button_label: Limpar
              exposed_sorts_label: 'Ordenar por'
              expose_sort_order: true
              sort_asc_label: 'Ordem crescente'
              sort_desc_label: 'Ordem decrescente'
              text_input_required: 'Aplique um filtro para ver os resultados'
              text_input_required_format: raw_html
          pager:
            type: infinite_scroll
            options:
              items_per_page: 15
              offset: 0
              id: 0
              total_pages: null
              tags:
                previous: Anterior
                next: Próximo
              expose:
                items_per_page: false
                items_per_page_label: 'Items per page'
                items_per_page_options: '5, 10, 25, 50'
                items_per_page_options_all: false
                items_per_page_options_all_label: '- All -'
                offset: false
                offset_label: Offset
              views_infinite_scroll:
                button_text: 'Total de Resultados: @total | Carregar mais @next_page_count'
                automatically_load_content: false
          style:
            type: default
          row:
            type: fields
          fields:
            created:
              id: created
              table: search_api_datasource_conteudo_entity_node
              field: created
              relationship: none
              group_type: group
              admin_label: ''
              label: ''
              exclude: false
              alter:
                alter_text: false
                text: ''
                make_link: false
                path: ''
                absolute: false
                external: false
                replace_spaces: false
                path_case: none
                trim_whitespace: false
                alt: ''
                rel: ''
                link_class: ''
                prefix: ''
                suffix: ''
                target: ''
                nl2br: false
                max_length: 0
                word_boundary: true
                ellipsis: true
                more_link: false
                more_link_text: ''
                more_link_path: ''
                strip_tags: false
                trim: false
                preserve_tags: ''
                html: false
              element_type: ''
              element_class: created
              element_label_type: ''
              element_label_class: ''
              element_label_colon: false
              element_wrapper_type: ''
              element_wrapper_class: ''
              element_default_classes: true
              empty: ''
              hide_empty: false
              empty_zero: false
              hide_alter_empty: true
              click_sort_column: value
              type: timestamp
              settings:
                date_format: custom
                custom_date_format: d/m/Y
                timezone: ''
              group_column: value
              group_columns: {  }
              group_rows: true
              delta_limit: 0
              delta_offset: 0
              delta_reversed: false
              delta_first_last: false
              multi_type: separator
              separator: ', '
              field_api_classes: false
              field_rendering: true
              fallback_handler: search_api_date
              fallback_options:
                date_format: fallback
                custom_date_format: ''
                timezone: ''
                link_to_item: false
                use_highlighting: false
                multi_type: separator
                multi_separator: ', '
              entity_type: node
              plugin_id: search_api_field
            title:
              id: title
              table: search_api_index_conteudo
              field: title
              relationship: none
              group_type: group
              admin_label: ''
              label: ''
              exclude: false
              alter:
                alter_text: false
                text: ''
                make_link: false
                path: ''
                absolute: false
                external: false
                replace_spaces: false
                path_case: none
                trim_whitespace: false
                alt: ''
                rel: ''
                link_class: ''
                prefix: ''
                suffix: ''
                target: ''
                nl2br: false
                max_length: 0
                word_boundary: true
                ellipsis: true
                more_link: false
                more_link_text: ''
                more_link_path: ''
                strip_tags: false
                trim: false
                preserve_tags: ''
                html: false
              element_type: ''
              element_class: title
              element_label_type: ''
              element_label_class: ''
              element_label_colon: false
              element_wrapper_type: ''
              element_wrapper_class: ''
              element_default_classes: true
              empty: ''
              hide_empty: false
              empty_zero: false
              hide_alter_empty: true
              click_sort_column: value
              type: string
              settings:
                link_to_entity: true
              group_column: value
              group_columns: {  }
              group_rows: true
              delta_limit: 0
              delta_offset: 0
              delta_reversed: false
              delta_first_last: false
              multi_type: separator
              separator: ', '
              field_api_classes: false
              field_rendering: true
              fallback_handler: search_api
              fallback_options:
                link_to_item: false
                use_highlighting: false
                multi_type: separator
                multi_separator: ', '
              plugin_id: search_api_field
            body:
              id: body
              table: search_api_index_conteudo
              field: body
              relationship: none
              group_type: group
              admin_label: ''
              label: ''
              exclude: false
              alter:
                alter_text: false
                text: ''
                make_link: false
                path: ''
                absolute: false
                external: false
                replace_spaces: false
                path_case: none
                trim_whitespace: false
                alt: ''
                rel: ''
                link_class: ''
                prefix: ''
                suffix: ''
                target: ''
                nl2br: false
                max_length: 250
                word_boundary: true
                ellipsis: true
                more_link: false
                more_link_text: ''
                more_link_path: ''
                strip_tags: true
                trim: true
                preserve_tags: ''
                html: false
              element_type: ''
              element_class: body
              element_label_type: ''
              element_label_class: ''
              element_label_colon: false
              element_wrapper_type: ''
              element_wrapper_class: ''
              element_default_classes: true
              empty: ''
              hide_empty: false
              empty_zero: false
              hide_alter_empty: true
              click_sort_column: value
              type: text_default
              settings: {  }
              group_column: value
              group_columns: {  }
              group_rows: true
              delta_limit: 0
              delta_offset: 0
              delta_reversed: false
              delta_first_last: false
              multi_type: separator
              separator: ', '
              field_api_classes: false
              field_rendering: true
              fallback_handler: search_api
              fallback_options:
                link_to_item: false
                use_highlighting: false
                multi_type: separator
                multi_separator: ', '
              plugin_id: search_api_field
            field_tags:
              id: field_tags
              table: search_api_datasource_conteudo_entity_node
              field: field_tags
              relationship: none
              group_type: group
              admin_label: ''
              label: ''
              exclude: true
              alter:
                alter_text: false
                text: ''
                make_link: false
                path: ''
                absolute: false
                external: false
                replace_spaces: false
                path_case: none
                trim_whitespace: false
                alt: ''
                rel: ''
                link_class: ''
                prefix: ''
                suffix: ''
                target: ''
                nl2br: false
                max_length: 0
                word_boundary: true
                ellipsis: true
                more_link: false
                more_link_text: ''
                more_link_path: ''
                strip_tags: false
                trim: false
                preserve_tags: ''
                html: false
              element_type: ''
              element_class: ''
              element_label_type: ''
              element_label_class: ''
              element_label_colon: false
              element_wrapper_type: ''
              element_wrapper_class: ''
              element_default_classes: false
              empty: ''
              hide_empty: false
              empty_zero: false
              hide_alter_empty: true
              click_sort_column: target_id
              type: entity_reference_label
              settings:
                link: true
              group_column: target_id
              group_columns: {  }
              group_rows: true
              delta_limit: 0
              delta_offset: 0
              delta_reversed: false
              delta_first_last: false
              multi_type: separator
              separator: ', '
              field_api_classes: false
              field_rendering: true
              fallback_handler: search_api_entity
              fallback_options:
                link_to_item: false
                use_highlighting: false
                multi_type: separator
                multi_separator: ', '
                display_methods:
                  abrangencia_do_evento:
                    display_method: label
                  agendas:
                    display_method: label
                  albuns:
                    display_method: label
                    view_mode: default
                  autoria:
                    display_method: label
                  categoria_do_evento:
                    display_method: label
                  categorias_de_noticias:
                    display_method: label
                  categorias_do_banco_de_imagens:
                    display_method: label
                    view_mode: default
                  categorias_do_banco_de_videos:
                    display_method: label
                  grupo:
                    display_method: label
                  grupos:
                    display_method: label
                  grupos_de_links:
                    display_method: label
                  local_de_publicacao_do_evento:
                    display_method: label
                  representante_do_evento:
                    display_method: label
                  subdivisao_de_grupos:
                    display_method: label
                  tags:
                    display_method: label
                  tipo_do_evento:
                    display_method: label
              entity_type: node
              plugin_id: search_api_field
            created_1:
              id: created_1
              table: search_api_datasource_conteudo_entity_node
              field: created
              relationship: none
              group_type: group
              admin_label: ''
              label: ''
              exclude: true
              alter:
                alter_text: false
                text: ''
                make_link: false
                path: ''
                absolute: false
                external: false
                replace_spaces: false
                path_case: none
                trim_whitespace: false
                alt: ''
                rel: ''
                link_class: ''
                prefix: ''
                suffix: ''
                target: ''
                nl2br: false
                max_length: 0
                word_boundary: true
                ellipsis: true
                more_link: false
                more_link_text: ''
                more_link_path: ''
                strip_tags: false
                trim: false
                preserve_tags: ''
                html: false
              element_type: ''
              element_class: ''
              element_label_type: ''
              element_label_class: ''
              element_label_colon: false
              element_wrapper_type: ''
              element_wrapper_class: ''
              element_default_classes: true
              empty: ''
              hide_empty: false
              empty_zero: false
              hide_alter_empty: true
              click_sort_column: value
              type: timestamp
              settings:
                date_format: d_m_y
                custom_date_format: d/m/Y
                timezone: America/Sao_Paulo
              group_column: value
              group_columns: {  }
              group_rows: true
              delta_limit: 0
              delta_offset: 0
              delta_reversed: false
              delta_first_last: false
              multi_type: separator
              separator: ', '
              field_api_classes: false
              field_rendering: true
              fallback_handler: search_api_date
              fallback_options:
                date_format: fallback
                custom_date_format: ''
                timezone: ''
                link_to_item: false
                use_highlighting: false
                multi_type: separator
                multi_separator: ', '
              entity_type: node
              plugin_id: search_api_field
          filters:
            search_api_fulltext:
              id: search_api_fulltext
              table: search_api_index_conteudo
              field: search_api_fulltext
              relationship: none
              group_type: group
              admin_label: ''
              operator: and
              value: ''
              group: 1
              exposed: true
              expose:
                operator_id: search_api_fulltext_op
                label: 'Termo da Pesquisa'
                description: ''
                use_operator: false
                operator: search_api_fulltext_op
                identifier: search_api_fulltext
                required: true
                remember: false
                multiple: false
                remember_roles:
                  authenticated: authenticated
                  anonymous: '0'
                  administrator: '0'
                  publicador_basico: '0'
                  publicador_presi: '0'
                  jornalista: '0'
                  publicidade: '0'
                placeholder: 'Digite o termo da pesquisa'
                operator_limit_selection: false
                operator_list: {  }
              is_grouped: false
              group_info:
                label: ''
                description: ''
                identifier: ''
                optional: true
                widget: select
                multiple: false
                remember: false
                default_group: All
                default_group_multiple: {  }
                group_items: {  }
              parse_mode: terms
              min_length: null
              fields: {  }
              plugin_id: search_api_fulltext
            created:
              id: created
              table: search_api_index_conteudo
              field: created
              relationship: none
              group_type: group
              admin_label: ''
              operator: '>='
              value:
                min: ''
                max: ''
                value: ''
                type: date
              group: 1
              exposed: true
              expose:
                operator_id: created_op
                label: 'Data inicial'
                description: ''
                use_operator: false
                operator: created_op
                identifier: initial_date
                required: false
                remember: false
                multiple: false
                remember_roles:
                  authenticated: authenticated
                  anonymous: '0'
                  administrator: '0'
                  publicador_basico: '0'
                  publicador_presi: '0'
                  jornalista: '0'
                  publicidade: '0'
                placeholder: 'Data inicial'
                min_placeholder: ''
                max_placeholder: ''
                operator_limit_selection: false
                operator_list: {  }
              is_grouped: false
              group_info:
                label: ''
                description: ''
                identifier: ''
                optional: true
                widget: select
                multiple: false
                remember: false
                default_group: All
                default_group_multiple: {  }
                group_items: {  }
              plugin_id: search_api_date
            created_1:
              id: created_1
              table: search_api_index_conteudo
              field: created
              relationship: none
              group_type: group
              admin_label: ''
              operator: '<='
              value:
                min: ''
                max: ''
                value: ''
                type: date
              group: 1
              exposed: true
              expose:
                operator_id: created_1_op
                label: 'Data final'
                description: ''
                use_operator: false
                operator: created_1_op
                identifier: final_date
                required: false
                remember: false
                multiple: false
                remember_roles:
                  authenticated: authenticated
                  anonymous: '0'
                  administrator: '0'
                  publicador_basico: '0'
                  publicador_presi: '0'
                  jornalista: '0'
                  publicidade: '0'
                placeholder: 'Data final'
                min_placeholder: ''
                max_placeholder: ''
                operator_limit_selection: false
                operator_list: {  }
              is_grouped: false
              group_info:
                label: ''
                description: ''
                identifier: ''
                optional: true
                widget: select
                multiple: false
                remember: false
                default_group: All
                default_group_multiple: {  }
                group_items: {  }
              plugin_id: search_api_date
            status:
              id: status
              table: search_api_index_conteudo
              field: status
              relationship: none
              group_type: group
              admin_label: ''
              operator: '='
              value: '1'
              group: 1
              exposed: false
              expose:
                operator_id: ''
                label: ''
                description: ''
                use_operator: false
                operator: ''
                identifier: ''
                required: false
                remember: false
                multiple: false
                remember_roles:
                  authenticated: authenticated
                operator_limit_selection: false
                operator_list: {  }
              is_grouped: false
              group_info:
                label: ''
                description: ''
                identifier: ''
                optional: true
                widget: select
                multiple: false
                remember: false
                default_group: All
                default_group_multiple: {  }
                group_items: {  }
              plugin_id: search_api_boolean
            field_tags:
              id: field_tags
              table: search_api_index_conteudo
              field: field_tags
              relationship: none
              group_type: group
              admin_label: ''
              operator: or
              value: {  }
              group: 1
              exposed: true
              expose:
                operator_id: field_tags_op
                label: 'Tags de notícias'
                description: ''
                use_operator: false
                operator: field_tags_op
                identifier: field_tags
                required: false
                remember: false
                multiple: false
                remember_roles:
                  authenticated: authenticated
                  anonymous: '0'
                  administrator: '0'
                  publicador_basico: '0'
                  publicador_presi: '0'
                  jornalista: '0'
                  publicidade: '0'
                reduce: false
                operator_limit_selection: false
                operator_list: {  }
              is_grouped: false
              group_info:
                label: ''
                description: ''
                identifier: ''
                optional: true
                widget: select
                multiple: false
                remember: false
                default_group: All
                default_group_multiple: {  }
                group_items: {  }
              reduce_duplicates: false
              type: select
              limit: true
              vid: tags
              hierarchy: false
              error_message: true
              plugin_id: search_api_term
          sorts:
            created:
              id: created
              table: search_api_index_conteudo
              field: created
              relationship: none
              group_type: group
              admin_label: ''
              order: DESC
              exposed: false
              expose:
                label: 'Ordenar por data'
              plugin_id: search_api
          title: Busca
          header: {  }
          footer: {  }
          empty:
            area_text_custom:
              id: area_text_custom
              table: views
              field: area_text_custom
              relationship: none
              group_type: group
              admin_label: ''
              empty: true
              tokenize: false
              content: 'Sua busca não retornou nenhum resultado.'
              plugin_id: text_custom
          relationships: {  }
          arguments: {  }
          display_extenders: {  }
          css_class: search-result
          use_ajax: true
          filter_groups:
            operator: AND
            groups:
              1: AND
        cache_metadata:
          max-age: -1
          contexts:
            - 'languages:language_content'
            - 'languages:language_interface'
            - url
            - url.query_args
            - user
          tags:
            - 'config:field.storage.node.body'
            - 'config:field.storage.node.field_tags'
      page_1:
        display_plugin: page
        id: page_1
        display_title: Page
        position: 1
        display_options:
          display_extenders: {  }
          path: busca
          exposed_block: false
        cache_metadata:
          max-age: -1
          contexts:
            - 'languages:language_content'
            - 'languages:language_interface'
            - url
            - url.query_args
            - user
          tags:
            - 'config:field.storage.node.body'
            - 'config:field.storage.node.field_tags'

```

# Answer
One solution to this problem would be a date picker widget. This removes the need for the user to type dates in a specific format.

You should check out the Date Popup module.

Reference: milkovsky's answer to #200787
> 0 votes

---
Tags: views, 8, search, datetime
---


title: More than one path alias per node

text:
# Question
Title: More than one path alias per node
I have a ticketing system where the path aliases are set like `ticket/[node ID]`, e.g. http://example.com/ticket/1234.

I would like to create multiple path aliases for the same node, and be able to access it also as `discussion/[node ID]`, e.g. http://example.com/discussion/1234.

I will be using different node templates basing on the path.

Is there any way to set multiple path aliases for the same node?

# Answer
To have a working code example for the routing approach.

First in `MYMODULE.routing.yml` write:

```
ticket.view:
  path: '/ticket/{node}'
  defaults:
    _controller: '\Drupal\node\Controller\NodeViewController::view'
  requirements:
    node: \d+
    _entity_access: 'node.view'
discussion.view:
  path: '/discussion/{node}'
  defaults:
    _controller: '\Drupal\node\Controller\NodeViewController::view'
  requirements:
    node: \d+
    _entity_access: 'node.view'

```

Then in `MYMODULE.module` you'ld add template suggestions like so:

```
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MYMODULE_theme_suggestions_node_alter(array &$suggestions, array $variables) {

  if (\Drupal::routeMatch()->getRouteName() == 'ticket.view') {
    $suggestions[] = 'ticket'; // Would take ticket.html.twig
  }

  if (\Drupal::routeMatch()->getRouteName() == 'discussion.view') {
    $suggestions[] = 'discussion'; // Would take discussion.html.twig
  }

}

```

Or maybe if all it takes are some different styles simply add a body class depending on the route:

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_html(&$variables) {

  if (\Drupal::routeMatch()->getRouteName() == 'ticket.view') {
    $variables['attributes']['class'][] = 'ticket';
  }

  if (\Drupal::routeMatch()->getRouteName() == 'discussion.view') {
    $variables['attributes']['class'][] = 'discussion';
  }

}

```

Last but not least check out this brilliant article https://thinkshout.com/blog/2016/07/drupal-8-routing-tricks-for-better-admin-urls/, there are some more route goodies inside you may like.
> 1 votes

# Answer
You can set multiple path aliases for one node, this is no problem. If you can't do it with Pathauto, then it's possible with custom code when saving the node.

But in your case it might be more efficient to set up different routes for `/ticket/{node}` and `/discussion/{node}`. You can either set a fixed route parameter or use a custom node controller to set a marker, that you can use in theme name suggestion to choose the custom template.

Another solution would be to set up a View with a contextual filter for the node and two displays with different paths. Choose for each a different view mode to get different templates. Technically it's almost the same, but you need no custom module, because Views sets up the routes for you.
> 2 votes

# Answer
Even better approach would be to still use custom routes and set different display modes for each route. With this you will have all the theme support from core with small to zero amount of custom code.
> 0 votes

---
Tags: 8, path-aliases
---


title: How to customize a textarea field?

text:
# Question
Title: How to customize a textarea field?
I have created a textarea field using admin ui. It allows users to add Bio to their profile. I want to do 2 things with this field.

1. Limit the characters to 255.
2. Use a text format. **Note:** I do not want to allow users to choose a text format.

# Answer
With HTML5 on Drupal 7 no JS is necessary if we can add a maxlength attribute to the textarea tag.

I tried to use a hook\_form\_alter to set this attribute, something like

```
$form['field_NAME'][LANGUAGE_NONE][0]['#attributes'] = array('maxlength' => 220);

```

or

```
$form['field_NAME'][LANGUAGE_NONE][0]['#maxlength'] = 220;

```

...and a gazillion variations using dsm($form) for ideas and to check my results. I could easily change the $form\['field\_name'\] values but my textarea failed to acquire the maxlength atttribute.

This worked:

```
/**
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 * Add a maxlength attribute to field_NAME.
 */
function MYMODULE_field_widget_text_textarea_form_alter(&$element, &$form_state, $context) {
  if (isset($element['#field_name']) && ($element['#field_name'] == 'field_NAME')) {
    $element['value']['#attributes'] = array('maxlength' => 220);
  }
}

```
> 4 votes

# Answer
For anyone who lands here like I did looking for a way to set maxlength in a Drupal 8 textarea, this worked for me using form\_alter:

```
$form['field_NAME']['widget'][0]['value']['#maxlength'] = 220;

```

Here is an example using a custom module:

```
function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    $node = $form_state->getFormObject()->getEntity(); //gets the node
    if ($node->getType() == 'mynode') { //check that it is the node where I want this
        $form['field_NAME']['widget'][0]['value']['#maxlength'] = 220;
    }
}

```
> 2 votes

# Answer
There are two modules which can do what you are wanting:

1. Better formats can hide the filter per role.
2. Field validation can add additional validation to the field.
> 1 votes

# Answer
We can limit the character count to 255 with jQuery validation

```
  $max_length = 500; // 500 chars max (should pull this from a config var)
  $form['my_textarea'] = array(
    '#type' => 'textarea',
    '#title' => t('Body'),
    '#default_value' => $node->body,
    '#required' => TRUE,
    '#description' => t('The main body text of your entry.  Please note that this is limited to %limit characters or less.', array('%limit'=>$max_length)),
    // this is the item to be added - limit length while typing
    '#attributes'=>array('onKeyPress'=>"return(this.value.length<$max_length);),
  );

```

Create a JS file and add it using drupal\_add\_js:

```
  drupal_add_js(drupal_get_path('module', 'mymodule'). '/myfile.js');

```

Inside myfile.js define the following function:

```
function textareaMaxLength(field, evt, limit) {
  var evt = (evt) ? evt : event;
  var charCode =
    (typeof evt.which != "undefined") ? evt.which :
   ((typeof evt.keyCode != "undefined") ? evt.keyCode : 0);

  if (!(charCode >= 13 && charCode <= 126)) {
    return true;
  }

  return (field.value.length < limit);
}

```

php validation

```
function myform_validate($form_id, $edit) {
  if (strlen($edit['text']) > 200) {
    form_set_error('text', t('Your text contains more than 200 characters'));
  }
}

```

Reference: https://www.drupal.org/node/80122
> 1 votes

# Answer
If you are using Drupal 8, you could put this together pretty fast with:

CKEditor Wordcount has the bonus of not counting HTML tags as characters which works well in the context of a WYSIWYG. I suppose you could add the Field Validation module in here as well, but for this use case, Field Validation would also have to ignore incoming HTML tags when counting characters so that the validations match up.

Better Formats will let you select, per field with text formatting on it, what roles should have access to which filters. If you only select 1 filter, they will not see a filter format drop down at all.
> 0 votes

---
Tags: 7, users, entities
---


title: Javascript Messages API Error

text:
# Question
Title: Javascript Messages API Error
1- I tried to set an error message in Drupal 8 from javascript with the new Messages API using the following code:

```
const messages = new Drupal.Message();
messages.add('test message');

```

I get the following error on the console log:

drupal.js?v=8.8.5:13 Uncaught TypeError: Drupal.Message is not a constructor.

How can I include this API?

2- As I can see in message.es6.js, there is an option to set message type: error, warning and status. How to pass these params once I get the function working?

Reference Documentation: https://www.drupal.org/node/2930536

Thank you.

# Answer
You need to make sure your library declares a dependency on `core/drupal.message`, e.g.

```
foo:
  js:
    js/foo.js: {}
  dependencies:
    - core/drupal.message

```

Once you've done that, you can choose the message type by including options:

```
const messages = new Drupal.Message();
messages.add('test message', { type: 'status' });

```
> 1 votes

---
Tags: 8
---


title: How can I use the UUID API?

text:
# Question
Title: How can I use the UUID API?
I am aware that the question is (almost) a duplicate of the following question #21991, which has been posted back in 2012. But that question is NOT related to Drupal 8, where UUID is in core.

References:

The Drupal 8 Core Module Documentation does not list UUID.

I wonder if I could leverage Drupal 8's core UUID module to migrate and map relational data imported from a different environment, which has unique keys generated by Firebase.

Update:

It has been kindly pointed out that UUID is not a module.

It seems to make UUID records per default for entities (aka nodes) and apparently can be used to map entity references.

Can I make use of this when I introduce external data, that already has unique IDs? So I have the "node" IDs and can map with the UUIDs?

Update based on further comments:

The goal is to use UUID with entities and the REST module. Respectively, it seems sensible to do so when importing external relational data, that already has unique IDs.

I just try to understand how UUID works, what it can do and what not, how I can generate and validate UUID's, what I need to be aware of, if I introduce external ID's.

# Answer
I assume what you want to know is how to generate a UUID in Drupal 8, because there's really not much else that you can do ;)

Entities all have an UUID automatically, so if you store your data as a config or content entity, you just have to define the uuid entity key.

To generate a UUID yourself, you need the uuid service:

```
$uuid = \Drupal::service('uuid');
$uuid->generate();
$uuid->isValid($uuid_to_validate);

```
> 14 votes

# Answer
To generate uuid with drush:

```
drush php-eval "echo \Drupal::service('uuid')->generate();"

```
> 9 votes

---
Tags: 8, entities, features
---


# Question
Title: Are passwords entered in the login form encrypted?
In the user login page, is the value entered for the password encrypted to avoid it can be sniffed by a hacker?

# Answer
When you submit the form on /user/login, the fields are both sent in plaintext in the POST body. If you use a browser debugger (like Chrome Inspector), you can look at the network traffic and see this.

Then, on the server side the submitted password is hashed with the current algorithm. (I think it's a stretched SHA-512 right now; see the `PhpassHashedPassword` class for more details.) The hash value is then checked against the value in the database.
> 4 votes

---
Tags: 8, authentication-authorization
---


# Question
Title: How can I restrict libraries to attach to my custom controller only?
I have a custom module that creates its own page and displays some stuff. I have some CSS and JS to add, and I'm using a library. The CSS and JS are being added, but to every page on the site. Can someone tell me how to restrict them to this page only?

The docs say "*But what matters most is that we don't decide whether to attach a library based on which page we're on (i.e. which URL or route), but based on which things are visible on the page...*" So, if that really is what matters most, then maybe I'm going about this all wrong?

*MycontrollerController.php*

```
<?php

namespace Drupal\mycontroller\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Returns responses for mycontroller routes.
 */
class MycontrollerController extends ControllerBase {
  public function content() {
    return [
      '#title' => 'My Controller',
      '#plain_text' => 'Here is some text.'
    ];
  }
}

```

*mycontroller.info.yml*

```
name: My Controller
description: It's a very nice controller
type: module
core: 8.x

```

*mycontroller.routing.yml*

```
mycontroller:
  path: '/mycontroller'
  defaults:
    _title: 'Mycontroller'
    _controller: '\Drupal\mycontroller\Controller\MycontrollerController::content'
  requirements:
    _permission: 'access content'

```

*mycontroller.libraries.yml*

```
mylibrary:
  version: 1.x
  css:
    layout:
      css/mycontroller-layout.css: {}
  js:
    js/mycontroller.js: {}

```

*mycontroller.module*

```
<?php
function mycontroller_page_attachments(array &$attachments) {
  $attachments['#attached']['library'][] = 'mycontroller/mylibrary';
}

```

*My directory structure...*

```
mycontroller
|-- css
|   `-- mycontroller-layout.css
|
|-- js
|   `-- mycontroller.js
|
|-- mycontroller.info.yml
|-- mycontroller.libraries.yml
|-- mycontroller.module
|-- mycontroller.routing.yml
`-- src
    `-- Controller
        `-- MycontrollerController.php

```

# Answer
Your render array can return the `#attached` property:

```
$build = [
 '#title' => 'My Controller',
 '#plain_text' => 'Here is some text.'
];

$build['#attached']['library'][] = 'mycontroller/mylibrary';

return $build;

```

See: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21theme.api.php/group/theme\_render/8.2.x
> 4 votes

---
Tags: 8, theming
---


# Question
Title: Menu endpoint hangs when access callback returns false
I'm trying to add a custom access callback function that checks that a user is a specific user (we only want this one api user to have this specific endpoint. It is set up like so:

```
function my_module_menu() {
    return array(
        '/api/v1/sample/request' => array(
            'page callback' => 'sample_request',
            'access callback' => 'user_is_api_user',
            'type' => MENU_CALLBACK,
        )
    );
}

function user_is_api_user() {
    watchdog("GLOBALS", "<pre>" . print_r($GLOBALS['user'], true) . "</pre>");
    return $GLOBALS['user']->name == 'api';
}

```

If my custom `user_is_api_user` function returns FALSE, the endpoint just hangs instead of sending back a 403 Forbidden (like expected). Instead, it looks it just keeps retrying because my recent logs just repeat the error `not authorized` and the watchdog log I put in over and over again until I end the request.

If my custom `user_is_api_user` returns TRUE, it logs the user in fine. Why does it just look and not actually return 403 forbidden when my custom function return false?

# Answer
To return `403 Forbidden` in your callback function, use drupal\_access\_denied() function something like:

```
function user_is_api_user() {
  watchdog("GLOBALS", "<pre>" . print_r($GLOBALS['user'], TRUE) . "</pre>");
  if ($GLOBALS['user']->name !== 'api'){
    drupal_access_denied();
  }
}

```
> 2 votes

---
Tags: 7
---


# Question
Title: Adding repositories in contrib module composer.json?
Is it possible to add repositories from a module's composer.json instead of a project's composer.json? I've got the following set up:

I'm developing Commerce Recurly and am declaring a dependency on the Recurly module. However, the Recurly module uses API v2, and I am using API v3 in Commerce Recurly. Since the namespacing of the two APIs are different there are no conflicts when running them concurrently, so I created a fork of the API v2 to allow both to be added to my project. The result is that I am able to get both `recurly/recurly-client` and `mrweiner/recurly-client-php-v2` concurrently installed to vendor.

Composer picks up all of the `require` dependencies correctly from both modules' composer.json files, as well as the patches from the Recurly Fork. It doesn't seem to pick up the repositories sections, though.

I'd expect to be able to just add the Commerce Recurly repo to my project's main composer.json like so and have everything install when running `composer require sandbox/commerce_recurly`:

```
    "repositories": {
        "0": {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        "commerce_recurly_sandbox": {
            "type": "vcs",
            "url": "https://git.drupalcode.org/sandbox/mrweiner-3131465"
        },
    }

```

This doesn't work, though. I need to add repository entries for all three repos to my project's main composer.json to get `composer require sandbox/commerce_recurly` to correctly install everything, like so:

```
    "repositories": {
        "0": {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        "commerce_recurly_sandbox": {
            "type": "vcs",
            "url": "https://git.drupalcode.org/sandbox/mrweiner-3131465"
        },
        "recurly_fork_sandbox": {
            "type": "vcs",
            "url": "https://git.drupalcode.org/sandbox/mrweiner-3131471"
        },
        "recurly_api_v2": {
            "type": "package",
            "package": {
                "name": "mrweiner/recurly-client-php-v2",
                "version": "2.12.13",
                "type": "vendor",
                "source": {
                    "url": "https://github.com/mrweiner/recurly-client-php.git",
                    "type": "git",
                    "reference": "c9f67565"
                }
            }
        },
    }

```

Is there some way to get composer to pick up the repositories defined in the modules' `composer.json` files? Having these extra entries isn't a huge deal for me right now, but when I move Commerce Recurly from Sandbox to a full project, it's going to be inconvenient to force people to add extra Repos to get things running.

# Answer
> 0 votes
Comments above pretty much answer this. No what I was looking to do is not possible.

---
Tags: composer
---


# Question
Title: Deprecated code cleanup: Updating EntityManager to EntityFieldManagerInterface
EntityManager is deprecated so I am trying to update code for Drupal 9. The documentation says it should usually be changed to EntityTypeManager, but in this case the code is using `getFieldStorageDefinitions` so it needs to be `EntityFieldManagerInterface`.

I changed this line:

```
  $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);

```

To:

```
  $fields = \Drupal::EntityFieldManagerInterface()->getFieldStorageDefinitions($entity_type);

```

Which gives this error when I run behat:

```
  [error]  Error: Call to undefined method Drupal::EntityFieldManagerInterface() in _drush_behat_get_entity_field_types() (line 95 of /app/drush/Commands/contrib/behat-drush-endpoint/behat.inc) #0 /app/drush/Commands/contrib/behat-drush-endpoint/behat.inc(123): _drush_behat_get_entity_field_types('node')

```

However, I don't understand this error, because EntityFieldManagerInterface does have `getFieldStorageDefinitions`.

How can I update entityManager to EntityFieldManagerInterface?

Here's the full function if that's useful:

```
function _drush_behat_get_entity_field_types($entity_type) {
  $return = array();
  $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
  foreach ($fields as $field_name => $field) {
    if (_drush_behat_is_field($entity_type, $field_name)) {
      $return[$field_name] = $field->getType();
    }
  }
  return $return;
}

```

# Answer
> 1 votes
EntityFieldManager has no shortcut in `\Drupal`, so you need to get it through `\Drupal::service()`:

```
$fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type);

```

---
Tags: 9
---


# Question
Title: How to get the referenced entity name instead of target_id in Normalizers?
I am working on exposing the article type content via REST in JSON format. I am using Normalizers to generate the required data format.

Normalizer:

```
use Drupal\serialization\Normalizer\ContentEntityNormalizer;

/**
 * StdClass normalizer.
 */
class NewsFeedNormalizer extends ContentEntityNormalizer {

  /**
   * @inheritDoc
   */
  public function normalize($entity, $format = NULL, array $context = []) {
    $node_detail = parent::normalize($entity, $format, $context);
    // $news_data = [];
    $news_data['id'] = $node_detail['nid'][0]['value'];
    $news_data['type'] = $node_detail['field_story_type'][0]['target_id'];
    $news_data['title'] = $node_detail['title'][0]['value'];
    $news_data['summary'] = $node_detail['body'][0]['summary'];

    return $news_data;
  }

}

```

Tha above code will return `target_id` in `$news_data['type']`. But I need to pass label of the term which is referred. I tried with another Normalizer called `EntityReferenceFieldItemNormalizer` But there also i didn't get the required result. Can anyone help me in this regard? Any suggestions will be apprceiated.

# Answer
> 0 votes
you have the target id so just load the term and send the label instead of target id, something like :

```
$tid = $node_detail['field_story_type'][0]['target_id'];
$term  =  \Drupal\taxonomy\Entity\Term::load($tid);
$news_data['type'] = $term->label();

```

**Note:** you are in class it's better to inject `entity.manager` service and change the line `\Drupal\taxonomy\Entity\Term::load($tid);` with something like:

```
$this->entityManager->getStorage('taxonomy_term')->load($tid);

```

---
Tags: 8, entities
---


# Question
Title: How to programmatically add a custom field to Address?
I'm using Address module, and I need to add a Boolean field "Handicap access" for all addresses, whichever country is selected.

I digged into module issues, I carefully read provided docs, where there is an example about how to : *Create a custom address field by repurposing an unused one*.

> What about address field X? Can I add another property to an address field?
>
> No, not without great difficulty. But you can repurpose an unused property for a custom one.

But there is not any boolean existing field into Address fields. Any tip to put me on the right track is welcome. Thanks !

# Answer
> 0 votes
Not sure if this solves your specific problem, but you can create a custom paragraph type with an address field and a boolean field, then add a Paragraph Entity field on your content type. You can limit this paragraph reference field to your newly created paragraph type. This will allow you to have a field with both address/accessibility information.

# Answer
> 0 votes
Since Address module field names follow the OASIS eXtensible Address Language (xAL) standard, I had a look at xAL standard itself but could not find a way to add a *disabled access* field properly following this standard.

So I stuck to the provided doc, not that bad in fact : instead of a boolean customers may have more informations :

In `mymodule.services.yaml`

```
mymodule.subscriber:
  class: Drupal\mymodule\EventSubscriber\DisabledAccessEventSubscriber
  tags:
    - {name: event_subscriber}

```

In `mymodule\EventSubscriber\DisabledAccessEventSubscriber.php`

```
namespace Drupal\mymodule\EventSubscriber;

use Drupal\address\Event\AddressEvents;
use Drupal\address\Event\AddressFormatEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class DisabledAccessEventSubscriber implements EventSubscriberInterface {

  /**
   * @inheritDoc
   */
  public static function getSubscribedEvents() {
    $events[AddressEvents::ADDRESS_FORMAT][] = ['onAddressFormat'];
    return $events;
  }

  public function onAddressFormat(AddressFormatEvent $event) {
    $definition = $event->getDefinition();

    $format = $definition['format'];
    $format = str_replace('%additionalName', '', $format);
    $format = str_replace('%addressLine2', "%addressLine2\n%additionalName", $format);
    $definition['format'] = $format;

    $event->setDefinition($definition);
  }

}

```

In `mymodule.module`

```
/**
 * Modifies Address format to add a PMR field
 */
function mymodule_customize_address($element, $form_state) {
  $element['additional_name']['#title'] = t('Disabled access');
  $element['additional_name']['#description'] = t(
    'Give your customers some details about your store accessibility');

  return $element;
}
function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (($form_id == 'profile_foo_profile_edit_form')) {
    foreach ($form['field_profile_address']['widget'] as $key => $value) {
      if (is_numeric($key)) {
        $form['field_profile_address']['widget'][$key]['address']['#after_build'][] = 'mymodule_customize_address';
      }
    }
  }
}

```

Be what it is, I'll be glad if somebody's able to explain me how to extend Address and add a field to default ones.

---
Tags: 8
---


# Question
Title: Add body classes to 404 and 403 error pages
I need to add a body class to the page when either a 403 or 404 error is served, I'm not sure how to go about this. I'm using logintoboggan which sets the default 403 page to toboggan/denied so don't want to override that and break functionality.

Any pointers would be great.

# Answer
You can implement `hook_preprocess_page()`, and alter the value of `$variables['body_classes']`, which contains a list of CSS classes separated with a comma.
In Drupal 6, code similar to the following one should work:

```
function mymodule_preprocess_page(&$variables) {
  $headers = drupal_get_headers();

  if (preg_match('@HTTP/1\.[01]\x20+403@', $headers)) {
    $variables['body_classes'] .= 'error-403,';
  }
  elseif (preg_match('@HTTP/1\.[01]\x20+404@', $headers)) {
    $variables['body_classes'] .= 'error-404,';
  }
}

```

Replace "error-403" and "error-404" with the actual CSS classes you want to use.

This is similar to the code I have used in a module hosted on Drupal.org, which had to detect when Drupal 6 shown an "access denied" page, or a "page not found" page.
> 6 votes

# Answer
For anyone working with Drupal 7, the function names and the way you pass variables are a bit different. The D7 solution for a 404 would look like this:

```
function MYMODULE_preprocess_html(&$variables) {
  $headers = drupal_get_http_header();

  if (isset($headers['status']) && $headers['status'] == '404 Not Found') {
    $variables['classes_array'][] = 'page-404';
  }
}

```

The drupal\_get\_headers() function from D6 is now drupal\_get\_http\_header() in D7. The values returned are structured a bit differently. You can view the contents of the array with "dpm($headers);" if you're using the devel module.

Finally, additional class variables can be added as elements of the $variables\['classes\_array'\] by assigning them to an empty index, which will then be added to the html body tag via the template\_process() function.
> 7 votes

# Answer
I've created a custom module in order to have a custom twig template for my 404 error page.

I needed to have a custom body class for this page for theming purpose.

Here is what I've done :

```
function MYTHEME_preprocess_html(&$variables) {

    // Check if current request is an exception to get error type
    $status = \Drupal::requestStack()->getCurrentRequest()->attributes->get('exception');

    // add body classes.
    if ($status && $status->getStatusCode() == 404) {
        $variables['attributes']['class'][] = 'path-error-404';
    }

    if ($status && $status->getStatusCode() == 403) {
        $variables['attributes']['class'][] = 'path-error-404';
    }

```

}
> 3 votes

---
Tags: theming
---


# Question
Title: Published checkbox field displaying in form footer instead of node options
In d8.4:

The Published checkbox field, which is part of the publishing options set of fields, is displaying at the bottom of the node edit form instead of with the other publishing options fields.

See screenshot:

I've tried reposition using the Field Group module and also unsetting the form with `unset($form['options']['status']);` and other variations with no success.

All I'd like is for that field to be included in the promotion options fieldset with the rest of the options.

The field is displaying in div.layout-region-node-footer - I' can't track down where that themeing is taking place.

Any help would be appreciated.

# Answer
> 4 votes
NodeForm.php defaults the position to the `'footer'` group:

```
$form['status']['#group'] = 'footer';

```

In a custom module or your theme, this can be set to the `'main'` section:

```
/*
* Implements hook_form_BASE_FORM_ID_alter()
* @param     Array $form, Object $form_state, Array $form_id
* @return    Array $form
*/
function MY_MODULE_form_node_form_alter(&$form, FormStateInterface $form_state,  $form_id) {

    // NodeForm.php defaults this to 'footer'.
    // Set to 'main' so we can reposition it in 'Manage form display'.
    $form['status']['#group'] = 'main';

  return $form;
}

```

After this, it can be repositioned in 'Manage form display'.

# Answer
> 0 votes
Depending on your theme, if the machine name of your main group is not "main" you will get WSOD as described. I my case machine name of the main group is "main\_content".

---
Tags: 8, nodes
---


title: How do I set a cookie?

text:
# Question
Title: How do I set a cookie?
I need to save a cookie for anonymous users in Drupal 8 when users visit the site for the first time, which will be used to display a message.

I can successfully save one using `setcookie("FirstTimer", 1, strtotime('+1 year'));` but I am sure Drupal 8 should have some alternatives.

I can also use the following code.

```
$user_is_first_timer = !isset($_COOKIE["Drupal_visitor_FirstTimer"]);

```

When I open it in Google Chrome, this works, but when I open it in incognito or in Firefox, there is no message. Somehow cached pages are being served.

The code is used in an implementation of `hook_page_attachments()`.

# Answer
With Drupal 7, Drupal 8, and Drupal 9 you could use `user_cookie_save()` to store a cookie.

```
function user_cookie_save(array $values) {
  foreach ($values as $field => $value) {
    // Set cookie for 365 days.
    setrawcookie('Drupal.visitor.' . $field, rawurlencode($value), REQUEST_TIME + 31536000, '/');
  }
}

```

The first parameter is an array, whose keys are the names of the cookies to set and its values are the cookie values.
`user_cookie_save()` doesn't allow to set when a cookie expires; cookies created with this function expires after 365 days.

The only method that in Drupal 8 calls `user_cookie_save()` is `SystemController::compactPage()`.

```
public function compactPage($mode) {
  user_cookie_save(['admin_compact_mode' => $mode == 'on']);
  return $this->redirect('<front>');
}

```

Unfortunately, there isn't an equivalent function to read a cookie. In Drupal 8 and Drupal 9, to read the cookie saved from `SystemController::compactPage()` it's used `system_admin_compact_mode()`.

```
function system_admin_compact_mode() {
  // PHP converts dots into underscores in cookie names to avoid problems with
  // its parser, so we use a converted cookie name.
  return \Drupal::request()->cookies->get('Drupal_visitor_admin_compact_mode', \Drupal::config('system.site')->get('admin_compact_mode'));
}

```

In alternative, in Drupal 8 and Drupal 9, you could store cookies using code similar to the one used by `BigPipeController::setNoJsCookie()` (implemented since Drupal 8.1.x).

```
if ($request->cookies->has(BigPipeStrategy::NOJS_COOKIE) || !$request->hasSession()) {
  throw new AccessDeniedHttpException();
}
if (!$request->query->has('destination')) {
  throw new HttpException(400, 'The original location is missing.');
}
$response = new LocalRedirectResponse($request->query->get('destination'));

// Set cookie without httpOnly, so that JavaScript can delete it.
$response->headers->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE, 0, '/', NULL, FALSE, FALSE, FALSE, NULL));
$response->addCacheableDependency((new CacheableMetadata())
  ->addCacheContexts([
    'cookies:' . BigPipeStrategy::NOJS_COOKIE,
    'session.exists',
  ]));
return $response;

```

This code used the `$response` object from Symfony, instead of using a PHP function.
It's also more "symmetric," as the same object allows to read and write cookies.

Using `$response->headers->setCookie()` gives more control over the cookie parameters (the parameters `Cookie::__construct()` accepts).
> 13 votes

# Answer
Drupal 8 cookies can be set using `ResponseHeaderBag` from the `Symfony\Component\HttpFoundation\Response` object.

Set new cookie value

```
use Symfony\Component\HttpFoundation\Cookie;

$cookie = new use Cookie('cookie_name', TRUE);
$response->headers->setCookie($cookie);
return $response;

```

Get cookies value

```
$request->cookies->get('cookie_name');

```
> 6 votes

---
Tags: 8, cookies
---


# Question
Title: How to set up a child theme using pattern lab?
I have multisite architecture in drupal 8. and I am using pattern lab in my base theme but now I want to access some component from parent theme to child theme. What would be the best way to create child theme using pattern lab? Thanks in advance.

# Answer
Welcome to Drupal answers.

Patternlab does not have opinion about Drupal theme hierarchy. So given you are maintaining the parent child hierarchy as per Drupal theming structure your child theme must be able to inherit all the component templates from parent to child.

While there could be multiple ways you can go ahead with development in future, one way would be to keep creating new components at parent theme & pattern lab. Patternlab can continue using base theme styling to show the components whereas in Drupal styling(css) would be dynamic via variables which would be decided for what theme you are building.
> 2 votes

---
Tags: 8
---


# Question
Title: paragraphs_update_8018 takes very long time to finish
The `paragraphs_update_8018` update takes very long to complete (we have over 1 mio. paragraphs), as of now it's already been over 1h40m and it's still running. EDIT: it finished after 1h47m

My question is: is it possible to run this update without maintenance mode? I don't want to take the site down for so long for this update.

# Answer
> 0 votes
**Disclaimer: act on your own risk!**

After looking into what this update exactly does, I decided to execute it without maintenance mode. It worked without any problems. It depends on your situation though. You have to make sure that nothing interferes with the tables in question (no editors editing paragraphs, no automatic content imports/updates etc.).

Note that `drush updb` automatically enables maintenance mode, you have to disable it explicitly.

Of course generally speaking it's not a good idea to disable the maintenance mode during `drush updb` and problems may occur.

# Answer
> 0 votes
You can use the query instead of the default drupal update method for this update

```
 UPDATE paragraphs_item_revision_field_data
 INNER JOIN paragraphs_item_field_data  ON (paragraphs_item_revision_field_data.id =
 paragraphs_item_field_data.id && paragraphs_item_field_data.parent_id IS NOT NULL)
 SET paragraphs_item_revision_field_data.parent_id =
 paragraphs_item_field_data.parent_id,paragraphs_item_revision_field_data.parent_type
 = paragraphs_item_field_data.parent_type,
 paragraphs_item_revision_field_data.parent_field_name =
 paragraphs_item_field_data.parent_field_name where
 paragraphs_item_revision_field_data.parent_id IS NULL;

```

as mentioned by btobac

---
Tags: 8, paragraphs
---


title: Prevent node save

text:
# Question
Title: Prevent node save
is there a way to prevent node from being saved? I want to save values form this content type into user profile fields and other profile module fields. Thank you

My code:

```
/**
 * Implements hook_form_alter().
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $form_id
 */
function hospitator_qr_decode_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'node_time_tracker_form') {

    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions'][$action]['#submit'][] = 'hospitator_qr_decode_form_submit';
      }
    }
  }
}

/**
 * Implements custom form submit. Try to prevent node save.
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 */
function hospitator_qr_decode_form_submit($form, FormStateInterface $form_state) {
  $form_state->setRedirect('hospitator_user_interface.main_page');

  \Drupal::messenger()->addMessage(t('Form Custom Submited'), 'status');
  //How to don't save the node?

  return;
}

```

# Answer
Did you try to replace the existing submit handlers with your own?

This adds a submit handler:

```
$form['actions'][$action]['#submit'][] = 'hospitator_qr_decode_form_submit';

```

This replaces the submit handlers:

```
$form['actions'][$action]['#submit'] = ['hospitator_qr_decode_form_submit'];

```
> 3 votes

---
Tags: 8
---


title: Can Views output "raw" text field data?

text:
# Question
Title: Can Views output "raw" text field data?
I have a view that shows the **Body** field of several book pages. The text format for these pages includes the Markdown filter.

I want to export the body field data as the original markdown without processing it into HTML. (This is an admin-only view that I want to use to collect the markdown-formatted text from several book pages to make an ebook.)

Is there an option within the Views module to output the "unprocessed" markdown?

# Answer
> 5 votes
Yes. Under the **Rewrite results \> Override the output of this field with custom text** option, one of the Twig tokens you can use is `{{ $FIELD_NAME__value }}` (e.g. `{{ body__value }}`). This will have views render the field in its raw, pre-filtered, format.

---
Tags: views
---


# Question
Title: How to handle the cache per user in REST Resource?
I have a requirement to expose a specific content type data via REST end point. Below is my code:

```
public function get() {
    $current_user = $this->currentUser->id();
    $user = $this->entityTypeManager->getStorage('user')->load($current_user);
    $userLangId = $user->language()->getId();

    // You must to implement the logic of your REST Resource here.
    // Use current user after pass authentication to validate access.
    if (!$this->currentUser->hasPermission('access content')) {
      throw new AccessDeniedHttpException();
    }
    $news_values = [
      'langcode' => $userLangId,
      'type' => ['story'],
      'status' => 1,
    ];
    $news_data = $this->entityTypeManager->getStorage('node')->loadByProperties($news_values);
    $newsfeed = [];
    $newsfeed['stories'] = ['Story' => array_values($news_data)];
    if (empty($newsfeed)) {
      return new ResourceResponse('No Newsfeed exist for this user.', 400);
    }
    $response = new ResourceResponse($newsfeed, 200);
//    $response->addCacheableDependency($current_user);

    $response->addCacheableDependency(CacheableMetadata::createFromRenderArray([
      '#cache' => [
        'context' => ['user.roles'],
        'tags' => ['user:3', 'languages:' . $userLangId],
      ],
    ]));
    return $response;
  }

```

I am getting a proper response with this but I am facing issues in handling the cache. This content is user specific. Based on user language content will popup when they access.

In Response Headers I am getting below things:

```
X-Drupal-Cache-Contexts: languages:language_interface theme url.site user.permissions
X-Drupal-Cache-Tags: config:filter.format.basic_html config:rest.resource.newsfeed_rest_resource config:rest.settings config:system.site http_response languages:fr node:7 node:9 user:3
X-Drupal-Dynamic-Cache: MISS/HIT

```

In Cache-tags i have not added node key but its automatically coming and its working once node updated. But if i try to login with different user via `basic auth` on postman client, content is not changing at all. Its showing cached content for previous user. How I can cache the content per user. Please help me in this regard.

# Answer
@Leigh is right and `user` does exist. Cache contexts are hierarchical (see change record https://www.drupal.org/node/2451661) and `user` is a top level context.

So this should work (note the plural form of `contexts`):

```
  '#cache' => [
    'contexts' => ['user'],

```

You can also add the cache context by IDE autocompleting:

```
$response->getCacheableMetadata()->addCacheContexts(['user']);

```
> 3 votes

---
Tags: caching, 8, meta-tags, http-request
---


# Question
Title: Sending multiple attachment files by email
I am trying to send multiple files attached to an email, but I can only make it work when only one file is attached. I am using mandrill mailer, btw.

Here is the code I have on a form submit:

```
    $attachments = [];
    if ($files) {
      foreach ($files as $key => $value) {
        $file = File::load($value['target_id']);
        $attachments[] = [
          'filepath' => $file->getFileUri(),
          'filename' => $file->getFileName(),
          'filemime' => $file->getMimeType(),
        ];
      }
    }

    $mailManager = \Drupal::service('plugin.manager.mail');
    $module = 'mymodule';
    $langcode = \Drupal::currentUser()->getPreferredLangcode();
    $params = [
      'subject' => 'Application from ' . $applying_user->get('field_first_name')->value . ' ' . $applying_user->get('field_last_name')->value,
      'candidate_name' => $applying_user->get('field_first_name')->value . ' ' . $applying_user->get('field_last_name')->value,
      'attachments' => $attachments,
    ];
    $mailManager->mail($module, 'email_application', $user_email, $langcode, $params);

```

Then using hook\_mail():

```
 case 'email_application':
      $message['from'] = \Drupal::config('system.site')->get('mail');
      $message['subject'] = $params['subject'];
      $message['body'][] = buildBodyMail($params);
      $message['attachments'] = $params['attachments'];
      break;

```

The email I receive does not have any attachment, even though there are 4 files in this particular example meant to be attached.

If I change the code to:

```
    if ($files) {
      foreach ($files as $key => $value) {
        $file = File::load($value['target_id']);
        $attachments = [
          'filepath' => $file->getFileUri(),
          'filename' => $file->getFileName(),
          'filemime' => $file->getMimeType(),
        ];
      }
    }

```

...then it attaches only the last file of the set. It seems that

```
$message['attachments']

```

does not allow a multidimensional array. I've seen examples with

```
$message['params']['attachments'] = $params['attachments'];

```

and have tried but to no avail.

How can multiple files be attached to an email? Thanks in advance.

# Answer
Try as $message\['attachments'\]\[\] instead of $message\['attachments'\] example $message\['attachments'\]\[\] = $params\['attachment2'\];
> 0 votes

---
Tags: 8, emails
---


# Question
Title: How do I update the configuration of a module?
I'm building a custom module in Drupal 8. It includes some YAML config files.

As I develop I need to change and add to the config, e.g. to add another field onto my custom entity.

At present the only way I've found to get Drupal to notice the changes is to uninstall the module and re-install it.

Is there a way to get Drupal to check that the config files provided by modules is the same as the active config, and if not, update the active config? How are module updates handled? In D7 `hook_update_N` would be used to add fields using PHP, but it looks like this should be handled by the CM in D8?

Things I've tried after updating the yml files in the module:

1. `drush cr`, config sync.
2. manually copying all the updated config files into `sites/default/files/config_XXX/staging/` \- but this gives this error *"The staged configuration cannot be imported, because it originates from a different site than this site. You can only synchronize configuration between cloned instances of this site."*.
3. manually importing the files one by one using the config manager. This works, but obviously there must be a more automatic way.
4. \[EDIT\] manually use the config\_update module to inspect changes and 'revert' to the module's config. Again, this is manual.

**EDIT:** From Managing configuration - do's and don'ts

> **DON'TS**
>
> Try to change the active configuration on your site by changing files in a module's config/install directory. This will NOT work because Drupal will only read from that directory when the module is installed.

...but changes there are *going* to happen, unless modules are bound to whatever config they needed in their first ever release, and may never ever update or add config.

Thanks in advance.

# Answer
As mentioned in the original question, and follow-up comments, there are a variety of contrib modules and manual methods to accomplish this.

To do it automatically, or in a custom fashion, I think `hook_update_N()` is still probably the most viable option.

For instance, this is an example from the Head 2 Head to update `system.site` to set the `default_langcode`:

```
  $config_factory = \Drupal::configFactory();
  $langcode = $config_factory->get('system.site')->get('langcode');
  $config_factory->getEditable('system.site')->set('default_langcode', $langcode)->save();

```

You can also read in config (recommended only for adding new config, not necessarily updating or overriding config that may have been customized):

```
  $source = new FileStorage($path);
  /** @var \Drupal\Core\Config\StorageInterface $active_storage */
  $active_storage = \Drupal::service('config.storage');
  $active_storage->write($name, $source->read($name));

```

where `$path` is the absolute path to the `my_config.foo.yml` file.
> 33 votes

# Answer
I've found this Gist on GitHub, which reverts/reloads given module's configuration using drush:

```
drush cim -y --partial --source=modules/path/to/module/config/install/

```
> 19 votes

# Answer
As I landed on this question as well but did not really find the correct answer for my situation here, I'd like to add another answer.

# Please note: Anti-pattern ahead!

## Use case

When we're developing projects we constantly update our test / acceptance environment with new configuration updates. Take for example a simple fictional News-module, we'd like to add a content-type to the module and deploy this to our acceptance environment. After review, we have concluded there are a few fields missing and other config-related stuff. Since we know the acceptance environment is not being updated in config, we really only want to reload the entire config from the module while added new functionality and not be bothered by importing every changed `.yml` file.

We only need our config in modules when we're developing multisites. For single sites, we mostly just use exported site config in which the next step is unnecessary .

## Reimport config entirely (anti-pattern!)

We found that using the ConfigInstaller service, we're able to reimport the complete config again from a specific module.

```
// Implement in a update_N hook.
\Drupal::service('config.installer')->installDefaultConfig('module', $module);

```

## Use with caution!

I'd like to add that this will overwrite any active content that has been altered within the environment. So, only use this solution when you are sure it's safe to overwrite the active config. We'll never use this on a production environment and will only apply in early development.

First try out @jhedstrom's solution before you begin considering this one.
> 14 votes

# Answer
Based on my comment: How do I update the configuration of a module?

> When I am following the second approach the config is written to Drupal but is not getting an UUID even when I export it to the config directory. This lead me into a problem where I tried this with a custom View. The Views overview page returned me an fatal error since the uuid for the Config entity was not available.

I have created a little function that helps me with that, here my example code:

```
function _example_views_update_config($configsNames) {
  $config_path    = drupal_get_path('module', 'example') . '/config/install';
  $source         = new FileStorage($config_path);
  $config_storage = \Drupal::service('config.storage');
  $config_factory = \Drupal::configFactory();
  $uuid_service = \Drupal::service('uuid');

  foreach ($configsNames as $name) {
    $config_storage->write($name, $source->read($name));
    $config_factory->getEditable($name)->set('uuid', $uuid_service->generate())->save();
  }
}

/**
 * Add new action configurations.
 */
function example_update_8003() {
  $configsNames = [
    'config-1',
    'config-2',
  ];

  _example_views_update_config($configsNames);
  return 'Added new configurations.';
}

```
> 4 votes

# Answer
The answer above (full re-import) worked for my use case also, but first I spent a little while looking into a more selective re-import. Here's the code I had which seemed to work as an update hook and was based on code in the config\_update module:

```
/**
 * Update all my config.
 *
 * This can be more selective than calling installDefaultConfig().
 */
function MYMODULE_update_8004() {
  $prefixes = [
    'field.storage.node',
    'field.field.node',
    'node.type',
    'core.base_field_override.node',
    'core.entity_view_display'
  ];
  $results = [];
  foreach ($prefixes as $prefix) {
    $results[$prefix] = _update_or_install_config($prefix);
  }
  $return = '';
  foreach ($results as $prefix => $result) {
    $return .= "\n$prefix:\n";
    foreach ($result as $key => $ids) {
      $return .= "$key: " . implode(', ', $ids) . "\n";
    }
  }
  if (function_exists('drush_log')) {
    drush_log($return, \Psr\Log\LogLevel::WARNING);
  }
  return $return;
}

/**
 * Update or install config entities from config/install files.
 *
 * @see \Drupal\config_update\ConfigReverter::import
 * @see \Drupal\config_update\ConfigReverter::revert
 *
 * @param string $prefix
 *   The prefix for YAML files in find, like 'field.storage.node'
 */
function _update_or_install_config($prefix) {
  $updated = [];
  $created = [];
  /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manger */
  $config_manger = \Drupal::service('config.manager');
  $files = glob(__DIR__ . '/config/install/' . $prefix . '.*.yml');
  foreach ($files as $file) {
    $raw = file_get_contents($file);
    $value = \Drupal\Component\Serialization\Yaml::decode($raw);
    if (!is_array($value)) {
      throw new \RuntimeException(sprintf('Invalid YAML file %s'), $file);
    }
    // Lazy hack here since that code ignores the file extension.
    $type = $config_manger->getEntityTypeIdByName(basename($file));
    $entity_manager = $config_manger->getEntityManager();
    $definition = $entity_manager->getDefinition($type);
    $id_key = $definition->getKey('id');
    $id = $value[$id_key];
    /** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $entity_storage */
    $entity_storage = $entity_manager->getStorage($type);
    $entity = $entity_storage->load($id);
    if ($entity) {
      $entity = $entity_storage->updateFromStorageRecord($entity, $value);
      $entity->save();
      $updated[] = $id;
    }
    else {
      $entity = $entity_storage->createFromStorageRecord($value);
      $entity->save();
      $created[] = $id;
    }
  }
  return [
    'updated' => $updated,
    'created' => $created,
  ];
}

```
> 2 votes

# Answer
Configuration Synchronizer module helps to solve this issue in a nice way. This module suite of 7 modules seems to be a bit overkill just for this case (its intention is mainly to safely merge in updates without overwriting customizations), but because of its concept it also allows to track and import configuration changes from module's /install and /optional folders quickly.

Basically, you can test it like following:

* create and enable your custom module on your local environment with some "default" configuration item(s) placed in /config/install folder as usual
* install and enable config\_sync module and all its dependent modules
* do some edits in your module's config item inside of /config/install folder
* access /admin/config/development/configuration/distro . You should see your change and have option to import it into the active configuration (Merge mode is intended to preserve the client changes, Reset mode forces import) - during development I will mostly use Reset mode, but merge mode should work as well unless you did any manual changes in the same configuration in parallel

Note: if you **only** want to use the config\_sync to accelerate config import during module's development (and you don't care about merging in with client updates), it's enough to have this suite installed and enabled on your local (development) environment only (assuming your module will go to higher environments after finalizing and you use the D8 core config management to post its configuration to higher environments).
> 1 votes

# Answer
I discovered this post after trying to add some new config to an existing custom module and `drush cex` wasn't picking it up. I tried the accepted answer using `hook_update_N()` but still no luck.

Turns out the project has https://www.drupal.org/project/config\_ignore enabled, with the relevant `*.settings.yml` ignored at `/admin/config/development/configuration/ignore`
> -1 votes

---
Tags: 8, updating, configuration
---