# Question
Title: config-import error: These entities need to be deleted before importing
I have two Drupal environments with the same `system.site:uuid`

In the main Drupal I export the configuration with command:

```
drush config-export deploy -y

```

In the destination drupal I import the configuration with command:

```
drush config-import deploy -y

```

But I have this error

> Entities exist of type Shortcut link and Default. These entities need to be deleted before importing.

And:

> Unable to install the mytest theme since it does not exist.

My test was a test for create subtheme, but then I delete mytest form drupal. And I don't know what it exports now, and, placeholder I don't Know what is it

I followed this article And I have the same issue of this comment

# Answer
> 6 votes
Sounds like you deleted your test theme without uninstalling it. You either have to properly uninstall it, which might not be possible when it's not there or edit the core.extension.yml file in your exported config and remove it by hand.

About the other error, it looks like you are either really deleting shortcut/menu link types or, more likely, you manually "fixed" the system.site UUID. That check and UUID exists for a reason, just changing it to the same value on two different installations will do a lot of unexpected things. You would have to update lots of other UUID's too, otherwise Drupal will delete and re-create pretty much every single configuration entity in your system. Due to the changed UUID, it assumes you deleted and re-created it, so that's what it is trying to do.

And since it prevents you from deleting bundle config entity types when there is still content for that type/bundle, it gives you that error.

What is it that you are trying to do exactly? Maybe you're looking for Config Installer instead?

# Answer
> 11 votes
For:

> Entities exist of type Shortcut link and Default. These entities need to be deleted before importing.

You need delete the entities of type `short-cut`, you can do with drush:

```
drush ev '\Drupal::entityManager()->getStorage("shortcut_set")->load("default")->delete();'

```

# Answer
> 8 votes
About the first error (Entities exist of type Shortcut link and Default. These entities need to be deleted before importing.):

I went to Home \> Administration \> Configuration \> User interface \> Shortcuts (admin/config/user-interface/shortcut), than in "List links" of "Default" I deleted every shortcut.

The error is gone now.

# Answer
> 6 votes
Whenever you get this type of error, you need to delete the entities first.

Here's a generic Drush command that will delete any entity type, unlike another answer here. Just set the machine name in the first PHP command.

```
drush @site eval '$entity_type = "my_entity_type"; $storage_handler = \Drupal::entityTypeManager()->getStorage($entity_type); $storage_handler->delete($storage_handler->loadMultiple(\Drupal::entityQuery($entity_type)->execute()));'

```

# Answer
> 1 votes
Using the answers above as a base the following worked for me:

To delete entities of a specific bundle, replace the first 2 values accordingly on the script and save it on a file.

```
$entity_type = "paragraph";
$type = "contact";

$storage_handler = \Drupal::entityTypeManager()->getStorage($entity_type);
$entities_to_delete = \Drupal::entityQuery($entity_type)
  ->condition('type', $type)->execute();
$storage_handler->delete($storage_handler->loadMultiple($entities_to_delete));

```

Then run `drush php:script to-delete-entities.php`

# Answer
> 1 votes
An easy way using drush nowadays: `drush edel [entity_type] --bundle=[bundle_name]`

```
drush edel shortcut_set --bundle=default

```

---
Tags: 8, configuration
---


# Question
Title: Programmatically remove duplicated nodes without changing the number of nodes shown per page
I have a content type called *Página de área* (*Area page*) referenced by two content type: *Article* and *Agrupador*. I have a view that displays all the *Article* nodes that share at least one area with an *Agrupador* node.

My goal is removing the duplicate nodes (I get calling `$query->addWhere()`) from the view.
I already tried using the *Distinct* and *Aggregation* options in the user interface, but they didn't work for me. I'm aware that this can be achieved using `hook_views_pre_render()`, but if (for example) I have 10 nodes per page and two nodes are duplicates, the view ends up showing eight nodes instead of 10.

I also tried what shown in Update view result and pager in hook\_views\_pre\_render() and in Distinct doesn't work when sorting by field with multiple values using the following code.

```
/**
 * Implements hook_views_query_alter().
 */
function gcaba_agrupador_views_query_alter(ViewExecutable $view, Sql $query) {
  if ($view->id() == 'noticias_agrupador' && $view->current_display == 'noticias_agrupador') {
    $agrupador = \Drupal::routeMatch()->getParameter('node');
    if ($agrupador instanceof NodeInterface) {
      $agrupador = Node::load($agrupador->id());
      $areas = explode(',', $agrupador->field_area->getString());
      $areasArray = array_map('intval', $areas);
      $query->addWhere(0, 'node__field_area.field_area_target_id', $areasArray, 'IN');
    }
  }
}

```

# Answer
> 0 votes
```
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implements hook_views_query_alter().
 *
 * @param \Drupal\views\ViewExecutable $view
 * @param \Drupal\views\Plugin\views\query\QueryPluginBase $query
 */
function gcaba_agrupador_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'noticias_agrupador' && $view->current_display == 'noticias_agrupador') {
    $agrupador = \Drupal::routeMatch()->getParameter('node');
    if ($agrupador instanceof \Drupal\node\NodeInterface) {
      $agrupador = \Drupal\node\Entity\Node::load($agrupador->id());
      $areas = explode(',', $agrupador->field_area->getString());
      $areasArray = array_map('intval', $areas);

      $query->addWhere(0, 'node__field_area.field_area_target_id', $areasArray, 'IN');

      // Remove duplicates using DISTINCT.
      $query->distinct();
    }
  }
}

```

---
Tags: 8, views
---


title: Removing phantom plugin from database

text:
# Question
Title: Removing phantom plugin from database
On several sites I've worked on, for whatever reason before I put my hands on it, the database seems to register a plugin that is no longer in config or code.

This usually goes as follows:

`[error] Drupal\Component\Plugin\Exception\PluginNotFoundException: The "name-of-plugin" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager->getDefinition()`

In D7, it was relatively straightforward to delete offending module entries from the database. What tables store plugin data so I can tell Drupal to stop looking for them and whitescreening when they can't be found?

# Answer
Export the entire config, either in UI or via `drush cex`. Then make a full-text search for the plugin name. Remove the configuration causing the error and import the config again `drush cim`.

BTW if you turn on full error messages at *admin/config/development/logging* you see more info on which code is trying to load the plugin. This can point to a code line using a config object or a hard-coded plugin name.

If you can't access the admin UI because of the error add this option to settings.php:

```
/**
 * Show all error messages, with backtrace information.
 *
 * In case the error level could not be fetched from the database, as for
 * example the database connection failed, we rely only on this value.
 */
$config['system.logging']['error_level'] = 'verbose';

```

Or activate `web/sites/example.settings.local.php` from where this is copied.
> 6 votes

---
Tags: plugins
---


# Question
Title: Why does twig tweak's drupal_field() function convert special characters to HTML entities?
I'm using the following inside views to change the page title to the term name but it renders term names with & in them as `&`

In the views override title section I'm using.

`{{ drupal_field('name', 'taxonomy_term', arguments.tid) }}`

I have tried adding render|striptags at the end of the function but that doesn't seem to work.

# Answer
An option is to try removing the auto escaping of the output with twig's autoescape tag

In this case, the code would look something like

```
{% autoescape false %}
  {{ drupal_field('name', 'taxonomy_term', arguments.tid) }}
{% endautoescape %}

```

Also, as already suggested in the comments, the raw filter could be used. Note however it is not considered safe, so in case of usage, one should be certain the data is not harmful. Combination of both could be helpful as well.
> 0 votes

---
Tags: views
---


# Question
Title: managed_file upload clearing $form_state
I am having an annoying problem whereby $form\_state\['values'\]\['region'\] and $form\_state\['values'\]\['country'\] are being cleared when I upload an image via the managed\_file field. This is causing a "...tid cannot be null" error upon DB insertion (of course because the values are now null after managed\_file upload). If I disable the managed\_file field everything works as it should but of course I need the upload!

I am relatively new to Drupal and thus not quite understanding why this is acting like it is. Can anyone help me out as this is driving me nuts!

**My form**

```
function myforms_company_add_form($form, &$form_state, $node) {

  $form['#prefix'] = '<div id="wrapper">';
  $form['#suffix'] = '</div>';

  if(!isset($form_state['values']['region']) && !isset($form_state['values']['country'])) {
      $selectedRegion = array_shift(taxonomy_get_parents($node->field_company_region['und'][0]['tid']))->tid;
      $selectedCountry = $node->field_company_region['und'][0]['tid'];
    }
    else {
        $selectedRegion = $form_state['values']['region'];
        $selectedCountry = $form_state['values']['country'];
    }

$form['region'] = array(
    '#title' => t('Region'),
    '#type' => 'select',
    '#required' => TRUE,
    '#options' => _get_region_list('region'),
    '#prefix' => '<div id="contact-selector"><div id="region-wrapper">',
    '#suffix' => '</div>',
    '#default_value' => $selectedRegion,
    '#ajax' => array(
      'callback' => 'region_ajax_callback',
      'wrapper' => 'wrapper',
     ),
  );

  $form['country']['wrapper'] = array(
    '#type' => 'markup',
    '#prefix' => '<div id="country-wrapper">',
    '#suffix' => '</div></div>',
  );

  if (isset($selectedRegion)) {
    $form['country'] = array(
        '#title' => t('Country'),
        '#type' => 'select',
        '#required' => TRUE,
        '#options' => _get_country_list($selectedRegion),
        '#default_value' => $selectedCountry,
        '#ajax' => array(
            'callback' => 'region_ajax_callback',
            'wrapper' => 'wrapper',
        ),
      );
   }

  $form['company_logo'] = array(
    '#title' => t('Logo'),
    '#type' => 'managed_file',
    '#upload_location' => 'public://my-files/',
    '#required' => FALSE,
    '#default_value' => $node->field_company_logo['und'][0]['fid'],
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#prefix' => '<hr>',
  );

  return $form;

}

```

**Then my callback**

```
function region_ajax_callback($form, &$form_state) {
  return $form;
}

```

# Answer
> 1 votes
I recently encountered the same problem. I found that data is erased in function - drupal\_validate\_form(). I have not fully understood why this is happening, therefore, just went bypassed the problem. I have rewritten my code so that the code section that erased the data in drupal\_validate\_form() is not executed.

My code:

```
  $managed_file_processing_fn = array_merge(
    element_info_property('managed_file', '#process', array()),
    array('ccw_managed_file_process')
  );

  $form['customization']['main']['request_design']['upload_design'] = array(
    '#type' => 'managed_file',
    '#progress_indicator' => 'bar',
    '#upload_location' => 'public://',
    '#upload_validators' => array(
      'file_validate_extensions' => array('jpg jpeg gif png zip rar tar'),
    ),
    '#states' => array(
      'visible' => array(
        ':input[name="type_of_upload"]' => array(
          array('value' => strval(CCW_GET_HELP)),
        ),
      ),
    ),
    '#process' => $managed_file_processing_fn,
    '#default_value' => $upload_design,
  );

/**
 * Process managed_file.
 */
function ccw_managed_file_process($element, &$form_state, $form) {
  // When AJAX is execute we ignore form validation.
  $element['upload_button']['#limit_validation_errors'] = FALSE;
  $element['remove_button']['#limit_validation_errors'] = FALSE;

  return $element;
}

```

Topic with the same problem on drupal.org: https://www.drupal.org/node/2311199

Also, I noticed that in Drupal 8 the behavior is the same.

# Answer
> 0 votes
Have modified function from the previous example. Filtering of non-empty values for `#limit_validation_errors` prevents validation errors of required but empty fields, and passes all non-empty values in `form_state`

```
function ccw_managed_file_process($element, &$form_state, $form) {
  $limit_validation_errors = array_map(
    function ($value) {
      return [$value];
    },
    array_keys(array_filter($form_state['values']))
  );
  // When AJAX is execute we ignore form validation.
  $element['upload_button']['#limit_validation_errors'] = $limit_validation_errors;
  $element['remove_button']['#limit_validation_errors'] = $limit_validation_errors;

  return $element;
}

```

---
Tags: 7, forms, ajax
---


# Question
Title: Use specific theme [not template file] for 404 and 403 generated for specific path
I have 2 themes, both enabled, assume they are called `my_first_theme` (default) and `my_second_theme`. I have `/whatever` path and lots of the pages under this path, and I have a theme negotiator, which sets `my_second_theme` as an active one for any page under this `/whatever` path, including nodes, views, custom controllers etc.

So far it works good. Problem is, when 404 or 403 is triggered, the theme used to generate the response is always the default one (`my_first_theme`).

What I need is when 404 or 403 response is generated for any path under `/whatever` path, I would like the `my_second_theme` to be used for those templates, not the default one. The only way to achieve it at this moment I see is that I create a copy of the frontend stuff under `my_first_theme` just to be used for 404 and 403 purposes, but that's definitely a dirty way to do that. Basically I will have a clone of `my_second_theme` assets under the `my_first_theme` folder just to serve 404 and 403 responses.

Few examples of what I would like to achieve:

* `/nonexistent404` \- `my_first_theme` used
* `/exists/but/access/denied403` \- `my_first_theme` used
* `/whatever/nonexistent404` \- `my_second_theme` used
* `/whatever/path/exists/but/no/access403` \- `my_second_theme` used

# Answer
How does the theme negotiator get the path?

In a sub-request for a 403/404 error page you are probably looking for the path of the main request:

```
$main_request = \Drupal::requestStack()->getMainRequest();
$path = \Drupal::service('path.current')->getPath($main_request);

```
> 1 votes

---
Tags: theming, 9, event-subscribers, 10, theme-negotiation
---


# Question
Title: Disabling (or overriding) a css file from contrib module's library
I am using admin\_toolbar module and I would like to override the path to a logo file that is by default provided by one of this module's CSS file.

I found information that I can achieve this with *libraries-override* in my theme.info.yml file.

The problem is that the file seems to be still loaded when I check the page source.

The file that defines the path to a logo file is located in:

> /modules/contrib/admin\_toolbar/admin\_toolbar\_tools/css/tools.css

And my theme.info.yml file looks like this:

```
name: Custom Olivero Theme
type: theme
description: 'Custom Olivero Theme.'
package: Custom Themes
core_version_requirement: ^8 || ^9
libraries:
  - custom_olivero/global-styling
base theme: olivero
libraries-override:
  admin_toolbar_tools/toolbar.icon:
    css:
      theme:
        /modules/contrib/admin_toolbar/admin_toolbar_tools/css/tools.css: false

```

Can you please share any suggestions on what am I doing wrong or, if this approach is not following the good Drupal practices, suggest what is the better way of achieving the same result?

# Answer
> 2 votes
The content of the admin\_toolbar\_tools.libraries.yml file is the following.

```
toolbar.icon:
  css:
    theme:
      css/tools.css: {}

```

You remove that file with the following override.

```
libraries-override:
  admin_toolbar_tools/toolbar.icon:
    css:
      theme:
        css/tools.css: false

```

You do not need to use the full file path, but the path used in the .libraries.yml file for that module.

---
Tags: theming, 9
---


# Question
Title: How can I delete an item depending on the processing result?
I have a queue that is processed while cron run. `processItem($data)` checks some requirements.

How can I delete an item when some requirements are not met? Can I update an item (the `$data` array) and "mark" it for deletion in another cron job?

# Answer
> 3 votes
Every item passed to `processItem()` is automatically deleted once `processItem()` returns, except in the case `processItem()` throws an exception. In that case, Drupal will log the exception and leave the item in the queue to be processed again later. If then `processItem()` throws `\Drupal\Core\Queue\SuspendQueueException`, Drupal will log the exception, leave the item in the queue, and not use other items from that queue until the next cron run.

See the code in `Cron::processQueues()`.

```
while ($this->time->getCurrentTime() < $end && ($item = $queue->claimItem($lease_time))) {
  try {
    $queue_worker->processItem($item->data);
    $queue->deleteItem($item);
  } catch (DelayedRequeueException $e) {
    // The worker requested the task not be immediately re-queued.
    // - If the queue doesn't support ::delayItem(), we should leave the
    // item's current expiry time alone.
    // - If the queue does support ::delayItem(), we should allow the
    // queue to update the item's expiry using the requested delay.
    if ($queue instanceof DelayableQueueInterface) {
      // This queue can handle a custom delay; use the duration provided
      // by the exception.
      $queue->delayItem($item, $e->getDelay());
    }
  } catch (RequeueException $e) {
    // The worker requested the task be immediately requeued.
    $queue->releaseItem($item);
  } catch (SuspendQueueException $e) {
    // If the worker indicates there is a problem with the whole queue,
    // release the item and skip to the next queue.
    $queue->releaseItem($item);
    watchdog_exception('cron', $e);

    // Skip to the next queue.
    continue 2;
  } catch (\Exception $e) {
    // In case of any other kind of exception, log it and leave the item
    // in the queue to be processed again later.
    watchdog_exception('cron', $e);
  }
}

```

---
Tags: queue
---


# Question
Title: Grant a permission for the current page load
What is the best way to grant a user permission dynamically for a single page load? In other words, I want Drupal to behave as if the user has a certain permission when it loads the page, depending on conditions. But I don't want to save the permission to the user's account.

It's fine if Drupal doesn't respect the temporary permission after the page loads. The user can interact with the page as if they no longer have that permission. But I want the page to load as it would if the user had the dynamically assigned permission.

**Use case:**

The site uses **Workbench Access** to control access in different content sections, and the core **Content Moderation** module to provide workflow transitions and associated permissions.

The project requires users to have access to different workflow transitions **per content section**. However, Content Moderation does not provide workflow transition permissions per role per content section -- it does not directly integrate with the contributed Workbench Access module, in other words.

Thus, out of the box, it is not possible to give a user access to workflow transition X for one content section, and transition Y for a different content section. So far, the only solutions I have been able to think of are, arguably, hacks. For example, we can check for a section-specific role in hook\_form\_alter and add/remove transition options from the state dropdown (Draft, Needs Review, Published, etc) accordingly. Another possible solution, arguably also a hack, is to modify the user's permissions conditionally when the node edit form loads, effectively presenting the state dropdown as if the user has (or does not have) permission for the relevant workflow transition(s) for that content section. In this way, we could permit Jane Smith to publish content to one section (defined in Workbench Access), while allowing Jane Smith to submit drafts, but not publish anything, in a different content section.

**Update:** The more I think of it, this use case will likely be very difficult to support. It would not suffice to alter the user's role/permission when the node edit form loads. The project requires that the user be able to re-assign content from one section to another, which would in turn require that the state options be altered each time the user changes the value of the taxonomy term field responsible for assigning the content to a section. It is, strictly speaking, possible to achieve, but would require AJAX. It seems unlikely any solution exists that is reasonably clean and maintainable.

# Answer
> 3 votes
Grant a permission by adding a role temporarily when the account is set for the page load, which triggers the AccountEvents::SET\_USER event:

*/mymodule/src/EventSubscriber/SetAccountSubscriber.php*

```
<?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\Core\Session\AccountEvents;
use Drupal\Core\Session\AccountSetEvent;
use Drupal\Core\Session\UserSession;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * mymodule event subscriber.
 */
class SetAccountSubscriber implements EventSubscriberInterface {

  /**
   * Account set event handler.
   *
   * @param \Drupal\Core\Session\AccountSetEvent $event
   *   Account set event.
   */
  public function onAccountSet(AccountSetEvent $event) {
    $account = $event->getAccount();
    if ($account->isAuthenticated()) {
      $roles = $account->getRoles();
      if (!in_array('administrator', $roles)) {
        $roles[] = 'administrator';
        $account = new UserSession([
          'uid' => $account->id(),
          'access' => $account->getLastAccessedTime(),
          'roles' => $roles,
          'name' => $account->getAccountName(),
          'preferred_langcode' => $account->getPreferredLangcode(),
          'preferred_admin_langcode' => $account->getPreferredAdminLangcode(),
          'mail' => $account->getEmail(),
          'time_zone' => $account->getTimeZone(),
        ]);
        \Drupal::currentUser()->setAccount($account);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      AccountEvents::SET_USER => ['onAccountSet'],
    ];
  }

}

```

This code is only for demonstration purposes, it adds admin privilege to all logged-in users. Also, you have to check for the added role because this event is triggered again when setting the new account, to avoid an infinite loop.

You might want to create a specific role containing the permission you wish to grant for the page load.

Register the service:

*/mymodule/mymodule.services.yml*

```
services:
  mymodule.set_account_subscriber:
    class: Drupal\mymodule\EventSubscriber\SetAccountSubscriber
    tags:
      - { name: event_subscriber }

```

**"Use Case" & "Update"**

In the use case added to the question things are getting more dynamic and I think are too complicated to be answered in one question. If you want to continue on this path you can try to define a custom account class implementing AccountInterface which allows you to change the account roles dynamically or even make the account object more intelligent to calculate permissions depending on states you set during the request. Of course, you can also try to tackle the problem from the other side, with access code you add to the components involved, as described in the comments.

---
Tags: 9
---


title: Hide active term from the term page

text:
# Question
Title: Hide active term from the term page
I have an article content type that has a taxonomy reference field that stores the author name. It can hold multiple authors in case the article is authored by more than one author.

As per the image given below, on the author term view page, I need to show only the co-authors names, hiding the current author. ie, if I take the **Author1**'s page, the authors field should hide the **Author1**'s name from the display and show other authors names only.

Is it possible to achieve this using views?

# Answer
I did this using the views with the help of contextual filters.

1. Created a view block with taxonomy terms - unformatted list of fields.
2. Added only Name Field

3. In contextual filters, selected Term ID and configured the following way:
a. When the filter value is NOT available - Provide default value: Taxonomy Term ID from URL and select "Load default filter from term page"

b. In the more section, select "Exclude" option. This is the option which does the magic. This will remove the filtered value from the view display
> 1 votes

---
Tags: 8, views, taxonomy-terms
---


title: How to take a site offline using Drush?

text:
# Question
Title: How to take a site offline using Drush?
How can I take a site offline using Drush?

# Answer
> 143 votes
Drupal 8: `drush sset system.maintenance_mode TRUE`

Drupal 7: `drush vset maintenance_mode 1`

Drupal 6: `drush vset site_offline 1`

# Answer
> 15 votes
First you should cd into the correct directory so that you are within the Drupal directory. If you are using a multi site installation cd into the correct sites/sitename directory or specify the correct -l setting

In Drupal 6 only this command is actually required:

```
$ drush vset --yes site_offline 1;

```

Also in Drupal 6 you can use the following commands if you wish to specify a message to show to the users of the site whilst it is down.

```
$ drush vset --yes site_offline_message "This site is being maintained";
$ drush vset --yes site_offline 1;

```

In Drupal 7 use following command to put the site into maintenance mode:

```
$ drush vset --yes maintenance_mode 1;

```

To set an a specific message use:

```
$ drush variable-set --yes maintenance_mode_message "This site is being maintained"

```

It could be necessary to clear caches that the changes of these variables take effect:

```
$ drush cc all

```

# Answer
> 3 votes
To do this with Drupal 8 and Drush 8.x use the `state-set` command:

`drush sset system.maintenance_mode 1`

At first, I assumed this would be something I would set with `drush config-set system.maintenance`, however the only keys in that configuration are `message` (the message displayed when maintenance mode is enabled) and `langcode` (the language code for said message).

# Answer
> 0 votes
This is controlled by a variable, site\_offline.

```
$ drush vset --always-set site_offline 1

```

You could also set the offline message this way.

```
$ drush vset --always-set site_offline_message 'Please try again later!'

```

# Answer
> 0 votes
From Drupal 6 use:

```
drush vset site_offline 1

```

To take it out of maintenance:

```
drush vset site_offline 0
drush cc all

```

# Answer
> 0 votes
For Drupal 8 and onward:

```
drush sset system.maintenance_mode 1
drush cr

```

Important to not forget clearing cache afterward, if you are running a devOps system.

# Answer
> 0 votes
For Drupal 9 onwards:

Enable Maintenance Mode

```
drush state:set system.maintenance_mode 1 --input-format=integer

```

Disable Maintenance Mode

```
drush state:set system.maintenance_mode 0 --input-format=integer

```

After running this, do not forget to clear caches:

```
drush cr

```

Thank you.

---
Tags: drush
---


# Question
Title: Creating twig template for rows in a specific view
Hi I have a view with the machine name news\_filter. In the html every content type it's fields are inside a `.views-row` div. I want to create a template for those specific rows and maybe later also for each field too. But I can't find the right naming conventions to do so.

Does anyone have an idea?

# Answer
> 0 votes
The template name would be `views-view-unformatted--news-filter.html.twig`, do clear the cache after adding the template file.

In views you cloud use a display with rendered entity display (Content) and a specific viewmode, use the template suggestion for the entity type, e.g. `node--news--VIEWMODE.html.twig`.

```
#views-view-unformatted--news-filter.html.twig
{% for row in rows %}
    {{- row.content -}}
{% endfor %}

```

```
#node--news--VIEWMODE.html.twig
<div class="news-item">
  <a href="{{ path('entity.node.canonical', {'node': 393}) }}?sort={{ node.id }}" class="use-ajax"
     data-dialog-type="full_screen">
    <article>
      {{ content.field_event_datum }}
      <h3>{{ label }}</h3>
    </article>
    <div class="click"><p>weiterlesen ></p></div>
  </a>
</div>

```

---
Tags: 9
---


# Question
Title: User error : "2" is an invalid render array key dans Drupal\Core\Render\Element::children()
I face off this message on certains pages, somtimes relate to twig template part, sometimes to other things. In watchdog:

```
    User error : "2" is an invalid render array key dans Drupal\Core\Render\Element::children() (/home//www/pfdev/multid9/recommended-project/web/core/lib/Drupal/Core/Render/Element.php ligne 98)
#0 /home//www/pfdev/multid9/recommended-project/web/core/includes/bootstrap.inc(347): _drupal_error_handler_real(256, '"2" is an inval...', '/home/provencef...', 98)
#1 [internal function]: _drupal_error_handler(256, '"2" is an inval...', '/home/provencef...', 98)
#2 /home//www/pfdev/multid9/recommended-project/web/core/lib/Drupal/Core/Render/Element.php(98): trigger_error('"2" is an inval...', 256)
#3 /home//www/pfdev/multid9/recommended-project/web/core/lib/Drupal/Core/Render/Renderer.php(404): Drupal\Core\Render\Element::children(Array, true)
#4 /home//www/pfdev/multid9/recommended-project/web/core/lib/Drupal/Core/Render/Renderer.php(204): Drupal\Core\Render\Renderer->doRender(Array, false)
#5 /home//www/pfdev/multid9/recommended-project/web/core/lib/Drupal/Core/Template/TwigExtension.php(479): Drupal\Core\Render\Renderer->render(Array)
#6 /home//www/pfdev/multid9/recommended-project/vendor/twig/twig/src/Environment.php(418) : eval()'d code(458): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true)

```

The othe rpost on this subject lead me to check my array sinto .theme like:

```
function starter_d9_2022_theme_suggestions_views_view_alter(array &$suggestions, array $variables) {
  $suggestions[] = 'views_view__' . $variables['view']->id();
  // If you want you can add a template suggestion for all views
  // based on their ID:
  $suggestions[] = sprintf('views_view__%s', $variables['view']->id());

  // Or you can check the ID, add suggestions, do whatever you want
  // ...
}
function starter_d9_2022_theme_suggestions_views_view(array $variables) {
  return [
    'views_view_display__' . $variables['view']->current_display,
    // Suggestion pour chaque affichages de la vue
  ];
}

```

but no effect instead of a WSOD. So I have no clue to fix this. Do someone know ?

Thanks

EDIt: after advices, it appear this correction goes wrong in the IDE(VS Code). Because of comment ?

```
function starter_d9_2022_theme_suggestions_views_view(array $variables) {
  //return [
    'views_view_display__' . $variables['view']->current_display;
    // Suggestion pour chaque affichages de la vue
  //];
}

```

# Answer
> 0 votes
It is hard for me to realize what's your goal here, but there are few things to note:

* `$suggestions[] = 'views_view__' . $variables['view']->id();` has the same result as `$suggestions[] = sprintf('views_view__%s', $variables['view']->id());` so you should take one or the other, not both.
* inside this hook: `function starter_d9_2022_theme_suggestions_views_view(array &$variables) {}` (please note the ampersand), one could work directly with the `$variables` array and it's not needed to return anything.

As for the WSOD, in Drupal it's recommended to enable the verbose errors handling on local environment or if it's not possible, at least check the admin's logs for the error.

---
Tags: 9
---


# Question
Title: How can I modify a field using PHP code in "rewrite results"?
Drupal 9.49

PHP 8.0

Views 9.49

I am returning the title field in a view. The title being returned is "XYZ Aberdeen".

I want it to simply return "Aberdeen"

When I click on "Content: Title" and then "Rewrite results" I was hoping I could simply use the following code:

```
<?php print str_replace('XYZ', '', {{ title }}); ?>

```

Can anyone tell me how to do this please?

# Answer
> 4 votes
Instead of PHP you use Twig now in "Rewrite Results" of a Views field:

```
{{ title|replace({'XYZ': ''}) }}

```

Using Twig filters often results in double escaping, so that you see the HTML code of special characters on the screen. A title field shouldn't contain HTML markup, but an ampersand is quite common. Then you can avoid the double escaping by rolling back the first escape in the replace filter:

```
{{ title|replace({'XYZ': '', '&': '&'}) }}

```

# Answer
> 3 votes
Adding a php code this way is discouraged as it might lead to security issues. One option is to use a hook. Here's an example code how to do this in your \*.theme file for example

```
/**
 * Implements hook_views_pre_render().
 */
function your_module_views_pre_render(\Drupal\views\ViewExecutable $view) {
   // Specify the view ID and display ID where you want to override the field title.
   if ('your_view_id' === $view->id() && 'your_display_id' === $view->current_display) {
    // Specify the field name whose title you want to override.
    $field_name = 'your_field_name';

    // Specify the new field title.
    $new_title = 'New Field Title';

    // Loop through each result and modify the field title.
    foreach ($view->result as $key => $result) {
      $view->result[$key]->_entity->{$field_name}->getFieldDefinition()->setLabel($new_title);
    }
  }
}

```

If you don't need to do this for all results, but in general for the view, you can skip the loop and instead target your field directly. More information on the hook's documentation here

# Answer
> 1 votes
one of the way is to create a twig template for your field. And use a replace filter inside this template.

---
Tags: views
---


title: Plugin not found

text:
# Question
Title: Plugin not found
I am overwriting the `CommentBulkForm` class in my module.

```
namespace Drupal\mymod\Plugin\views\field;

use Drupal\comment\Plugin\views\field\CommentBulkForm;

/**
 * Defines a custom comment operations bulk form element.
 *
 * @ViewsField("custom_comment_bulk_form")
 */
class CustomCommentBulkForm extends CommentBulkForm {

  /**
   * {@inheritdoc}
   */
  protected function emptySelectedMessage() {
    return $this->t('some other message.');
  }

}

```

This file is placed inside mymodule\src\Plugin\views\field. I overwrote the views.view.comment to look for this class. However, I get the following error when I try to load the comments view.

> Drupal\Component\Plugin\Exception\PluginException: Plugin (custom\_comment\_bulk\_form) instance class "Drupal\mymod\Plugin\views\field\custom\_comment\_bulk\_form" does not exist. in Drupal\Component\Plugin\Factory\DefaultFactory::getPluginClass() (line 97 of /vagrant/web/core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php).

What's wrong in the code?

# Answer
> 3 votes
1. For PSR-2 loading to work is important:

* Check namespace, folders are coherent. If your module is `ahrq`, ensure the namespace uses `ahrq`, and the folder it sits is `ahrq/src/Plugin/views/field`. Check the casing is respected just in case (lowercase/uppercase matters).
* Ensure the file is named `CustomCommentBulkForm.php`

2. Yeah, obvious, but have you cleared your cache?

# Answer
> 0 votes
> Plugin (xxx) instance class "Drupal\mymod\Plugin\views\field\custom\_comment\_bulk\_form" does not exist. in Drupal\Component\Plugin\Factory\DefaultFactory::getPluginClass()

This happens when you've references to that plugin and Drupal cannot find it.

First step is obviously to try to clear the caches (`drush cr`, in case of Redis - `redis-cli flushall`). Alternatively try truncating `cache_discovery` table where this reference is stored.

If the clear cache didn't work, others things that can be done:

* Identify and ensure the module using that plugin/namespace is enabled.
* Ensure class/plugin is defined in module's `.services.yml` file.
* Ensure no files are missing, no typos and permission are fine.
* Re-run `composer install`.
* Briefly check Composer's autoload values (such as `vendor/composer/autoload*` and `vendor/composer/installed.json`), whether it has the right paths (sometimes mixing different environments or copying/committing these files can mess up with the paths).
* If this happened after module upgrade: review existing release changes, bugs and patches that you're using. Sometimes the old patch could break the working module on the upgrade.
* Review code for any typos.
* Otherwise consider removing/disabling broken code (all the references), then clearing up caches (`cache_discovery` table), if it's not needed.

---
Tags: views, comments, 9
---


# Question
Title: Enable xdebug on Lando using Pantheon recipe and PHPStorm
I am trying to enable xdebug on Lando using the pantheon recipe. I have tried different tutorials, but PHPStorm does not seem to connect to Lando, or xdebug is not correctly enabled on Lando.

```
recipe: pantheon
config:
  framework: drupal8
  xdebug: true

```

Have some of you had this issue?

# Answer
The answer from @no-sssweat works great. Even so, many of those settings can be removed, and you can set up tooling so xdebug isn't always running (and slowing down your local testing). This is based on the lando github issue "Allow faster xdebug on/off toggling":

**.lando.yml**

```
recipe: pantheon
config:
  framework: drupal8
  xdebug: off
  config:
    php: .lando.php.ini
services:
  appserver:
    overrides:
      environment:
        XDEBUG_MODE:
tooling:
  xdebug-on:
    service: appserver
    description: Enable xdebug for nginx
    cmd:
      - echo "[INFO] Enabling xdebug ..."
      - echo xdebug.mode = "debug,develop" > /usr/local/etc/php/conf.d/zzz-lando-xdebug.ini
      - pkill -o -USR2 php-fpm
    user: root
  xdebug-off:
    service: appserver
    description: Disable xdebug for nginx
    cmd:
      - echo "[INFO] Disabling xdebug ..."
      - echo xdebug.mode = "off" > /usr/local/etc/php/conf.d/zzz-lando-xdebug.ini
      - pkill -o -USR2 php-fpm
    user: root

```

(yes, you need XDEBUG\_MODE in there so that you can override the value, and yes, start with it off so that it doesn't enable debugging by default)

**.lando.php.ini**

```
; Xdebug settings required for PhpStorm.
xdebug.start_with_request=yes

```

Then leave PhpStorm listening all the time and just run the tooling:

```
>lando xdebug-on
>lando xdebug-off

```
> 4 votes

# Answer
**Note:** While my answer works, @Eric Woods answer is superior.

---

Ever since Xdebug 3 came out, I've had to use a .lando.php.ini file in order for it to work with Lando.

```
recipe: pantheon
config:
  framework: drupal8
services:
  appserver:
    type: php
    xdebug: true
    config:
      php: .lando.php.ini
    overrides:
      environment:
        PHP_IDE_CONFIG: "serverName=appserver"
        LANDO_HOST_IP: "host.docker.internal"
        XDEBUG_CONFIG: "remote_enable=1 remote_host=host.docker.internal"

```

In the project's root folder, create a .lando.php.ini

**.lando.php.ini**

```
; Xdebug
xdebug.max_nesting_level = 256
xdebug.show_exception_trace = 0
xdebug.client_host = ${LANDO_HOST_IP}
xdebug.log = /tmp/xdebug.log
xdebug.mode = debug
xdebug.client_port = 9003
xdebug.start_with_request = yes

```

In your PHP storm settings, create the "appserver" by hitting the "+" icon. Make sure you add the `/app` path to the root.

<sub>**Note:** Replace Host with your actual host name.</sub>
> 2 votes

---
Tags: virtual-machine, 8, debugging
---


# Question
Title: Entity print broken when updating to PHP8.1
I've updated my drupal environment **php 7.4** to **php 8.1.18**. i've enable some extensions, but I have this error when i try to download a PDF

```
Error : Typed property DOMDocument::$documentElement must not be accessed before initialization in Masterminds\HTML5\Parser\DOMTreeBuilder->startTag() (/var/www/myproject/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php line 275)

#0 /var/www/myproject/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php(399): Masterminds\HTML5\Parser\DOMTreeBuilder->startTag()
#1 /var/www/myproject/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php(141): Masterminds\HTML5\Parser\Tokenizer->tagName()
#2 /var/www/myproject/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php(82): Masterminds\HTML5\Parser\Tokenizer->consumeData()
#3 /var/www/myproject/vendor/masterminds/html5/src/HTML5.php(161): Masterminds\HTML5\Parser\Tokenizer->parse()
#4 /var/www/myproject/vendor/masterminds/html5/src/HTML5.php(89): Masterminds\HTML5->parse()
#5 /var/www/myproject/vendor/dompdf/dompdf/src/Dompdf.php(478): Masterminds\HTML5->loadHTML()
#6 /var/www/myproject/web/modules/contrib/entity_print/src/Plugin/EntityPrint/PrintEngine/DomPdf.php(207): Dompdf\Dompdf->loadHtml()

```

the extensions are the same than PHP7.4

EDIT :

By digging, I've found that this on

is producing this on php7

but this in php8 (going through the same functions)...

The `nodeName` is just `name` in php 8 (and so on). Do I have to change another thing in my server to update the \DOMImplementation() ?

EDIT 2 :

i've remade the delivry of my package to another server (so php7.4 to php8.1.13), same result. It only works into my docker container, not my client server. Here's my procedure :

```
apt install php8.1-fpm php8.1-xml php8.1-mysql php8.1-gd php8.1-cli php8.1-common php8.1-mbstring php8.1-opcache php8.1-readline php8.1-curl php8.1-bcmath php8.1-zip

    I. edit ini file : /etc/php/8.1/fpm/php.ini

extension=gd
extension=zip
extension=dom
extension=pdo_mysql
extension=mbstring

II. Restart PHP/Nginx
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx
sudo update-alternatives --set php /usr/bin/php8.1

```

# Answer
This is not entity\_print related, but to it's dependencies, you should use PHP 8.2.x, see https://github.com/Masterminds/html5-php/issues/220
> 0 votes

---
Tags: 9
---


title: Sub groups under groups

text:
# Question
Title: Sub groups under groups
Anybody has idea about how we can have Sub Groups under Drupal Group?

This module; https://www.drupal.org/project/group, will manage grouping of content, users.... perfectly.

But we are looking to have a hierarchical Group functionality (Group inside a group).

Use Case: An Organization has various Groups and Departments.

Main Company -\> Organizations(Groups) -\> Departments (subgroups) Departments/Groups Should be able to administer content/users.

# Answer
Subgroup module should suit your needs. Make sure to read this short documentation page as well
> 0 votes

---
Tags: 8, group
---


# Question
Title: Can I add classes to individual menu links?
I am using the main menu /admin/structure/menu/manage/main

There are a couple of links that I want to display only in mobile devices, and then also another couple of links that I want to display only in laptop devices. Can I do this without needing two separate menus? I guess one way would be to attach a css class to the relevant links but looking at /admin/structure/menu/item/1/edit there is no option to add classes to a menu link in the menu UI.

I don't want to use CSS nth-child because if in future the menu is edited / reordered then any nth-child rules will get messed up.

So can anyone tell me how to add an option to add classes to individual menu links in the menu UI - and / or some alternative route.

# Answer
The Menu Link Attributes contrib module adds the option to assign each menu link a class in the admin UI.
> 3 votes

---
Tags: theming, navigation, 10
---


# Question
Title: Store custom checkout pane data to order
I've created a custom checkout pane according to documentation. When I submit my Order and go to admin page, where all my orders are listed, I can't see this custom pane field there. I've already tried to add `$this->order->save();` at the end of **submitPaneForm** function but that seems to make no difference. I've already created field with machine name **"field\_test\_me"** in my Order type and also have added this field to enabled fields on "Manage display" tab, but the field seems to be empty.

Is there anything I'm missing to get my custom pane fields to be displayed on the "Order detail" page, please?

This is how my **buildPaneForm** function looks like:

```
public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form)
{
$pane_form['billing_info'] = [
  '#type' => 'fieldset',
  '#title' => $this->t('@title', ['@title' => $this->configuration['title']]),
];

$pane_form['billing_info']['field_test_me'] = [
  '#type' => 'textfield',
  '#title' => 'Test me',
  '#wrapper_attributes' => [
    'class' => ['col-md-6']
  ],
  '#default_value' => 'MY CUSTOM STRING'
];
return $pane_form;

```

}

And this is how my **submitPaneForm** function looks like:

```
public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form)
{
    $values = $form_state->getValue($pane_form['#parents']);
    $this->order->setData('field_test_me', $values['billing_info']['field_test_me']);
}

```

I'm using other functions for displaying value on "Review" page, but those are not part of my issue.

# Answer
> 0 votes
I found a solution. With my custom field called "Test me" and machine name "field\_test\_me" created in my Order Type entity I could save the data from Custom Checkout Pane with `$this->order->set()` function instead of `$this->order->setData()`. Of course I needed to change `$this->order->getData()` to `$this->order->get()` everywhere where used.

I don't understand what's the difference between `set()` and `setData()`, but it seems to store my Custom Checkout Pane values to my custom fields created in my Order type entity.

# Answer
> 0 votes
I'm doing it this way:

```
public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, &$complete_form) {
     // save the data
    $values = $form_state->getValue($pane_form['#parents']);
    $this->order->setData('send_gift_to_recipient', $values['send_gift_recipient']);
    $this->order->setData('gift_recipient_address', $values['gift_recipient_address']);
    $this->order->save();
}

```

Then I copied the twig file: `commerce-order--admin.html.twig` from /modules/contrib/commerce/modules/order/templates into my custom module templates directory (uslhs\_checkout\_pane/templates).

In my checkout pane module file: `uslhs_checkout_pane.module` I've added this code to override the Commerce Orders twig file and use mine instead:

```
/**
 * Implements hook_theme().
 */
function uslhs_checkout_pane_theme($existing, $type, $theme, $path) {
  return [
    'commerce_order__admin' => [
      'base hook' => 'commerce_order',
      'render element' => 'elements',
    ],
  ];
}

function uslhs_checkout_pane_preprocess_commerce_order(array &$variables) {
  $order = $variables['elements']['#commerce_order'];
  $variables['send_gift_to_recipient'] = ($order->getData('send_gift_to_recipient') == 1) ? 'Yes':'No';
  $variables['gift_recipient_address'] = $order->getData('gift_recipient_address');
}

```

Clear the cache to have it read the new twig file. I had to use Drush to clear it, when I used the Drupal UI my template still wasn't taking effect. But doing a `Drush cr` did the trick.

And then finally in my twig file I've added these lines:

```
<div class="gift_details">
    <div><span class="field__label">{{ 'Send gift to recipient'|t}}:</span> <span class="field__item">{{ send_gift_to_recipient }}</span></div>
    <div><span class="field__label">{{ 'Gift recipient address'|t}}:</span> <span class="field__item">{{ gift_recipient_address }}</span></div>
  </div>

```

---
Tags: 8, commerce
---


# Question
Title: Getting error while importing the fields in Google Analytics Reports module
I have installed Google Analytics Reports module latest version, enabled the GA reports data API and created a service account credentials on developer console. Then I have downloaded the json file of service account and uploaded in the GA reports module configs and also added the property id. But now when I am importing the fields I am getting this error.

I have checked the logs also and it says **"Integrity constraint violation: 1062 Duplicate entry 'conversions:click' for key 'PRIMARY': INSERT INTO "google\_analytics\_reports\_fields".**

Can anyone guide me to solve this issue?

# Answer
> 0 votes
The reason why this error was coming because I have created multiple conversions on my google analytics that's why it was throwing 'Duplicate entry 'conversions:click' error. So I deleted one conversion:click from GA and then successfully imported the fields.

---
Tags: views, google-analytics
---


title: Add Language Switcher on admin toolbar

text:
# Question
Title: Add Language Switcher on admin toolbar
What is the correct way for adding Language Switcher (Dropdown) or links on the admin toolbar menu from my custom module or from a contributed module?

# Answer
Well, I got something up and running via `hook_toolbar`. Only thing left is, that you can't click directly on the "Language: EN" string in the toolbar. You have to click slightly next to it. Maybe you can fix this.

Apart from that, please also have a look at the Devel module and their implementation of `hook_toolbar` where they have an extra `src/ToolbarHandler.php` class for everything. You better should rebuild the code below into a dedicated handler.

---

```
use Drupal\Core\Url;
use Drupal\Core\Link;

/**
 * Implements hook_toolbar().
 */
function MYMODULE_toolbar() {

  // Get languages, get current route.
  $current_language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $languages = \Drupal::languageManager()->getLanguages();
  $route = \Drupal::service('path.matcher')
    ->isFrontPage() ? '<front>' : '<current>';

  // Get links.
  $links = [];
  foreach ($languages as $language) {
    $url = new Url($route, [], ['language' => $language]);
    $links[] = [
      '#markup' => Link::fromTextAndUrl($language->getName(), $url)
        ->toString(),
    ];
  }

  // Set cache.
  $items['admin_toolbar_langswitch'] = [
    '#cache' => [
      'contexts' => [
        'languages:language_interface',
        'url',
      ],
    ],
  ];

  // Build toolbar item and tray.
  $items['admin_toolbar_langswitch'] += [
    '#type'   => 'toolbar_item',
    '#weight' => 999,
    'tab'     => [
      '#type'       => 'html_tag',
      '#tag'        => 'div',
      '#value'      => '<span>' . t('Language') . '</span>: <span class="current-language">' . strtoupper($current_language) . '</span>',
      '#attributes' => [
        'class' => ['toolbar-item-admin-toolbar-langswitch'],
        'title' => t('Admin Toolbar Langswitch'),
      ],
    ],
    'tray'    => [
      '#heading' => t('Admin Toolbar Langswitch'),
      'content'  => [
        '#theme'      => 'item_list',
        '#items'      => $links,
        '#attributes' => [
          'class' => ['toolbar-menu'],
        ],
      ],
    ],
  ];

  return $items;
}

```
> 2 votes

# Answer
The example above for hook\_toolbar is almost perfect. I fixed it, see code below. You just have to remove the span on the Language : EN then the click functionality works perfectly.

see my code:

```
/**
 * Implements hook_toolbar().
 */
function examplemodule_toolbar() {

  // Get languages, get current route.
  $current_language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $languages = \Drupal::languageManager()->getLanguages();
  $route = \Drupal::service('path.matcher')
    ->isFrontPage() ? '<front>' : '<current>';

  // Get links.
  $links = [];
  foreach ($languages as $language) {
    $url = new Url($route, [], ['language' => $language]);
    $links[] = [
      '#markup' => Link::fromTextAndUrl($language->getName(), $url)
        ->toString(),
    ];
  }

  // Set cache.
  $items['admin_toolbar_langswitch'] = [
    '#cache' => [
      'contexts' => [
        'languages:language_interface',
        'url',
      ],
    ],
  ];

  // Build toolbar item and tray.
  $items['admin_toolbar_langswitch'] += [
    '#type'   => 'toolbar_item',
    '#weight' => 999,
    'tab'     => [
      '#type'       => 'html_tag',
      '#tag'        => 'div',
      '#value'      => t('Language') . ': ' . strtoupper($current_language),
      '#attributes' => [
        'class' => ['toolbar-item-admin-toolbar-langswitch'],
        'title' => t('Admin Toolbar Langswitch'),
      ],
    ],
    'tray'    => [
      '#heading' => t('Admin Toolbar Langswitch'),
      'content'  => [
        '#theme'      => 'item_list',
        '#items'      => $links,
        '#attributes' => [
          'class' => ['toolbar-menu'],
        ],
      ],
    ],
  ];

  return $items;
}

```
> 1 votes

# Answer
Ok, nowadays there is https://www.drupal.org/project/toolbar\_language\_switcher for solving this problem
> 0 votes

# Answer
The link in the reply berramou posted doesn't mention the contrib module toolbar\_menu, which makes adding stuff in the toolbar more convenient than what is mentioned in the link.
> -2 votes

---
Tags: 8, theming, i18n-l10n, navigation, transliteration
---


title: Show image for only first view item

text:
# Question
Title: Show image for only first view item
I've created a view for a group of nodes, what I want to do is output the image just for the first result rather than all of them.

Currently I'm using CSS to hide all except the first but that isn't ideal.

# Answer
> 3 votes
Display Suite provides this functionality. Just install DS, then, in your view, choose "Display Suite" under the option for "Show":

In the settings for that option you can choose a different view mode for the first item in your list:

# Answer
> 0 votes
(d8/9/10) Single Image https://www.drupal.org/project/single\_image\_formatter module provides formatters for Image, Media and Responsive image field, that displays only first value of multi-valued fields.

---
Tags: 7, views
---


title: Multiple source IDs error

text:
# Question
Title: Multiple source IDs error
I'm getting error

```
Drupal\Core\Database\DatabaseExceptionWrapper</em>: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'map.sourceid2' in 'field list': SELECT map.sourceid1 AS sourceid1, map.sourceid2 AS sourceid2, map.destid1 AS destid1

```

when trying to use two value ids in migrate yml file:

```
id: recipe_daily
label: Recipes
migration_group: recipe
status: true

source:
  plugin: url
  data_fetcher_plugin: http
  data_parser_plugin: xml
  urls:
    - http://mysource.com/data
  item_selector: /recipes/recipe

  fields:
    -
      name: text
      label: 'Text'
      selector: text
    -
      name: title
      label: 'Title'
      selector: title
    -
      name: recipe_day
      label: 'Day'
      selector: '@day'
    -
      name: recipe_id
      label: 'Recipe id'
      selector: 'detail/@id'

  ids:
    title:
      type: string
    recipe_id:
      type: string

destination:
  plugin: entity:node

process:

  type:
    plugin: default_value
    default_value: recipe_daily

  title: title
  text: text

dependencies:
  enforced:
    module:
      - recipe

```

Since it's called ids I assume it takes multiple values but cannot find any examples anywhere. Any ideas much appreciated

# Answer
I think you used to have 1 ID before and that you added the second ID after you ran the migrations?

If your migrations aren't in prod, you can simply delete these tables and try again:

* `migrate_map_recipe_daily`
* `migrate_message_recipe_daily`

I think it should work.

If your migration is in prod, you might have to:

* Create a `sourceid2` column matching with your ID type
* Update the table keys to consider `sourceid1` and `sourceid2` as composite keys

I have tried the first one many times.
> 2 votes

# Answer
I will copy what this comment said into an answer, because it helped me. However, I was fortunate to see it at all, since it was only a comment, and with zero upvotes at the time. So I hope this gives the solution the visibility it deserves.

> When you make changes to source IDs, all existing meta data of this migration is broken. Remove existing data and the module, search for migrate\_map\_YOURID and migrate\_message\_YOURID tables in your DB and drop them. Then reinstall your module.

After dropping the table and reinstalling the module, I reran my migration without issues.
> 0 votes

---
Tags: migrations
---


title: Custom plugin definition not loading

text:
# Question
Title: Custom plugin definition not loading
I'm trying to create my own plugin type in Drupal 9 but it's not finding my test definition and I can't figure out why.

Here's my services.yaml:

```
services:
  plugin.manager.reaction:
    class: Drupal\nm_events\ReactionManager
    parent: default_plugin_manager

```

Here's ReactionManager.php:

```
<?php

namespace Drupal\nm_events;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;

/**
 * Defines the reaction plugin manager.
 */
class ReactionManager extends DefaultPluginManager {

  /**
   * Constructs a ReactionManager object.
   *
   * @param \Traversable $namespaces
   *   An object that implements \Traversable which contains the root paths
   *   keyed by the corresponding namespace to look for plugin implementations.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   Cache backend instance to use.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_h
andler) {
    parent::__construct('Plugin/Reaction', $namespaces, $module_handler, 'Drupal\nm_events\ReactionInterface', 'Drupal\nm_even
ts\ReactionAnnotation');
    $this->setCacheBackend($cache_backend, 'reaction_plugins');
    $this->alterInfo('reaction_info');
  }

}

```

Here's my Annotation class:

```
<?php

namespace Drupal\nm_events;

use Drupal\Component\Annotation\Plugin;

/**
 * Declare a class for event reactions.
 *
 * Plugin Namespace: Plugin\Reaction.
 *
 * @see plugin_api
 *
 * @Annotation
 */
class ReactionAnnotation extends Plugin {
  /**
   * The plugin ID.
   *
   * @var string
   */
  public $id;

  /**
   * The human-readable title of the plugin.
   *
   * @var \Drupal\Core\Annotation\Translation
   *
   * @ingroup plugin_translatable
   */
  public $title;

}

```

And here's my Test plugin (in src/Plugin/Reaction/Test.php

```
<?php

namespace Drupal\nm_events\Plugin\Reaction;

use Drupal\nm_events\ReactionInterface;

/**
 * Test reaction.
 *
 * @Reaction(
 *   id = "test",
 *   title = @Translation("Reaction for testing reactions")
 * )
 */
class Test implements ReactionInterface {
  public function processEvent($event, $entity) {
    var_export($event->title->value);
  }
}

```

But when I try to get the definitions:

```
$ drush cr
 [success] Cache rebuild complete.
$ drush php
Psy Shell v0.11.17 (PHP 8.0.15 — cli) by Justin Hileman
New/Mode base (Drupal 9.5.8)

> $p = $container->get('plugin.manager.reaction')
= Drupal\nm_events\ReactionManager {#2893}

> $p->getDefinitions();
= []

```

Edit: Here's the interface definition:

```
<?php

namespace Drupal\nm_events;

use Drupal\Component\Plugin\PluginInspectionInterface;

/**
 * Defines an interface for a Reaction plugin.
 *
 * @see plugin_api
 */
interface ReactionInterface extends PluginInspectionInterface {
  public function processEvent($event, $entity);
}

```

# Answer
> 1 votes
I have played a little bit and changed the structure slightly, but finally made it work. Here's my example:

Final structure:

```
├── pm_test.info.yml
├── pm_test.services.yml
└── src
    ├── Annotation
    │   └── ReactionAnnotation.php
    └── Plugin
        ├── Reaction
        │   └── Test.php
        ├── ReactionInterface.php
        └── ReactionManager.php

```

services.yml looks like this:

```
services:
  plugin.manager.reaction:
    class: Drupal\pm_test\Plugin\ReactionManager
    parent: default_plugin_manager

```

Annotation class(`src/Annotation/ReactionAnnotation.php`)

```
<?php

namespace Drupal\pm_test\Annotation;

use Drupal\Component\Annotation\Plugin;

/**
 * Declare a class for event reactions.
 *
 * Plugin Namespace: Plugin\Reaction.
 *
 * @see plugin_api
 *
 * @Annotation
 */
class ReactionAnnotation extends Plugin {

  /**
   * The plugin ID.
   *
   * @var string
   */
  public $id;

  /**
   * The human-readable label of the plugin.
   *
   * @var \Drupal\Core\Annotation\Translation
   *
   * @ingroup plugin_translatable
   */
  public $label;

}

```

The ReactionInterface (`src/Plugin/ReactionInterface.php`)

```
<?php

namespace Drupal\pm_test\Plugin;

use Drupal\Component\Plugin\PluginInspectionInterface;

/**
 * Defines an interface for a Reaction plugin.
 *
 * @see plugin_api
 */
interface ReactionInterface extends PluginInspectionInterface {

  public function processEvent($event, $entity);

}

```

The ReactionManager(`src/Plugin/ReactionManager.php`)

```
<?php

namespace Drupal\pm_test\Plugin;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;

/**
 * Defines the reaction plugin manager.
 */
class ReactionManager extends DefaultPluginManager {

  /**
   * Constructs a ReactionManager object.
   *
   * @param \Traversable $namespaces
   *   An object that implements \Traversable which contains the root paths
   *   keyed by the corresponding namespace to look for plugin implementations.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   Cache backend instance to use.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(
    \Traversable $namespaces,
    CacheBackendInterface $cache_backend,
    ModuleHandlerInterface $module_handler,
  ) {
    parent::__construct(
      'Plugin/Reaction',
      $namespaces,
      $module_handler,
      '\Drupal\pm_test\Plugin\ReactionInterface',
      '\Drupal\pm_test\Annotation\ReactionAnnotation'
    );

    $this->alterInfo('reaction_info');
    $this->setCacheBackend($cache_backend, 'reaction_info_plugins');
  }

}

```

And finally the Test(`/src/Plugin/Reaction/Test.php`):

```
<?php

namespace Drupal\pm_test\Plugin\Reaction;

use Drupal\Component\Plugin\PluginBase;
use Drupal\pm_test\Annotation\ReactionAnnotation;
use Drupal\pm_test\Plugin\ReactionInterface;

/**
 * Test reaction.
 *
 * @ReactionAnnotation(
 *   id = "test",
 *   title = @Translation("Reaction for testing reactions")
 * )
 */
class Test extends PluginBase implements ReactionInterface {
  public function processEvent($event, $entity) {
    var_export($event->title->value);
  }

}

```

At the end, I checked the same way with drush and here's the result:

```
Psy Shell v0.11.18 (PHP 8.0.24 — cli) by Justin Hileman
Drush Site-Install (Drupal 9.5.9)
> $p = $container->get('plugin.manager.reaction');
= Drupal\pm_test\Plugin\ReactionManager {#7435}

> $p->getDefinitions();
= [
    "test" => [
      "id" => "test",
      "title" => Drupal\Core\StringTranslation\TranslatableMarkup {#7452},
      "class" => "Drupal\pm_test\Plugin\Reaction\Test",
      "provider" => "pm_test",
    ],
  ]

```

In my opinion the biggest issue with your code was the Annotation. Instead of using

```
 * @Reaction(
 *   id = "test",
 *   title = @Translation("Reaction for testing reactions")
 * )

```

it should have been

```
 * @ReactionAnnotation(
 *   id = "test",
 *   title = @Translation("Reaction for testing reactions")
 * )

```

after the name of the annotation class. I hope this helps

# Answer
> 1 votes
You have two options:

* A. Adjust Test class with correct annotation id
* B. Rewrite your code to follow common approaches with plugin definition.

A. The `Test.php` reaction plugin uses wrong annotation name. Instead of `@Reaction` there sholud be `@ReactionAnnotation`.

B. Code Refactor. There are couple of issues with your code:

1. Rename and move ReactionAnnotation.php from `nm_events/src/ReactionAnnotation.php` into `nm_events/src/Annotation/Reaction.php` and adjust namespace to `Drupal\nm_events\Annotation` and class name to `Reaction`
2. Change annotation name in `ReactionManager.php` from `Drupal\nm_events\ReactionAnnotation` to `Drupal\nm_events\Annotation\Reaction`
3. Change annotation id within `Test.php` from `@ReactionAnnotation` to `@Reaction`

After this adjustments `$p = $container->get('plugin.manager.reaction')->getDifitions()` should show your test plugin.

However. When you try to create plugin instance: `$test = $container->get('plugin.manager.reaction')->createInstance('test', [])`

You will get fatal error `Test contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods`. To fix it you need extend it with `Drupal\Core\Plugin\PluginBase` class.

Now instance could be created.

Note. I would recommend to take a look how other core modules deal with plugins, there are lot's of useful classes out of the box in Drupal. Here is example: ImageEffectManager.php. And maybe you also need plugin collection similar to: ImageEffectPluginCollection

To save time you can use `drush generate plugin:manager` command and create all stuff (including service, annotation, interface, manager, test plugin, plugin interface) using provided wizard.

---
Tags: 9, plugins
---


# Question
Title: How to migrate Group module from 2.0 to 3.0?
I am working on implementing the Group module on Drupal 9. The Release Notes describe moving from Group 2.0.x to 3.0.x as a 'Migration', which I take it is not just an upgrade that can be done using Composer.

Our overall project plan means we will need to do this migration on a site containing Group data, with associated content (Nodes) and members (Users).

Without considering the migration of custom modules, how can we perform this migration?

# Answer
Yes it *is* a migration. A revealing comment by the maintainer in its issue queue and the comments following it explain the details of migration to 2.0 and summarize the smaller changes of migration to 3.0.
> 0 votes

# Answer
The maintainer is referencing using the Drupal migrate module when using the word "migrate" as opposed to "upgrade". So there is no "upgrade" path provided by the maintainer, meaning it isn't easy. A "migration" in this case will look like creating another copy of your site removing all of the group and group content entities and uninstalling the group module. From there you can install the group module fresh on version 3.x with the new flexible permissions module. Setup all of your group types fresh and then "migrate" your content from the old copy of the site to the new copy of the site using the new architecture.
> 0 votes

---
Tags: group
---


title:
Why is
 changed to
?

text:
# Question
Title: Why is
 changed to
?
After I edit a block in *Full HTML* form CKEditor on *Source mode* and save, Drupal changes `<br>` to `<br />`.

Drupal also seems to me to unify some HTML tags into one line.

This

```
<p>
<!-- -->
<br>

```

Becomes something like this

```
<p><!-- --><br />

```

In /admin/config/content/formats/manage/full\_html the only filters that are on are:

* Align images
* Caption images
* Track images uploaded via a text editor

The *Correct faulty and chopped off HTML* filter isn't on.

It might be that the very work on *Full HTML* mode causes this because it's "full" without any sugar syntax. If so, manually changing the HTML level of nearly 30 blocks and also hundreds of nodes to *Restriced HTML* is not something I want to do.

Why is this happening? How do I prevent it?

# Answer
> 1 votes
`<br>` is changed to `<br />` because all the HTML markup used as block or node content is passed to `Html::normalize()`, which calls `Html::serialize()` which uses `DOMDocument::saveXML()`. The latter is what changes `<br>` to `<br />`. (It would also do the same for any tag without content.)

```
public static function serialize(\DOMDocument $document) {
  $body_node = $document->getElementsByTagName('body')->item(0);
  $html = '';
  if ($body_node !== NULL) {
    foreach ($body_node->getElementsByTagName('script') as $node) {
      static::escapeCdataElement($node);
    }
    foreach ($body_node->getElementsByTagName('style') as $node) {
      static::escapeCdataElement($node, '/*', '*/');
    }
    foreach ($body_node->childNodes as $node) {
      $html .= $document->saveXML($node);
    }
  }
  return $html;
}

```

That is not possible to change.

As for why the text is shown on a single line, that is what CKEditor 5 actually does. The issue linked by @cilefen in his comment (CKEditor 5 saves content as single line HTML making revision diffing impossible) contains a link to a feature request opened in the CKEditor 5 issue queue (Output formatted HTML code).
That needs to be implemented in CKEditor 5; then Drupal needs to use the release it implements that.

---
Tags: blocks, 9
---


title: Turn off caching for local tasks menu

text:
# Question
Title: Turn off caching for local tasks menu
I have a somewhat complicated view that uses multiple displays for showing events. It uses a datepager (https://www.drupal.org/project/date\_pager), exposed filters (using better exposed filters), and a local task menu.

The overall issue I'm having is that I want any event view link, be it a local task tab, a pagination link, or activating an exposed filter, to preserve any arguments in the URL. And because of a currently known bug for BEF, I can't even use the remember filters option.

So I've decided my best route is to go into the twig templates for these various pagers and menus, get the current arguments from the URL, and append or merge them as needed on the render links.

So far this seems to be working, but I'm running into an issue getting it to work well with the local task menu tabs.

I have a preprocess function in my theme file (using template\_preprocess\_menu\_local\_task) to get the arguments from the URL but the issue is that its caching and so if someone changes what filters they have selected the arguments don't update unless the cache is cleared.

I tried doing this: $variables\['element'\]\['#cache'\]\['max-age'\] = 0; but it didn't change anything.

Is there a way to turn off caching for local tasks from my custom theme?

# Answer
The only officially supported way to add cache metadata in a preprocess hook is to `#cache` in the top level of $variables:

```
$variables['#cache']['tags'][] = 'foo';
$variables['#cache']['contexts'][] = 'url.query_args';
$variables['#cache'] = ['max-age' => 0];

```

Be careful not to overwrite existing tags or contexts.

If you want to use cache contexts or max-age for anonymous users you have to uninstall the Internal Page Cache module, this module works only with cache tags. The exception is the context for query arguments, these are part of the URL, which is used as storage key for the Internal Page Cache module.
> 1 votes

---
Tags: views, navigation
---


# Question
Title: How can I add an external/third party library with type = 'module' using drupal_add_js()?
```
  drupal_add_js('path_to_external_JS_file_on_CDN', [
    'every_page' => TRUE,
    'type' => 'external',
    'defer' => 'defer',
    'attributes' => [
      'async' => true,
      'type' => 'module'
    ],
  ]
);

```

I tried all combinations of the above, but I couldn't get it work. Is there a way to achieve it using `drupal_add_js()`, or should I use some other way?

I am trying to achieve this.

```
<script type='module' src='path_to_external_JS_file_on_CDN'></script>

```

Edit: I added the code above in `my_module_preprocess_page(&$variables)`. The following code works as expected.

```
drupal_add_js('path_to_external_JS_file_on_CDN', [
  'every_page' => TRUE,
  'type' => 'external'
]);

```

I just can't figure out how to load a JavaScript file with the `type='module'` attribute.

# Answer
> 0 votes
According the function's documentation the `module` is not an allowed type, that's why it doesn't work.

You may try omitting the type or use the default one - `file` instead.

The allowed types are 'file', 'inline', 'external' or 'setting'.

The hook you tried `my_module_preprocess_page(&$variables)` is a good choice.

You may also use the hook\_init `YOUR_MODULE_NAME_init()` in a custom module to ensure your library is loaded everywhere. Please note that `hook_init()` is triggered after the theme and all modules are loaded already in the memory.

Please check if this solves your issue and put a note with the result.

---
Tags: 7, javascript
---


# Question
Title: How do I handle git asking me to remove untouched files?
A while ago, I cloned the Drupal repo. Today, I attempted a pull only to find out that I'm being asked to remove most, if not all, of the `core` directory to prevent overwriting. This happened to me once again about a month ago and I fixed it by removing the `core` directory prior to pulling, but obviously I can't remove the directory every time I pull. How can I fix this once and for all?

EDIT: git output:

```
➜  dev-drupal git:(10.1.x) ✗ time gl
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (25/25), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 28 (delta 8), reused 17 (delta 8), pack-reused 3
Unpacking objects: 100% (28/28), 29.22 KiB | 1.33 MiB/s, done.
From https://git.drupalcode.org/project/drupal
   d3d1d05dfa..3c8128a0ac  11.x       -> origin/11.x
Updating 2090b606ea..65212de44c
error: Your local changes to the following files would be overwritten by merge:
    composer.json
    composer.lock
    composer/Generator/Builder/DrupalCoreRecommendedBuilder.php
    composer/Metapackage/CoreRecommended/composer.json
    composer/Metapackage/DevDependencies/composer.json
    composer/Metapackage/PinnedDevDependencies/composer.json
    core/MAINTAINERS.txt
    core/assets/scaffold/files/default.settings.php
    core/assets/vendor/ckeditor5/ckeditor5-dll/ckeditor5-dll.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ar.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ast.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/az.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/bg.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/bn.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ca.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/cs.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/da.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/de-ch.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/de.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/el.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/en-au.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/en-gb.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/eo.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/es.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/et.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/eu.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/fa.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/fi.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/fr.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/gl.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/he.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/hi.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/hr.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/hu.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/id.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/it.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ja.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/km.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/kn.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ko.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ku.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/lt.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/lv.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ms.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/nb.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ne.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/nl.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/no.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/pl.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/pt-br.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/pt.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ro.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ru.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/sk.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/sl.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/sq.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/sr-latn.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/sr.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/sv.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/th.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/tk.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/tr.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/tt.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ug.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/uk.js
    core/assets/vendor/ckeditor5/ckeditor5-dll/translations/ur.js
    core/assets/vendor/c
error: The following untracked working tree files would be overwritten by merge:
    core/assets/vendor/ckeditor5/horizontal-line/translations/uz.js
    core/assets/vendor/ckeditor5/special-characters/translations/hr.js
    core/assets/vendor/ckeditor5/table/translations/sl.js
    core/lib/Drupal/Core/Routing/PathChangedHelper.php
    core/modules/block_content/src/Routing/RouteSubscriber.php
    core/modules/file/tests/modules/file_test_views/config/optional/node.type.file_test.yml
    core/modules/file/tests/modules/file_test_views/config/optional/views.view.test_file_to_node.yml
    core/modules/file/tests/modules/file_test_views/config/optional/views.view.test_file_to_user.yml
    core/modules/file/tests/modules/file_test_views/config/optional/views.view.test_file_user_file_data.yml
    core/modules/file/tests/modules/file_test_views/config/optional/views.view.test_node_to_file.yml
    core/modules/file/tests/modules/file_test_views/config/optional/views.view.test_user_to_file.yml
    core/modules/file/tests/src/Kernel/Views/RelationshipNodeFileDataTest.php
    core/modules/node/tests/src/FunctionalJavascript/NodeDeleteConfirmTest.php
    core/modules/system/tests/modules/path_changed_helper_test/path_changed_helper_test.info.yml
    core/modules/system/tests/modules/path_changed_helper_test/path_changed_helper_test.routing.yml
    core/modules/system/tests/modules/path_changed_helper_test/src/Controller/TestController.php
    core/modules/views/tests/src/FunctionalJavascript/RedirectAjaxTest.php
    core/tests/Drupal/KernelTests/Core/Routing/PathChangedHelperTest.php
    core/tests/Drupal/Tests/Core/Routing/PathChangedHelperTest.php
    core/themes/claro/css/components/dropbutton-noscript.css
    core/themes/claro/css/components/dropbutton-noscript.pcss.css
Please move or remove them before you merge.
Aborting
git pull  0.11s user 0.24s system 16% cpu 2.032 total

```

I have edited root composer.json but other than that, I haven't touched any files.

EDIT: Output of `git status`:

```
➜  dev-drupal git:(11.x) ✗ gst
On branch 11.x
Your branch is behind 'origin/11.x' by 47 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   sites/default/default.settings.php

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .DS_Store
    .idea/
    .lando.yml
    core/assets/vendor/ckeditor5/horizontal-line/translations/uz.js
    core/assets/vendor/ckeditor5/special-characters/translations/hr.js
    core/assets/vendor/ckeditor5/table/translations/sl.js
    core/lib/Drupal/Core/Routing/PathChangedHelper.php
    core/modules/block_content/src/Routing/
    core/modules/file/tests/modules/file_test_views/config/
    core/modules/file/tests/src/Kernel/Views/RelationshipNodeFileDataTest.php
    core/modules/node/tests/src/FunctionalJavascript/NodeDeleteConfirmTest.php
    core/modules/system/tests/modules/path_changed_helper_test/
    core/modules/views/tests/src/FunctionalJavascript/RedirectAjaxTest.php
    core/tests/Drupal/KernelTests/Core/Routing/PathChangedHelperTest.php
    core/tests/Drupal/Tests/Core/Routing/PathChangedHelperTest.php
    core/themes/claro/css/components/dropbutton-noscript.css
    core/themes/claro/css/components/dropbutton-noscript.pcss.css
    modules/.DS_Store
    modules/contrib/
    modules/custom/
    sites/default/files/
    sites/default/settings.php
    vendor/

no changes added to commit (use "git add" and/or "git commit -a")

```

# Answer
> 0 votes
The following is destructive, but should work. Use with care: git reset --hard HEAD; git clean . -f, then you can run git pull after. The two commands will reset your repo to exactly the same as the branch in the repo, by reverting any changes that have been made, and removing any files that aren't tracked by Git.

---
Tags: version-control
---


title: Trying to set drush

text:
# Question
Title: Trying to set drush
First, I installed Lando which also installs Docker Desktop. After installing Lando, I opened the Windows Terminal and created a folder called "Sites". Inside the "Sites" folder, I created another folder named "my-first-drupal10-app". Then, I navigated to the "my-first-drupal10-app" folder and executed the following command: `lando init --source cwd --recipe drupal10 --webroot web --name my-first-drupal10-app`.

Next, I ran the command `lando composer create-project drupal/recommended-project:10.0.x-dev@dev tmp && cp -r tmp/. . && rm -rf tmp` to create a Drupal project. Once the project was set up, I started Lando with `lando start`". I didnt have containers so it created new ones.

After that, I needed to install Drush, so I used the command `lando composer require drush/drush`. Although the installation was successful, I encountered an error when trying to execute a Drush command.

```
`C:\Users\Hya\Sites\my-first-drupal10-app>lando drush
PHP Fatal error:  Uncaught Error: Class "Symfony\Component\HttpKernel\Kernel" not found in /app/vendor/drush/drush/src/Preflight/Preflight.php:209
Stack trace:
#0 /app/vendor/drush/drush/src/Runtime/Runtime.php(84): Drush\Preflight\Preflight->loadSymfonyCompatabilityAutoloader()
#1 /app/vendor/drush/drush/src/Runtime/Runtime.php(51): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 /app/vendor/drush/drush/drush.php(77): Drush\Runtime\Runtime->run(Array)
#3 /app/vendor/drush/drush/drush(4): require('/app/vendor/dru...')
#4 /app/vendor/bin/drush(120): include('/app/vendor/dru...')
#5 {main}
  thrown in /app/vendor/drush/drush/src/Preflight/Preflight.php on line 209

Fatal error: Uncaught Error: Class "Symfony\Component\HttpKernel\Kernel" not found in /app/vendor/drush/drush/src/Preflight/Preflight.php:209
Stack trace:
#0 /app/vendor/drush/drush/src/Runtime/Runtime.php(84): Drush\Preflight\Preflight->loadSymfonyCompatabilityAutoloader()
#1 /app/vendor/drush/drush/src/Runtime/Runtime.php(51): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 /app/vendor/drush/drush/drush.php(77): Drush\Runtime\Runtime->run(Array)
#3 /app/vendor/drush/drush/drush(4): require('/app/vendor/dru...')
#4 /app/vendor/bin/drush(120): include('/app/vendor/dru...')
#5 {main}
  thrown in /app/vendor/drush/drush/src/Preflight/Preflight.php on line 209`

```

# Answer
> 0 votes
For what it's worth, I've been working with Lando for only about a month. I've not had to install Drush separately. The lando drupal recipe installs Drush for you. Try just running "lando drush cr" to see if it works.

---
Tags: 10
---


title: Set select box options in form_alter

text:
# Question
Title: Set select box options in form_alter
I have a select box named **`field_ee_project`** . I want to add the select box options dynamically on **`hook_form_alter`** .

**What i have tried**

---

```
    function gamodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
       //check whether the form is effort estimation
        if($form_id = 'node_effordestimation_form'){
            $form['field_ee_project']['und']['#options'] = effort_estimation_project_autoload();
        }
     }

    /*
     * Effort estimation project field select box
     */
    function effort_estimation_project_autoload(){
            $matches = array();
            $result = db_query("SELECT ga_id,name FROM ga_projects");
            $row = $result->fetchAll();
            $row = json_decode(json_encode($row), True);
            foreach ($row as $key => $value) {
                $matches[$value['name']] = $value['name'];
             }
            return $matches;
    }

```

But it is not working . Any idea ?

# Answer
Try this it should work.

```
 function gamodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
   //check whether the form is effort estimation
    if($form_id = 'node_effordestimation_form'){
        $form['field_ee_project']['widget']['#options']  = effort_estimation_project_autoload();
    }
 }

function effort_estimation_project_autoload(){
                $matches = array();
                $result = db_query("SELECT ga_id,name FROM ga_projects");
                $row = $result->fetchAll();
                $row = json_decode(json_encode($row), True);
                foreach ($row as $key => $value) {
                    $matches[$key] = $value['name'];
                 }
                return $matches;
        }

```
> 3 votes

# Answer
The Field Type API are more strict in Drupal 8 so that Web Services and Forms follow the same validation path. This is not always the behavior that we want.

Looking at your question again, I think that using an allowed values callback on the field would work as well.

I provided some alternatives based on the restrictions that core places on list fields below #1 as well in case the following doesn't work as intended. These could be useful for other people doing similar things.

### #1: Try to use allowed values callback for the field instead

Set an allowed\_values\_callback for the list field.

```
function gamodule_allowed_values_callback(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL, &$cacheable = TRUE) {
  // @todo make this a bit more conditional based on the parameters above.
  $result = db_query("SELECT ga_id,name FROM ga_projects");
  $row = $result->fetchAll();
  $row = json_decode(json_encode($row), True);
  foreach ($row as $key => $value) {
    $matches[$key] = $value['name'];
  }
  return $matches;
}

```

Note that the documentation for callback\_allowed\_values\_callback mentions using opt groups, but this functionality has a bug and is broken in 8.

### #2: Migrate list field to text field

Make a Select list Field Widget for text fields. Migrate your data over.

Risks * A lot of work to re-architect.
* May confuse a development team inheriting the site.

### #3: Override the AllowedValues constraint plugin

Use `hook_validation_constraint_alter` to provide your own Constraint plugin (see Symfony 2 Constraint documentation).

Risks * Site is incompatible with a couple of contrib modules doing the same thing (select\_or\_other, cck\_select\_other).

### #4: Make sure all possible allowed values are in the list field

Don't use a custom table to store allowed values. Set the allowed values in list field configuration. Write a field widget plugin.

Write your own Field Widget that restricts options based on some other parameter like your query.

### #5: Override Core handling of list field plugins with your own implementation

Use `hook_field_info_alter` to not use Core code at all. Write your own List Field Type plugin with a better Options or Allowed Values implementation.

Risks * May confuse a development team inheriting the site.
* All list fields now behave this way.
> 7 votes

# Answer
To set options dynamically use `allowed_values_function`  in field instance definition configuration.

Refer : https://chromatichq.com/insights/dynamic-default-and-allowed-values-list-fields-drupal-8/
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Config Export changes to different folder
Is it possible to export only the changed configuration files to a specified folder?

When you run `drush cex` to see the change list of files like this

```
+------------+----------------------+-----------+
| Collection | Config               | Operation |
+------------+----------------------+-----------+
|            | views.view.frontpage | Update    |
+------------+----------------------+-----------+

```

I'm trying to export updated configuration items into a specific folder so that I can get items to run from an update hook, so I need to export them somewhere other than the default config export location

Whilst doing it for a single config item isn't much trouble, it'll be a bit of a pain to move a huge list of changes to a folder

I thought that when you put the `--destination` flag on the `drush cex` command that it would export the differences to a new folder, but it does the whole lot again.

Is there a simple way to export only the changes to a directory?

# Answer
> 0 votes
Config Partial Export module supports this functionality and it has a Drush command.

# Answer
> 0 votes
I agree with @Lambic comment, it's not a good idea to mix update hooks and importing config. If you need more info about the changes copy the sync folder before drush cex and then run the command `diff`. You can use the result of diff to patch the destination. If you are only interested in the changed file names use the option `--brief`. Or use git for deployment which runs such things automatically.

---
Tags: 9, configuration
---


# Question
Title: Show block in /user/* page, not /user/*/edit
From the Drupal 8 administration, I configured a block (block created from a custom module) for display it in /user/\* pages.

It works; I see this block in /user/\* and /user/\*/edit pages. Now, I want to display my block only from /user/\* pages (the view mode), not from /user/\*/edit pages (the edit mode).

Can I do that from the Drupal Administration page? I tested it adding "!/user/\*/edit" but this has no effect.

If I can't, how can I do that from my custom module?

# Answer
> 10 votes
If you use this module then the exclamation prefix would work to exclude paths: https://www.drupal.org/project/block\_exclude\_pages

# Answer
> 8 votes
For Drupal 8 install the Route Condition Module and use the `entity.user.canonical` condition.

# Answer
> 1 votes
For drupal 7 users you can use Context module and simple add page to path /user/\* and ~/user/\*/edit/ to exclude edit page.

# Answer
> 0 votes
If it's your own custom block plugin, you can have your build function return null on node edit pages.

# Answer
> 0 votes
There is a module called Route Condition that allows you to specify exact routes (pages) to display blocks on. So for the user profile page the route would be `user.entity.canonical` (which is actually the example on the module page.

# Answer
> -1 votes
## sometimes block display settings are all you need

Block displays are set per theme. You can sometimes simply disable the block on the theme used for `/*/edit` pages and leave it enabled on the theme used for `/user/` pages.

If your site is set up this way, you can avoid extra modules, custom code and complex workarounds.

## example

On a site using Claro as the admin theme (for other themes just substitute the name in the path):

* visit `/admin/appearance` to confirm there's a check in the box labeled "Use the administration theme when editing or creating content" (if not, see note below)
* visit `/admin/structure/block/list/claro` and disable the unwanted blocks
* visit `/admin/structure/block` (the default theme block settings page) to confirm that the same blocks are still enabled

With this configuration they show at `/user/` but not at `/user/edit`.

## note

If your site doesn't already use the admin theme when editing or creating content, checking the box will change the display of all add/edit pages (e.g. `node/add/page` and `node/123/edit`). Have a look at all add/edit pages if you make this change, as it may cause some changes you'd need to address separately, like adjusting theme templates.

# Answer
> -3 votes
Why don't you try just to hide on the pages you don't want it to be displayed instead of using "Show for the listed pages"? Change the option with "Hide for the listed pages" and add there user/\*/edit and every other page where you don't want that block to be displayed.

---
Tags: users, 8, blocks
---


# Question
Title: How can I check if an element has a CSS class that matches a value in an array?
In Drupal 9, I'm trying to check if an element has a certain css class using `hasClass()`.

```
<p{{ attributes }}>Does this element have my css class?</p>

{% if attributes.hasClass('my-css-class') %}
  <p>Yes it does!</p>
{% else %}
  <p>No it doesn't.</p>
{% endif %}

```

Instead of checking for one class, I would like to check if my element has one of the classes contained in an array.

```
{%
  set my_css_classes = [
    'class-one',
    'class-two',
    'class-three'
  ]
%}

```

How can I check if my element has a class that matches one (or more) of the values in the `my_css_classes` array?

# Answer
> 3 votes
Yeah, a simple loop should do:

```
{% set class_match = null %}

{% for class in my_css_classes %}
  {% if attributes.hasClass(class) %}
    {% set class_match = true %}
  {% endif %}
{% endfor %}

{% if class_match %}
  <p>Match exists</p>
{% endif %}

```

---
Tags: theming, 9
---


# Question
Title: Extra Block Types (EBT) settings error after push
I've added and enabled the Extra Block Types, Core and Core Remover Helper, modules on my local site. Enabling them also enabled multiple dependencies including Field and Field Group.

The site works fine locally, but I just pushed it to Pantheon dev and I get an error. Clearing the caches (either the button on dev, or via Terminus) didn't help.

Looking at the error logs, I see these errors.

> Uncaught PHP Exception Drupal\Component\Plugin\Exception\PluginException: Plugin (field\_group\_accordion) instance class Drupal\field\_group\Element\Accordion does not exist. at /code/web/core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php line 97

> Unable to determine class for field type 'ebt\_settings' found in the 'field.storage.block\_content.field\_ebt\_settings' configuration at /code/web/core/modules/field/src/FieldStorageConfigStorage.php line 167

I see that there is an *Extra Block Types (EBT): Accordion / FAQ* module available, which I haven't installed on local.

Why does the site work on local but not on dev?

# Answer
When Extra Block Types was installed locally via Home / Administration / List in Drupal, it installed Field Group automatically, bypassing Composer. The app broke when I pushed to Pantheon Dev because Field Group was missing.

I uninstalled Field Group locally, installed it via Composer, then pushed back to Pantheon Dev. Problem solved.
> 0 votes

---
Tags: 10
---