# Question
Title: Accordion is not working in field group module
I have configured the Field group module for Drupal 8 to manage the display of my node into accordion. I added an accordion wrapper, and assigned an accordion item into it. Lastly, added the fields into the accordion-item. But it does not seem to work as expected. Please suggest what I might be missing.

# Answer
> 0 votes
Please make sure you have installed and enabled https://www.drupal.org/project/jquery\_ui\_accordion

---
Tags: 8, entities, navigation
---


title: Using #states in a form with checkboxes

text:
# Question
Title: Using #states in a form with checkboxes
I would like when a client check one of the checkboxes, a text field appeares. Example: if he clicks on 3 checkboxes, all the textfields of the 3 show off. My #checkboxes :

```
$form['input']['livraison'] = [
      '#title' => t('Options de livraison (à la charge de l’acheteur)'),
      '#type' => 'checkboxes',
      '#description' => t(''),
      '#options' => [
        'home' => $this->t('Retrait chez moi (gratuit)'),
        'hand' => $this->t('Remise en main propre (gratuit)'),
        'myself' => $this->t('Je livre moi-même le produit'),
        'colissimo' => $this->t('Colissimo'),
        'custom' => $this->t('Livraison personnalisée'),
      ],
      '#attributes' => [
        //define static name and id so we can easier select it
        'id' => 'select-shipping',
        'name' => 'field_select_shipping',
      ],
    ];

```

and my textfield :

```
$form['input']['adresse_home'] = [
      '#type' => 'textfield',
      '#title' => 'Adresse',
      '#required' => false,
      '#states' => [
        //show this textfield only if the radio 'other' is selected above
        'visible' => [
          ':input[name^="field_select_shipping"]' => [['checked' => 'false'], ['value' => 'home']],
          ':input[name^="field_select_shipping"]' => [['checked' => 'false'], ['value' => 'hand']],
          ':input[name^="field_select_shipping"]' => [['checked' => 'false'], ['value' => 'myself']],
          ':input[name^="field_select_shipping"]' => [['checked' => 'false'], ['value' => 'colissimo']],
          ':input[name^="field_select_shipping"]' => [['checked' => 'true'], ['value' => 'custom']],
],
      ],
    ];

```

\**Solution : \**

As berramou sent, this way is the one that works the best with checkboxes.
If you have any issues with it look if a plugin couldn't block states, that what happened to me with iCheck.
If you need to show all the input's checked, just put the TRUE condition in your 'visible', this way you can select 2 options and get both display correctly.

# Answer
To use state for checkboxes element, you should target the specific element by JQuery selector, all elements they have the `name="field_select_shipping"` with `value` attribute different so try to target the input with both attributes try with the following to show adresse\_home only if `home` and `colissimo` checkbox checked:

```
$form['input']['adresse_home'] = [
      '#type'     => 'textfield',
      '#title'    => 'Adresse',
      '#required' => FALSE,
      '#states'   => [
        'visible' => [
         ':input[name="field_select_shipping"][value="home"]' => ['checked'   => TRUE],
         // This like AND so the input show if home and colissimo checked
        ':input[name="field_select_shipping"][value="colissimo"]' => ['checked'   => TRUE],
        ],
      ]
    ];

```
> 7 votes

# Answer
Your approach is right but you have the wrong syntax.

```
$form['input']['adresse_home'] = [
  '#type' => 'textfield',
  '#title' => 'Adresse',
  '#required' => false,
  '#states' => [
    'visible' => [
      ':input[name^="field_select_shipping"]' => [['checked' => 'true'], ['value' => 'home']],
     // Omitted the rest.
  ],
];

```

**UPDATE** As commented here you need to set the name properly which already includes the value. I did not get that to work but using ^= selector and using AND target conditions I got it to work.

An excelent article about Form States API, thought is Drupal 7 is totally valid.
> 0 votes

# Answer
In a custom form, you need to look at how names are written in the DOM. The name includes the id in brackets, so you need to add that in the state selector. Here's a working example:

```
$form['check'] = [
  '#type' => 'checkboxes',
  '#title' => $this->t("Title"),
  '#options' => [
    'OPT1' => $this->t("Option 1"),
    'OPT2' => $this->t("Option 2"),
    'OPT3' => $this->t("Option 3"),
  ],
];

$form['example'] = [
  '#type' => 'textfield',
  '#title' => $this->t("Example"),
  '#states' => [
    'visible' => [
      ':input[name="check[OPT3]"]' => ['checked' => TRUE],
    ],
  ]
];

```
> 0 votes

---
Tags: 8, forms, javascript, ajax
---


# Question
Title: Query to fetch users with specific roles
I'm using the following code.

```
$query = \Drupal::entityQuery('user');
$query->condition('uid', [302,330], 'IN')
  ->condition('status', 1, '=')
  ->condition('field_membership_status.value', 'paid', '!=')
  ->condition('roles', ['individual','organization'], 'IN')
  ->condition('roles', ['organization_member'], 'NOT IN');

$uids = $query->execute();

$users = \Drupal::entityTypeManager()->getStorage('user')->loadMultiple(array_values($uids));

foreach ($users as $user) {
  $type= "Final membership reminder";
  \Drupal::logger('my_module')->notice("email to ".$user->getAccountName());
  \Drupal::service('vc_mailer.email.service')->send_email($type, $user);
}

```

One of the user accounts has the following roles: authenticated, individual, and organization\_member. This user account is still returned by the code; it seems like the code ignores the last condition. What is the problem?

`condition('uid', [302,330], 'IN')` is just to constrain the query to those members for testing purposes.

The SQL query is the following.

```
SELECT "base_table"."uid" AS "uid", "base_table"."uid" AS "base_table_uid" FROM "users" "base_table" INNER JOIN "users_field_data" "users_field_data" ON "users_field_data"."uid" = "base_table"."uid" INNER JOIN "user__field_membership_status" "user__field_membership_status" ON "user__field_membership_status"."entity_id" = "base_table"."uid" INNER JOIN "user__roles" "user__roles" ON "user__roles"."entity_id" = "base_table"."uid" WHERE ("users_field_data"."uid" IN ('302', '330')) AND ("users_field_data"."status" = '1') AND ("user__field_membership_status"."field_membership_status_value" != 'paid') AND ("user__roles"."roles_target_id" IN ('individual', 'organization')) AND ("user__roles"."roles_target_id" NOT IN ('organization_member'))

```

# Answer
**Snippet code to get users with some role but not some other role**: Drupal 9/10:

```
$query = \Drupal::entityQuery('user');
$Group1 = $query->orConditionGroup()
->condition('roles.0.target_id', 'organization_member', 'NOT IN')
->condition('roles.0.target_id', NULL, 'IS NULL');

$Group2 = $query->orConditionGroup()
->condition('roles.1.target_id', 'organization_member', 'NOT IN')
->condition('roles.1.target_id', NULL, 'IS NULL');

$Group3 = $query->orConditionGroup()
->condition('roles.2.target_id', 'organization_member', 'NOT IN')
->condition('roles.2.target_id', NULL, 'IS NULL');

$Group = $query->andConditionGroup()
  ->condition($Group1)
  ->condition($Group2)
  ->condition($Group3);

$query->condition('uid', 0, '<>');
$query->condition('roles', ['individual','organization'], 'IN');

$query->condition($Group);
$result  = $query->execute();

```

**Additional Info:** let's say **site has 3 roles**, excluding authenticated & anonymous role if you want to get user who has not role 'organization\_member' then you have to check that role 'organization\_member' for each role's row for individual user **as role is multiple value field.**

**Analysis:** **#1:** I also found some of articles where used query like this:

**$query-\>condition('roles.target\_id', 'organization\_member', 'NOT IN');**

Which interpret like this when query execute:

```
'roles.target_id' = 'roles.0.target_id'

```

So It 'll not scan through all the roles rows for each user entity, then unexpected result will be returned, it seems that 'NOT IN' operator not work with role field of user. **But in actual role is multivalue field.** require to use 'NOT IN' operator for per role row.

**#2:** With uid 'NOT IN' conditon works fine , as uid is single value field similarly goes with the type field of node.
> 0 votes

---
Tags: entities, 9
---


# Question
Title: Migrating Wysiwyg/Ckeditor embedded images to embeded images
I am migrating a Drupal 7 site that is using: drupal/wysiwyg:^2.9' (plus the ckeditor library) drupal/media:^2.27' drupal/media\_ckeditor:^2.14'

In Drupal 7, when you insert an image into the wysiwyg body. The source code looks like this.

```
[[{"type":"media","view_mode":"media_large","fid":"532","field_deltas":{"1":
{}},"link_text":null,"fields":{},"attributes":{"alt":"Image of a hand","height":"238","width":"278","style":"margin: 10px; width: 278px; height: 238px;
float: right;","class":"media-image media-element file-media-large","data-delta":"1"}}]]

```

After migrating this site to Drupal 9 using drush. This source code still looks the same. Is there a way to convert this markup to the Drupal 9 embedded image markup. Which looks simular to this.

```
 <drupal-entity alt="uil" data-embed-button="file_browser" data-entity-embed-
 display="image:image" data-entity-embed-display-settings="
 {"image_style":"","image_link":""}" data-entity- type="file"
 data-entity-uuid="380923a6-e8b4-4b44-b0e5-c8d807aa6fef" data-langcode="en"> </drupal-entity>

```

Do I need to use this module on the Drupal 9 site? https://www.drupal.org/project/media\_migration

# Answer
> 1 votes
Use module https://www.drupal.org/project/media\_migration

Open your settings.php file and add this:

```
// Using module - Media Migration - use method - media_embed and uuid
// https://www.drupal.org/node/3135434
$settings['media_migration_embed_token_transform_destination_filter_plugin'] = 'media_embed';
// force using data-entity-uuid instead of data-entity-id
$settings['media_migration_embed_media_reference_method'] = 'uuid';

```

Go to your text format and checkbox tick 'Embed media'. Set it to use ckeditor Drag the media button onto the active toolbar.It is okay to check and use these filters:Align images, Caption images, Track images uploaded via a Text Editor

# Answer
> 0 votes
I had the same exact problem. Tried https://www.drupal.org/project/media\_migration but just couldn't seem to get it to work. So, I went old school. I figured that I could write a migration source plugin that would take this:

```
[[{"type":"media","view_mode":"media_large","fid":"532","field_deltas":{"1":
{}},"link_text":null,"fields":{},"attributes":{"alt":"Image of a hand","height":"238","width":"278","style":"margin: 10px; width: 278px; height: 238px;
float: right;","class":"media-image media-element file-media-large","data-delta":"1"}}]]

```

And convert it to a ckeditor compatible D9 image link.

In my migration module, I created two functions:

```
<?php
/**
* Get the inline image link info for this fid
*
* Requires: fid
*
* Returns an array with the FileName, UUID and RealPath for the fid image
*
* Array containing uuid, filename and realpath to file
*
* Array
* (
* [uuid] => 2a8c2c69-7cc9-43cd-9d79-3ee22e59c0a7
* [filename] => node label - hidden.jpg
* [path] => /var/www/html/websites/drupal9/master1and1/private/master1and1/node label - hidden.jpg
* )
*
*/
function sbn_migrations_get_image_link_info($fid) {

 $link_info = [];

$database = \Drupal\Core\Database\Database::getConnection('default', 'default');

$query = $database->select('file_managed', 'fm');
$query->condition('fm.fid', $fid, '='); // Find this fid
$query->fields('fm', ['uri']);
$query->fields('fm', ['uuid']);
$query->fields('fm', ['filename']);
$result = $query->execute();
foreach ($result as $record) {
$link_info['uuid'] = $record->uuid;
$link_info['filename'] = $record->filename;
  $uri = $record->uri;
  $link_info['path'] = \Drupal::service('file_system')->realpath($uri);
$link_info['path'] = str_replace(' ', '%20', $link_info['path']);
}

return $link_info;
}
/**
* Insert the correctly formatted D9 link into text body
*
* Requires: body text field
*
* Returns updated body text field with correct links (if necessary)
*
*
*/
function sbn_migrations_insert_link_into_body($body) {

$body;
$array = [];
$pattern = '/\[\[[^\]]+\"fid\"\:\"([0-9]+)\"\,[^\]]+\]\]/i';

preg_match_all($pattern, $body, $array); // search for the d7 code
// dpm($array); // Test
if (empty($array)) return $body; // if no code is found, return the $body

// If code is found, we continue on.

foreach ($array[1] as $key => $fid) {

$link_info = sbn_migrations_get_image_link_info($fid); // get the link information for this $fid
// Only continue processing if something is returned
if (!empty($link_info) && !is_null($link_info)) {
// Create the link
  $link = '<img alt="'.$link_info['filename'].'" data-entity-type="file" data-entity-uuid="'.$link_info['uuid'].'" src="'.$link_info['path'].'" />';
  $pattern01 = '/(\[\[)[^\]]+\"fid\"\:\"('.$fid.')\"\,[^\]]+(\]\])/i'; // this is the pattern for replacing links in the body text
  $replacement = $link; // this will be the the new $link replacing the old code.
  $body = preg_replace($pattern01, $replacement, $body); // this is the new body text
  \Drupal::messenger()->addStatus('(info) insert link into body processing fid value '.$fid.' | '.$link_info['filename']);

}
}
return $body;
}
?>

```

Then, in the **prepareRow()** section of my source plugin, I added this:

```
<?php
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {

// Check the $body_value for inline image links
$body_value = $row->getSourceProperty('body_value');
$body_value = sbn_migrations_insert_link_into_body($body_value); // Check body for image links
$row->setSourceProperty('body_value', $body_value);

return parent::prepareRow($row);
}

?>

```

Essentially, I am scanning the body text of my source input and replacing the D7 ckeditor image links with D9 formatted links. I use php regex functions **preg\_replace()** and **preg\_match\_all()** to find the old code and replace it with new.

This works because the files referenced in the D7 links are migrated by the Drupal d7\_file migration and they are in the correct public/private locations. I use `\Drupal::service('file_system')->realpath($uri)`, create the new D9 (standard html) link, and I'm in business.

Just sharing an alternate method for getting this done.

# Answer
> 0 votes
Another option is to create a simple migrate process plugin, like this:

```

namespace Drupal\your_migrate\Plugin\migrate\process;

use Drupal\migrate\Annotation\MigrateProcessPlugin;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;

/**
 * Converts the media embed from D7 to D10 media embed in body
 *
 * @MigrateProcessPlugin(
 *   id = "body_with_embed_media"
 * )
 */
class BodyWithEmbedMedia extends ProcessPluginBase implements ContainerFactoryPluginInterface {
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    public $entity_type_manager,
    public $file_usage,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): BodyWithEmbedMedia|static {
    return new static (
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
     $container->get('file.usage'),
    );
  }

  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property): array {
    $text = $value['value'];
    if (preg_match_all('/\[\[\{"fid":"(\d+)".*?\]\]/m', $text, $matches) > 0) {
      $replacements = [];
      foreach ($matches[1] as $id => $fid) {
        $file = $this->entity_type_manager->getStorage('file')->load($fid);
        $result = $this->file_usage->listUsage($file);
        $media_id = array_keys($result['file']['media'])[0];
        $media = $this->entity_type_manager->getStorage('media')->load($media_id);
        $replacements[$id] = 'uuid() . '"> ';
      }
      $value['value'] = str_replace($matches[0], $replacements, $value['value']);
    }
    return $value;
  }
}

```

And in your migration yaml in the process section you'll just use it like this:

```

  body:
    -
      plugin: body_with_embed_media
      source: body

```

**Warning! This code will only works with PHP 8.2 and higher.** To make it work in PHP versions lower than 8.2 you need to get rid of the constructor property promotion (https://stitcher.io/blog/constructor-promotion-in-php-8)

---
Tags: migrations, wysiwyg, 9
---


# Question
Title: How can I make a core link field have the option to open in a new tab?
I have created a block type with some fields, but then I created a link type for some buttons and I need this link type field to have the option to open in a new tab when the content is uploaded.

Is there a way to implement it, a module? I hope you can help me, thank you very much!

# Answer
> 1 votes
I'm not sure I understood the question completely, but you can probably use the Link Attributes widget module.

> ## Overview
>
> Link attributes widget provides an additional widget for the link field found in Drupal core.
>
> The widget allows users to set attributes on their link.
>
> In addition the module alters the default menu link content link field to use this widget, allowing menu links to have attributes too
>
> ## Features
>
> Supported attributes include
>
> * id
> * class
> * name
> * target
> * rel
> * accesskey
> * aria-label (since 8.x-1.3)
> * title (since 8.x-1.7)
> * Linkit support (since 2.1.0) - via a submodule

If that doesn't help, its source code can definitely guide you to a custom solution.

---
Tags: 10
---


# Question
Title: DrupalDateTime showing the date of the previous day and not the correct date while setting it
I have got the date from the url query parameter but while setting it to the default value of field\_date form element it is showing the date of the previous day and not the correct date.

use Drupal\Core\Datetime\DrupalDateTime;

```
function time_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
    // Get the current request object and a specific parameter from the URL query.
    $request = \Drupal::request();
    $parameter_value = $request->query->get('param');
    if ($form_id == 'node_time_entry_form'){
      $form['field_date']['widget'][0]['value']['#default_value'] = new DrupalDateTime($parameter_value);
    }

```

# Answer
Each date string is only valid for a specific timezone:

```
$date = new DrupalDateTime($date_string, 'America/Yellowknife');

```

If you don't specify a timezone the date/time object will be instantiated with the default timezone set for your system. So you might be able to solve the problem also by changing the site or user timezone settings.
> 2 votes

---
Tags: datetime
---


# Question
Title: Fields/custom text show translated label for field
I am building a bilingual site with Drupal 10 and I am using views to show content items listings. In my views I am using field: Custom text to format the teasers of each item the way I want.

I have translated all the fields of my content types and my issue is how to show in the custom text each field's label.

Here is how my view's configuration looks like:

Here is an example of such a custom text:

```
<div class="col-sm-12 teaser-wrapper">
    <div class="teaser-image">{{ field_image }}</div>
    <div class="teaser-header">{{ title }}</div>
    <div class="teaser-text">{{ body }}</div>
    <div class="row teaser-field">
        <div class="col-xs-12 col-sm-12 teaser-field">
                <span class="lbl">Location: </span>
                <span class="val">{{ field_region }}</span>
        </div>
        <div class="col-xs-12 col-sm-12 teaser-field">
                <span class="lbl">Path Length: </span>
                <span class="val">{{ field_path_length }}</span>
        </div>
        <div class="col-xs-12 col-sm-12 teaser-field">
                <span class="lbl">Activities: </span>
                <span class="val">{{ field_nature_activities }}</span>
        </div>
    </div>
</div>

```

As you can see at the moment I am just using hardcoded values for the labels.

How can I print their translated values?

# Answer
You can use

```
<span class="lbl">{% trans %}Location{% endtrans %}: </span>

```
> 0 votes

---
Tags: views, i18n-l10n
---


# Question
Title: Clearing cache via admin_toolbar results in white screen with "Redirects to external URLs are not allowed by default"
After pressing this admin\_tool button to Flush all caches, the browser hangs on a white screen with the message: `Redirects to external URLs are not allowed by default, use \Drupal\Core\Routing\TrustedRedirectResponse for it`. The hung URL is `/admin/flush?token=wieu87APDL`

* This only happens on production, not local
* Clearing cache in `/admin/config/development/performance` works fine

# Answer
> 1 votes
This is no doubt the admin\_toolbar contributed module. Looking at a bug report to the issue that is identical to this question it is likely that there is a caching proxy with this website and that Drupal is not set up to trust the IP addresses of that proxy.

---
Tags: redirection
---


# Question
Title: Generating <button type="submit"> with the form API
I have a heavily themed form to integrate, whose structure is shown below. I am just about there for the most part except for the submit.

```
 <form action="#">
   <fieldset>
     <legend>Authentification</legend>
       <label for="email">Courriel*</label>
       <input type="text" name="email" id="email">
       <label for="password">Mot de passe*</label>
       <input type="password" name="password" id="password" class="last">
       <a href="#" title="Mot de passe oublié?" class="clearfix">Forgot password?</a>
       <button type="submit" class="clearfix"><span>Login</span></button>
   </fieldset>
 </form>

```

I have tried many different combinations, turns out button\_type has no effect on core. So I used this hack, hoping it would fix my issue. Alas, it only changes the 'type' attribute (obviously), and not the element itself. The button type can hold other elements, in this case the span is needed to hold a background image, it needs to be in a span to stretch as the text in the button is dynamic.

Does anyone have a clue as to how I can generate the following line of markup using the form API?

```
<button type="submit" class="clearfix"><span>Login</span></button>

```

# Answer
In D7 would recommend:

```
$form['custom-form'] = array(
  '#prefix' => '<button type="submit">',
  '#suffix' => '</button>',
  '#markup' => '<span>' . t('Login') . '</span>',
);

```

That way you can replace the #markup in an alter function later if needed, without having to rebuild the button HTML.
> 12 votes

# Answer
As an addition, just in case someone runs into the same trouble as I did - when using the `#markup` or `#prefix`/`#suffix` trick on a form's `actions` group, the submit callback function **won't be called at all**, unless a `submit` type element is present. My workaround was like this:

```
$form['actions']['submit'] = array
(
    '#type' => 'submit',
    '#value' => '',
    '#attributes' => array( 'style' => array( 'display: none' )), // hide the input field
    '#submit' => array( 'my_callback_for_the_form_submit' ),
    '#prefix' => '<button type="submit" class="btn btn-primary">Add <i class="fa fa-plus-square-o">',
    '#suffix' => '</i></button>',
);

```

That way you can use custom HTML for submit action groups.
> 18 votes

# Answer
To add some custom tag you can use the following snippets:

```
// Drupal 6.
$form = array();

// Other elements.

$form['custom-form'] = array(
    '#value' => '<button type="submit" class="clearfix"><span>Login</span></button>',
);

```

```
// Drupal 7.
$form = array();

// Other elements.

$form['custom-form'] = array(
    '#markup' => '<button type="submit" class="clearfix"><span>Login</span></button>',
);

```
> 4 votes

# Answer
Just for completeness I'll post an alternative solution that involves overriding `theme_button` (taken from this blog post)

First add a `buttontype` attribute to the form element:

```
$form['submit'] = array (
    '#type' => 'submit',
    '#buttontype' => 'button',
    '#value' => 'Search',
);

```

And then override theme button:

```
/**
 * Override of theme_button().
 *
 * Render the button element as a button and the submit element as an input element.
 */
function MYTHEME_button($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'submit';

  element_set_attributes($element, array('id', 'name', 'value'));

  $element['#attributes']['class'][] = 'form-' . $element['#button_type'];
  if (!empty($element['#attributes']['disabled'])) {
    $element['#attributes']['class'][] = 'form-button-disabled';
  }

  if (isset($element['#buttontype']) && $element['#buttontype'] == 'button') {
    $value = $element['#value'];
    unset($element['#attributes']['value']);
    return '<button' . drupal_attributes($element['#attributes']) . '>' . $value . '</button>';
  }
  else {
    return '<input' . drupal_attributes($element['#attributes']) . ' />';
  }
}

```

This creates problems however if there is more that one button in the form as Drupal is unable to detect which button has been clicked.

This can be addressed by adding an `#after_build` callback to the form:

```
$form['#after_build'][] = 'mymodule_force_triggering_element';

```

And then in the after build function:

```
function mymodule_force_triggering_element($form, &$form_state) {
  if (isset($form_state['input']['submit'])) {
    $form_state['triggering_element'] = $form['submit'];
  } elseif (isset($form_state['input']['other_button'])) {
    $form_state['triggering_element'] = $form['other_button'];
  }
  return $form;
}

```
> 2 votes

# Answer
Here is how I achieve this in Drupal 8. Basically I create a new theme suggestion so i can override the button with a custom twig file.

Add this code inside your mythemename.theme file:

```
/**
 * Add twig suggestions for input elements.
 *
 * If a form api element has a data-twig-suggestion attribute, then allow twig
 * theme override, add to suggestions.
 *
 * @param array $suggestions
 *   Current list of twig suggestions.
 * @param array $variables
 *   Every variable of the current element.
 */
function mythemename_theme_suggestions_input_alter(&$suggestions, array $variables) {
  $element = $variables['element'];

  if (isset($element['#attributes']['data-twig-suggestion'])) {
    $suggestions[] = 'input__' . $element['#type'] . '__' . $element['#attributes']['data-twig-suggestion'];
  }
}

```

In your code wherever you create your form, add a 'data-twig-suggestion' attribute to your submit button:

```
$form['submit'] = [
      '#type' => 'submit',
      '#value' => t('Submit') . ' >',
      '#attributes' => [
        'data-twig-suggestion' => 'button',
      ],
    ];

```

Now if you have twig debug enabled and you check the html source of your button on the site, you will see a new twig suggestion:

```
<!-- FILE NAME SUGGESTIONS:
   * input--submit.html.twig
   * input--submit--button.html.twig
   x input.html.twig
-->

```

Now you can create a input--submit--button.html.twig file (I place this in mythemename/templates/form\_elements but you can place it elsewhere if you like):

```
<button{{ attributes }} type='submit'>
    <span class="great-success">Submit</span>
</button>

```
> 2 votes

# Answer
I tried Óscar Gómez Alcañiz's answer but my form was *still* not getting submitted. As a workaround I altered his solution so the input was sitting over top of the button but was transparent:

```
$form['actions']['submit'] = array (
    '#type' => 'submit',
    '#value' => '',
    '#attributes' => array( 'style' => 'position: absolute; left: 0; right: 0; top: 0; bottom: 0; border: none; opacity: 0; width: 100%;'), // put input field over the top of button and make transparent
    '#prefix' => '<button type="submit" class="btn btn-primary">Add <i class="fa fa-plus-square-o">',
    '#suffix' => '</i></button>',
);

```

This way the actual `input[type="submit]` is getting clicked and triggering the action but the button

Probably a good idea to put all that CSS in a stylesheet in real life but just put in the inline style tag here as an example.
> 1 votes

# Answer
Keeping with the forms api and rendering a button, **html\_tag** type does the trick:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21HtmlTag.php/class/HtmlTag

https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme\_html\_tag/7.x

```
$form['my_button'] = [
  '#type' => 'html_tag',
  '#tag' => 'button',
  '#value' => t('My Button'),
  '#attributes' => $attributes,
];

```
> 0 votes

# Answer
More correct way is:

```
$form['submit'] = array(
  '#type' => 'button',
  '#value' => '<span>Login</span>',
);

```

It produces valid HTML like this:

```
<button value="<span>Login</span>" type="submit">
    <span>Login</span>
</button>

```

...and this method doesn't brake autocomplete and other features.
> -3 votes

---
Tags: forms
---


# Question
Title: admin user interface language is changed to another user's preferred language
I have a weird situation. I as an admin have the preferred language set to English and I want to edit another user that has a preferred language set to something different (French for example). When I click the edit button, the url contains the "fr" prefix and obviously the site's language is changed. It goes back to english if I save the changes or if I set the administration language to English for admin account, but if I just continue browsing the site's language will be changed to French because of that prefix.

Is there any way I can edit any user without having the language prefix in the url if they have a different preference? Thanks.

# Answer
There are various factors that can influence which language is used to display a page. For example,

* The language prefix in the URL
* The user's selected language
* The user agent (browser) language

Drupal lets you choose the priority for each of these. Further, you can set a different preference for **Interface language** (the UI language) and **Content language**.

To do so, as an administrator, visit `/admin/config/regional/language/detection`.

It sounds like you want to make sure that **Account administration pages** is enabled and at the top of the list for **Interface language detection**.
> 0 votes

---
Tags: 8, i18n-l10n
---


# Question
Title: Implement anti-CSRF tokens into all requests to add protection from cross-site request forgery attacks
Is there any module or technique to implement anti-CSRF tokens into all requests in Drupal 9 for anonymous users?

# Answer
Drupal already has CSRF protection for authenticated users.

One day core may add support to protect anonymous users as well.

In the meantime, you could look at the anonymous token module, or force all users to register/log in before using forms on the site.
> 1 votes

---
Tags: security, csrf
---


title: Adding class to form-item

text:
# Question
Title: Adding class to form-item
I've been trying to add a custom classname to a form-item to use as a 'marker' for theming with my css file.

I've been on stackexchange/overflow and several other sites and forums, including the Drupal documentation, but found no reason why it shouldn't work.

Official documentation state the use of the attribute tag like so:

```
'#attributes' => array('class' => 'myclass'),

```

But as seen in my example below, this doesn't work or give me errors.

Am I doing something wrong?

# Answer
> 2 votes
#attributes is not supported by item form elements.

> ### item
>
> **Description:** Generate a display-only form element allowing for an optional title and description.
>
> **Note:** since this is a read-only field, setting the #required property will do nothing except theme the form element to look as if it were actually required (i.e. by placing a red star next to the #title).
>
> **Properties:** #access, #after\_build, #description, #element\_validate, #parents, #post\_render, #prefix, #pre\_render, #required, #suffix, #theme, #title, #tree, #type, #value, #weight

You would then need to add a custom theme call such as:

`function MYTHEME_preprocess_form_element(&$vars) {
 $vars['#attributes']['class'][] = 'another-class';
}`

# Answer
> 0 votes
In the end, I solved it by adding code to the .module file. I wrapped a div with class around the content.

# Answer
> 0 votes
You could use `_form_set_class()`

Docs: https://api.drupal.org/api/drupal/includes!form.inc/function/\_form\_set\_class/6.x

Example:

```
_form_set_class($element, array('my-class'));

```

# Answer
> 0 votes
It turns out that although you cannot use `#attributes` with `'#type' => 'item'`, you can use `#wrapper_attributes`.

See https://github.com/backdrop/backdrop-issues/issues/3817 for details/background.

# Answer
> -1 votes
for the future, if you use the #attributes, wrap the class name(s) in an array like this:

```
'#attributes' => array('class' => array('myclass', 'otherclass')),

```

---
Tags: 6, theming, forms
---


# Question
Title: How do I sort view results by query order?
In my twig I use `{{ drupal_view('slider', 'block_1', '74,84,82' ) }}`, how can I make sure the output of this view has the slides in that specific order?

Currently on D9. I've looked around but can't seem to find any relevant info on how to achieve this. Doesn't seem like this should be that complicated?

# Answer
I don't think views is a good choice if you manally want to choose and order items. Views basically is a database query, to be sorted and filtered automatically by a database column (like title field). Instead create the slider markup in the template file, and then render the individual entities by ID (or by IDs sourced and ordered in an entity reference field, if you want to control it in a GUI).

Pseudo-code (using Twig Tweak's `drupal_entity`):

```
<div class="my_slider_container">
  <div class="my_slider_item">{{ drupal_entity('node', 74, 'teaser')  }}</div>
  <div class="my_slider_item">{{ drupal_entity('node', 84, 'teaser')  }}</div>
  <div class="my_slider_item">{{ drupal_entity('node', 82, 'teaser')  }}</div>
</div>

```
> 0 votes

---
Tags: views, nodes, database
---


title: Custom Field Type Checkboxes

text:
# Question
Title: Custom Field Type Checkboxes
I'm trying to create a custom FieldType. I've found many example with a textfield. But I want a custom field with checkboxes. I'm having a hard time finding an example like that.

If anyone can help me out, it would be greatly appreciated.

I have the field made, correct options showing up. I'm currently stuck with the incorrect primitive type. I'm not sure how to set this up properly.

Here's my code for the FieldType, FieldWidget and config.

```
<?php

namespace Drupal\field_active_bundles\Plugin\Field\FieldType;

use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

/**
 * Plugin implementation of the 'field_active_bundles' field type.
 *
 * @FieldType(
 *   id = "field_active_bundles",
 *   label = @Translation("Active Bundles"),
 *   module = "field_active_bundles",
 *   category = "Custom",
 *   description = @Translation("Selects active bundles for component."),
 *   default_widget = "field_active_bundles_widget",
 *   default_formatter = "field_active_bundles_formatter"
 * )
 */
class ActiveBundles extends FieldItemBase {

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return [
      'columns' => [
        'value' => [
          'type' => 'text',
          'size' => 'tiny',
          'not null' => FALSE,
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $value = $this->get('value')->getValue();
    return $value === NULL || $value === '';
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('string')->setLabel(t('What ever'));
    return $properties;
  }

}

```

```
<?php

namespace Drupal\field_active_bundles\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'field_active_bundles' widget.
 *
 * @FieldWidget(
 *   id = "field_active_bundles_widget",
 *   module = "field_active_bundles",
 *   label = @Translation("Default checkboxes"),
 *   field_types = {
 *     "field_active_bundles"
 *   }
 * )
 */
class ActiveBundlesWidget extends WidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $bundle_info = \Drupal::service('entity_type.bundle.info')->getBundleInfo('entity_product');

    foreach ($bundle_info as $key => $value) {
      $options[$key] = $value['label'];
    }

    $element['value'] = [
      '#type' => 'checkboxes',
      '#title' => 'Active Bundles',
      '#options' => $options,
      '#element_validate' => [
        [$this, 'validate'],
      ],
    ];

    if ($element['#required']) {
      $element[$key]['#required'] = TRUE;
    }

    return ['value' => $element];
  }

  /**
   * Validate the fields and convert them into a single value as text.
   */
  public function validate($element, FormStateInterface $form_state) {
    // TBD.
  }

}

```

```
# @see Configuration schema/metadata at https://drupal.org/node/1905070
field.field_active_bundles.value:
  type: sequence
  label: 'Default value'
  sequence:
    - type: mapping
      label: 'Default'
      mapping:
        value:
          type: string
          label: 'Value'

```

# Answer
> 0 votes
It seems the only custom requirement is providing dynamic checkboxes items. You could use the core field list type and provide the options in this callback:

*mymodule.module*

```
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\field\Entity\FieldStorageConfig;

function mymodule_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) {
  $options = [];
  $bundle_info = \Drupal::service('entity_type.bundle.info')->getBundleInfo('entity_product');
  foreach ($bundle_info as $key => $value) {
    $options[$key] = $value['label'];
  }
  return $options;
}

```

See How do I programmatically update the allowed values of a list field?

However, for this specific case there is a UI-only solution by adding a multi-value reference field for other entities and then specifying the config entity for the product bundles.

---
Tags: 9
---


title: Add views block to views header

text:
# Question
Title: Add views block to views header
I want to have the views header elements after exposed filters, so i try to get the filters in the header. For that, i expose them in a block, and try to add that block to headers, but no success. I also tried to show the filters-block on the view's page (an admin path) via the block settings (show in content area, only on pages admin/content/myview), also no success.

To add a generic block to a views header via UI, there's the module https://www.drupal.org/project/views\_block\_area

On the module page it says

> Blocks that are generated by views, can't be selected. These blocks can be inserted by views areas.

But i can't see how to do that. When i add a view area to my view's header, i have the view which generates the exposed-filters block, but the block is not listed, only the default and an attachment i have in that view.

# Answer
> 0 votes
The easiest way to do that is to modify your View template. Identify it in the third column (Advanced), section Theme : informations (by default views-view.tpl.php). Find it (usually in sites/all/modules/views/theme). Then you will just have to reorganize this tpl file. In your case, you just need to switch two sections like this :

```
<?php if ($exposed): ?>
<div class="view-filters">
  <?php print $exposed; ?>
</div>

```

```
<?php if ($header): ?>
<div class="view-header">
  <?php print $header; ?>
</div>

```

# Answer
> 0 votes
Add views block to views header: Drupal 8/9/10

This can be done from backend by voew UI

Install & enable twig tweak module

Edit particular view & click on header section, add following code:

```
{{ drupal_view('view_name', 'display_name') }}

```

---
Tags: blocks, views
---


# Question
Title: How to update migration field mapping using custom module/form?
I was learning about Drupal migration recently and found out that we can use Migrate Plus module to import migrations as configurations. Hence I started wondering if a migration is imported as a configuration, is it possible to override/update the migration's process plugin field mapping through a custom form using the "config.factory" service. I tried implementing this and found out that the configuration update through the custom form is not taking effect in the migration end, until and unless I flush the cache in the custom form's submit handler. I feel like this is not the right way. Is there any other way to implement this without clearing the cache every time the form submits?

The submit handler for my config form looks like this -\> I am trying to change the mapping of the entity:node:body field with a different source plugin field whose id is stored in the *selectfield* field in the form.

```
public function submitForm(array &$form, FormStateInterface $form_state)
  {
    $config_factory = \Drupal::configFactory();
    $config = $config_factory->getEditable('migrate_plus.migration.data');
    $process = $config->get('process');
    $process['body'] = $form_state->getValue("selectfield");
    $config->set('process', $process);
    $config->save();
    $this->config("config.migrateform")->set("selectfield", $form_state->getValue("selectfield"))->save();
    drupal_flush_all_caches();
  }

```

# Answer
Your solution changes the migration configuration via form which would then require config export if you have staging, prod etc. environments to import the new config.

Which in the end makes you think what is the point of having a form in the first place when you can edit migration yaml file directly to achieve the same result.

However to answer the question two solutions come to mind:

Both solutions should have the form submit save only the value of the field.

```
public function submitForm(array &$form, FormStateInterface $form_state) {
  $this->config('config.migrateform')
    ->set('selectfield', $form_state->getValue('selectfield'))
    ->save();
}

```

**1. Using an event subscriber to the `migrate.pre_import` event**

Migration import fires the event at the start of the migration.

```
$this->getEventDispatcher()->dispatch(new MigrateImportEvent($this->migration, $this->message), MigrateEvents::PRE_IMPORT);

```

You can subscribe to this event and get the migration object from the event.

Migration object allows you to get and/or set the process plugin definitions.

```
/**
 * Gets the normalized process plugin configuration.
 *
 * The process configuration is always normalized. All shorthand processing
 * will be expanded into their full representations.
 *
 * @see https://www.drupal.org/node/2129651#get-shorthand
 *
 * @return array
 *   The normalized configuration describing the process plugins.
 */
public function getProcess();

/**
 * Allows you to override the entire process configuration.
 *
 * @param array $process
 *   The entire process pipeline configuration describing the process plugins.
 *
 * @return $this
 */
public function setProcess(array $process);

```

So in the event subscriber you can load the `config.migrateform` and the value `selectfield` then replace the process configuration.

```
public function onPreImport(MigrateImportEvent $event): void {
  $migration = $event->getMigration();
  // Don't do anything if migration is not the one you want to alter
  if ($migration->getPluginId() !== 'my_migration_id') {
    return;
  }

  $fieldProcess = \Drupal::configFactory()->get('config.migrateform')->get('selectfield');
  $process = $migration->getProcess();
  $process['body'] = $fieldProcess;
  $migration->setProcess($process);
}

```

This is just a subscriber method snippet, complete solution should use dependency injection.

This will alter the migration on the fly but will not update the yaml configuration which might confuse other developers looking at the migration yaml file but the migration would act differently, so it might be a good idea to add a comment to the yaml file that the event subscriber alters the behaviour. To avoid this confusion the second solution can be used.

Another issue here is that the subscriber applies to the migration id(s) you specify in the if block which would need updating if you want to use it in multiple migrations.

**2. Creating a custom plugin**

This solution requires creating a custom process plugin that can dynamically load another process plugin from form configuration and delegate the processing to the loaded plugin.

Create a custom process plugin:

```
/**
 * @MigrateProcessPlugin(
 *   id = "dynamic_process_plugin"
 * )
 */
class DynamicProcessPlugin extends ProcessPluginBase implements ContainerFactoryPluginInterface {

  protected $configFactory;

  protected $pluginManager;

  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactoryInterface $factory, MigratePluginManagerInterface $pluginManager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->configFactory = $factory;
    $this->pluginManager = $pluginManager;
  }

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('config.factory'),
      $container->get('plugin.manager.migrate.process')
    );
  }

  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $fieldProcess = $this->configFactory->get('config.migrateform')->get('selectfield');
    $processPlugin = $this->pluginManager->getInstance($fieldProcess);

    return $processPlugin->transform($value, $migrate_executable, $row, $destination_property);
  }

}

```

And use this custom plugin in the migration yaml for whatever field you want - in your case for body:

```
process:
  body:
    plugin: dynamic_process_plugin
    source: body

```

This solution is more flexible as you can add use the plugin in any migration on any field you want and there is no confusion for other developers.

*Note that I have not tested this code and it is not complete - missing namespaces, incomplete coding standards etc.*
> 0 votes

---
Tags: forms, migrations, configuration, plugins
---


# Question
Title: Add taxonomy term assignment to meta tag
Drupal core 9.3.19, Metatag module 1.21.0

We have a taxonomy term named 'KamTags' which contains 'name' field only.

The customer wants to define a bunch of KamTags taxonomy terms and have content team assign these predefined KamTags taxonomy terms to Basic Page content type.

This can be easily done in Structure -\> Content Types -\> Basic Page -\> Manage Fields -\> Add field: and select Taxonomy Term as the field type. The taxonomy term would now appears in the Basic Page Edit page body:

Here's where it gets tricky:

Instead of Basic Edit page body, the customer wants the taxonomy terms to appear and be managed in the right column, under Meta Tag -\> Basic Tags section (with Page Title, Description, Keywords, etc). I could potentially talk him into having the KamTag terms form section under Meta Tag accordion, but the main goal remains to have taxonomy terms assignment appear in the right column.

Is this even possible? Has anyone done anything like that?

# Answer
> 1 votes
**Display Field in the right sidebar for content type:**

You cam do it from backend by using "Field Group" module:

1. Go to Structure, “Content types” & click on “Manage form display” of content type.
2. Click on “Add Field Group” & select “Details Sidebar” from “Add a new group” drop-down. Add “Additional Info” into Label.
3. In “Manage form display” section, you will see newly added "Additional Info" group in the Disabled section.
4. Move “Additional Info” above Tags(Taxonomy field) and add Tags under “Additional Info” field group.
5. click on Save

# Answer
> 1 votes
**To display custom field under Meta - Tags section**

Step 1: Add field's Meta Tags Plugin :

**file Add**: 'KamTags.php' will be add in this particular folder structure:
custom\_module\src\Plugin\metatag\Tag;

```
<?php

namespace Drupal\custom_module\Plugin\metatag\Tag;

use Drupal\metatag\Plugin\metatag\Tag\MetaNameBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\taxonomy\Entity\Term;

/**
 * The standard page title.
 *
 * @MetatagTag(
 *   id = "kamtags",
 *   label = @Translation("Kam Tags"),
 *   description = @Translation("The text to display in the title bar of a visitor's web browser when they view this page."),
 *   name = "kamtags",
 *   group = "basic",
 *   weight = -6,
 *   type = "label",
 *   secure = FALSE,
 *   multiple = FALSE,
 *   trimmable = TRUE
 * )
 */
class KamTags extends MetaNameBase {
  // Nothing here yet. Just a placeholder class for a plugin.
  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function form(array $element = []) {
    $selected_kamtags = $this->value()['kamtags']['0']['target_id'];
    $form['field_kamtags'] = [
      '#type' => 'entity_autocomplete',
      '#target_type' => 'taxonomy_term',
      '#title' => $this->t('Kam Tags'),
      '#default_value' => $selected_kamtags ? Term::load($selected_kamtags) : null,
      '#tags' => TRUE,
      '#selection_settings' => [
        'target_bundles' => ['tags'],
      ],
      '#weight' => '0',
    ];

    return $form;
  }
}

```

As entity autocomplete field render array instead of term name for custom(KamTags) meta tags: to fix it, used following hook: in .module file

```
function custom_module_metatags_alter(array &$metatags, array &$context) {
  if(isset($metatags['kamtags'])){
    $tid = $metatags['kamtags']['field_kamtags'][0]['target_id'];
    if(isset($tid) && !empty($tid)){
      $term = Term::load($tid);
      if(isset($term)){
        // Render Term label
        $metatags['kamtags'] = $term->getName();
      }
    }
  }
}

```

**Note:**: In this approach you don't have to add field at entity level as custom meta tags plugin field bind at meta tags level, that you will see on following URLs:

**#1:** Meta tags config page: https://your-site\_url/admin/config/search/metatag/global

#2: At entity/node level: https://your-site\_url/node/2/edit

---
Tags: meta-tags
---


# Question
Title: How can I print a custom commerce_invoice field or custom commerce order field in the invoice pdf?
In In Drupal 9 commerce\_invoice I created a custom field for an invoice number with machine name 'field\_numero\_de\_factura' and every time I generate a new invoice, I can manually enter the invoice number. The invoice number is shown correctly in /admin/commerce/orders/%/invoices . All this is working fine.

However I can't find out how to edit the commerce-invoice.html.twig template to print the value of the field\_numero\_de\_factura in the invoice PDF.

I installed Twig Field Value and tried things like {{ invoice\_entity.field\_numero\_de\_factura|field\_value }} or {{ content.invoice\_entity.field\_numero\_de\_factura|field\_value }} in the commerce-invoice.html.twig template but no success.

Optionally it could be a custom order field instead of a custom comerce\_invoice field. Any of the solutions would suit me.

Can anyone help me out? I guess more people are struggling with similar matters.

Thanks so much

# Answer
> 0 votes
I could achieve it using `{{ invoice_entity.get('field_numero_de_factura').value }}`.

---
Tags: commerce
---


# Question
Title: getPluginDefinition custom QueueWorker empty after upgrade
I've got a custom queue worker that used to work fine in Drupal 9, but stopped working after the upgrade to Drupal 10.

I've narrowed it down to the getPluginDefinition method not returning anything. So in the core Cron.php I get a warning on the following line:

```
$lease_time = $worker->getPluginDefinition()['cron']['time'];

```

If I comment out this line, and just set the $lease\_time to 1 my QueueWorker works fine. Clearly the worker itself is OK, but getting the meta data fails for some reason.

This is what my class definition looks like:

```
namespace Drupal\module_send_pdf\Plugin\QueueWorker;

use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * A Mail Sender that sends e-mails on CRON run.
 *
 * @QueueWorker(
 *   id = "module_pdf_mail_sender",
 *   title = @Translation("PDF Mail Sender"),
 *   cron = {"time" = 105}
 * )
 */
class MailSender extends QueueWorkerBase implements ContainerFactoryPluginInterface {

protected $mailManager;

  public function __construct(MailManagerInterface $mail_manager) {
    $this->mailManager = $mail_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {

    return new static(
      $container->get('plugin.manager.mail')
    );
  }

```

As far as I can tell that markup is OK. So what am I missing?

# Answer
Please change your constructor and `create()` method to match the `ContainerFactoryPluginInterface` interface for the plugin definition details to be passed to the parent class:

```
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, MailManagerInterface $mail_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->mailManager = $mail_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('plugin.manager.mail')
    );
  }

```
> 2 votes

---
Tags: cron, 10, queue
---


title: node reference ordering

text:
# Question
Title: node reference ordering
I have a content type "Review" and there there is dropdown for brands, I want to order dropdown list by alphabetical order. is there any way to reordering drupal node reference dropdown?

# Answer
If you chose auto-complete for your node reference field & if number of item to be added is set to unlimited then you get to re-order the values which appear.

Though my answer is not proper for question which you have asked as you are asking for select field but this way I have done it..
> 0 votes

# Answer
There are 2 ways you can do this

1. By altering the menu path used for autocomplete and change the results based on your custom approach. Refer to this article here
2. Create a new view with "Entity reference" as display and in the filter choose content type, Sort results alphabetically or based on your custom needs. Add an entity reference field and then under "Entity selection" switch mode to "Views: Filter by an entity reference view" and select the view you have created.

In either way, you can get the results Alphabetically based on your needs.
> 0 votes

---
Tags: 7, theming, hooks
---


title: Command "cim" is not defined

text:
# Question
Title: Command "cim" is not defined
I'm getting the following error while running `drush cim` on a new environment to import the configurations as they exist in the repo:

`Command "cim" is not defined`

also:

`Command "config:import" is not defined`

`Command "config:export" is not defined`

`Command "config:cex" is not defined`

In trying to search for help online, nearly all of the results include the string "Drush was unable to query the database", which is NOT in my error, and I'm perplexed as to why I'm not getting better results and starting this post in the meantime.

# Answer
> 7 votes
Although this post shows the exact same error, it was for a different purpose, but it reminded me to add the debug flag to the command, making `drush cim --debug`. This showed a stack trace that included *The config sync directory is not defined in `$settings["config_sync_directory"]`*. Which is weird, because it is defined, except for a typo in the string! Fixing that typo made everything work as normal, but the error was so misleading that I'm writing it up for anyone else in the same predicament.

---
Tags: drush
---


# Question
Title: Default value for datetime field definition in content entity?
I have the following datetime field definition for my content entity:

```
$fields['start_date'] = BaseFieldDefinition::create('datetime')
  ->setLabel(t('Start date'))
  ->setDescription(t('Start date in GMT time.'))
  ->setSettings([
    'default_value' => DrupalDateTime::createFromTimestamp(time()),
  ])
  ->setDisplayOptions('view', [
    'label' => 'above',
    'type' => 'string',
    'weight' => -4,
  ])
  ->setDisplayOptions('form', [
    'type' => 'datetime_default',
    'weight' => -3,
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE);

```

As a result, when creating a new entity, I get the field display without default value set in a form. I also tried setDefaultValue method but with no luck. What is the proper way to set the default values for the custom content entities?

# Answer
> 8 votes
You need to pass in a callback function that is evaluated when the entity is saved. If you evaluate the time value in `YourEntity::baseFieldDefinitions`, then the default value will fixed at whatever time the entity type was installed.

`DrupalDateTime::createFromTimestamp` can't serve as a callback because it expects you to pass a timestamp. The default value callback needs to take two arguments: the entity being saved and the field definition itself:

* `\Drupal\Core\Entity\FieldableEntityInterface $entity`
* `\Drupal\Core\Field\FieldDefinitionInterface $definition`

See the API docs: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Field%21FieldConfigInterface.php/function/FieldConfigInterface%3A%3AsetDefaultValueCallback/8.7.x

So you'll need to create a callback function, e.g.

```
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;

// ...

function mymodule_get_current_datetime($entity, $definition) {
  $current_time = DrupalDateTime::createFromTimestamp(time());
  return $current_time->format(DateTimeItem::DATETIME_STORAGE_FORMAT);
}

```

And then pass that callback as a string.

```
$fields['start_date'] = BaseFieldDefinition::create('datetime')
  ->setLabel(t('Start date'))
  ->setDescription(t('Start date in GMT time.'))
  ->setDefaultValueCallback('mymodule_get_current_datetime')
  ->setDisplayOptions('view', [
    'label' => 'above',
    'type' => 'string',
    'weight' => -4,
  ])
  ->setDisplayOptions('form', [
    'type' => 'datetime_default',
    'weight' => -3,
    'default_value' => DrupalDateTime::createFromTimestamp(time()),
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE);

```

# Answer
> 3 votes
Field of type `datetime` accept date with format `Y-m-d\TH:i:s` So to set the default value, the date should be in this format, try with the following.

```
// Get the current date time in the format Y-m-d\TH:i:s.
    $current_date_time = DrupalDateTime::createFromTimestamp(time())
      ->format('Y-m-d\TH:i:s');
    $fields['start_date'] = BaseFieldDefinition::create('datetime')
      ->setLabel(t('Start date'))
      ->setDescription(t('Start date in GMT time.'))
      ->setDefaultValue($current_date_time)
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => -4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'datetime_default',
        'weight' => -3,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

```

# Answer
> 1 votes
Based on @berramou answer, I think this would be the right way (timezone and format wise):

```
->setDefaultValue(DrupalDateTime::createFromTimestamp(\Drupal::time()
      ->getRequestTime(), DateTimeItemInterface::STORAGE_TIMEZONE)
      ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT))

```

# Answer
> 1 votes
To add current datetime when create or update your values you should use:

```
BaseFieldDefinition::create('created')
BaseFieldDefinition::create('changed')

```

# Answer
> 1 votes
You can pass an array to the default value to use the current time the entity is being created.

```
$fields['start_date'] = BaseFieldDefinition::create('datetime')
      ->setLabel(t('Start date'))
      ->setDescription(t('Start date in GMT time.'))
      ->setDefaultValue([
        'default_date_type' => 'now',
        'default_date'      => 'now',
      ])
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => -4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'datetime_default',
        'weight' => -3,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

```

The key bit of information here being:

```
[
    'default_date_type' => 'now',
    'default_date'      => 'now',
]

```

# Answer
> 0 votes
In addition to the answer of CallMarl, mentioning that you should use another data type instead, the actual proper way to initialize *any* data of your custom entity, including not only timestamps but anything else, is to use the `preCreate()` function, for instance:

```
public static function preCreate(EntityStorageInterface $storage, array &$values) {
  parent::preCreate($storage, $values);

  $values['user_id'] = \Drupal::currentUser()->id();
  $values['created'] = time();
  $values['uuid'] = \Drupal::service('uuid')->generate();
}

```

---
Tags: 8, entities
---


# Question
Title: How to get the installed version of a module?
We have a "MyModule" module, which has a mymodule.install. Inside the file, there is mymodule\_update\_8001, 8002 ... etc.

How can I tell programmatically that on which version the module has at the moment? I know where to find them in database (key\_value table), but I would like to use a service instead, if that's possible.

**The closest I found:**

```
$update_hook_count = \Drupal::keyValue('system.schema')->get('mymodule');

```

This returns the update hook number.

# Answer
You can use the global function `drupal_get_installed_schema_version()`:

```
$update_hook_count = drupal_get_installed_schema_version('mymodule');

```
> 5 votes

# Answer
```
drush sql-query "SELECT schema_version FROM system WHERE name = 'mymodule';"

```
> 1 votes

# Answer
`drush php-eval "echo drupal_get_installed_schema_version('my_module');"`

From: https://www.drupal.org/docs/drupal-apis/update-api/updating-database-schema-andor-data-in-drupal-8#s-useful-drush-commands-while-developing-your-hook-update-n
> 1 votes

# Answer
I came here to find a version of module but this question is actually about getting module's database schema version. So here is a way to get only module version:

```
$version = \Drupal::service("extension.list.module")->getExtensionInfo('mymodule')['version'] ?? 0;

```

And if you need later compare version:

```
$affectedVersion = version_compare($version, '1.3.0', '>=');

```
> 1 votes

# Answer
The Ivan Chaer's answer is deprecated due to database changes. Update below:

```
drush sql-query "SELECT CONVERT(value USING utf8) FROM key_value WHERE name = 'mymodule'"

```
> 0 votes

# Answer
Drupal versions 9 and above would work with `\Drupal::service('update.update_hook_registry')->getInstalledVersion('MODULE_NAME');`.

See this for more information.
> 0 votes

---
Tags: 8, updating
---


# Question
Title: What is the approach for autocompletion of links in CKEditor5?
I have a new install of Drupal 10 with CKEditor 5 enabled, and I thought that CKEditor 5 now provided autocompletion of links, as used to be provided by the Linkit module. However, whenever I try to use the Link button, I get the 'Link URL' box shown below, but never any autocompletion suggestions no matter how many characters I type.

What is the correct method to get this working?

# Answer
At the time I write this, it is necessary to install and enable LinkIt on desired text formats in Drupal 10 to enable this feature. Yes, there is a Core issue to bring LinkIt features into Core but that is incomplete.
> 3 votes

---
Tags: wysiwyg, 10
---


# Question
Title: Debugging anonymous session regarding cookie specific page caching
Have been following this guide to make caching depend on the value of a specific cookie:

https://cornel.co/article/page-cache-cookiesor-anything-available-http-request-d9

However, it does not seem to work for anonymous users.

Debugging (xdebug) within both

**src/StackMiddleware/CookiesPageCache.php**

**src/CookiesPageCacheServiceProvider.php**

is possible when logged in as admin and running "cache rebuild" - but not when anonymous.

My question is - how should one go about debugging in the case of anonymous users?

# Answer
I know this is over a year later, but the reason you're seeing this for anonymous users is very likely due to having the core Internal Page Cache module installed, which caches and serves the complete response to all anonymous users, and part of that response are the cookies. I know this because I went down my own rabbit hole, pulling out my proverbial hair trying to figure out why this was happening, which I documented in a GitHub issue.
> 1 votes

---
Tags: caching
---


# Question
Title: How to set media library widget so that allows only certain dimension images for each field?
I'm trying to find a way to set some image dimension limit for the media library widget. That will allow me to restrict on which image sizes can be selected based on the fields they are using them.

I know that you can set a global min and max image size but the problem with this is that if you want to upload 300x300px image sizes for a certain field only and all the other images on the site are larger than 800px then you are forced to use 800px images for all fields as that would be the min size you could upload.

Is there a hook that I can implement in a module so that I can extend this functionality or a module that can give me this more granule control?

# Answer
> 0 votes
You could add validation against each field with something like this https://www.drupal.org/docs/drupal-apis/entity-api/entity-validation-api/defining-constraints-validations-on-entities-andor-fields

in your validate function you would need to load the image on the selected media entity and then check its dimensions. If they're not correct then set an error

# Answer
> 0 votes
Not an answer (yet) but there is a Drupal core issue filed on Drupal.org to fix this:

Image minimum resolutions should be configurable per field instance (for fields of Reference type Media with Media type Image) and these should be honored when uploading new images or selecting existing ones from the media library \[#3016649\]

Anything that helps you develop a workaround would likely help develop a patch, or developing a patch may be the only option, so worth engaging people following that thread in your work.

---
Tags: media, 9
---


# Question
Title: The hacked module report is not able to fetch the information of the enabled modules on the site
I am trying to use the Hacked module report for a site audit. However it has trouble fetching the data of the available modules on the site.

When tried using the drush commands of hacked module, I am getting the following errors.

```
Unable to decode output into JSON: Syntax error

  TypeError: Argument 3 passed to Drupal\hacked\HackedProjectWebDevDownloader
  ::gitClone() must be of the type string, null given, called in /var/www/htm
  l/www/modules/contrib/hacked/src/HackedProjectWebDevDownloader.php on line
  70 in Drupal\hacked\HackedProjectWebDevDownloader->gitClone() (line 100 of
  /var/www/html/www/modules/contrib/hacked/src/HackedProjectWebDevDownloader.
  php).

```

I am also getting the following errors related to fetching of modules.

```
>  [error]  Could not download project: drupal
>  [error]  Could not hash remote project: drupal
>  [error]  Could not download project: drupal
>  [error]  Could not hash remote project: drupal
>  [error]  Could not hash local project: drupal
>  [notice] Finished processing: drupal

```

The same site is also having trouble fetching the list of available udpates.

Reference in drupal.org https://www.drupal.org/project/hacked/issues/3385655

# Answer
> 0 votes
I fixed the problem by implementing the instructions in the following

Cannot update: "No available releases found"

---
Tags: 9
---


# Question
Title: Change Priority of ServiceProvider class
I have a module, `pod`. I am attempting to alter another service (`group.relation_handler.access_control.group_content_menu`), by implementing `Drupal\pod\PodServiceProvider::alter()`. This is working picked up, and I am able to swap out the backend class.

However, this alteration/swap is happening too late in the pipeline. For context, my alteration needs to happen before `Drupal\group\GroupServiceProvider::alter()` is called, as this class/callback alters the original class further, but my alteration comes later in the pipeline than this.

The problem is that `PodServiceProvider` is executed *after* `GroupServiceProvider`, and I need it to be executed before. I'm guessing this is because they are executed alphabetically.

So how can I change the priority of `PodServiceProvider` to be executed before `GroupServiceProvider`?

# Answer
It seems like you are in control of the fully-qualified class name. It doesn't matter how often it is altered, the latest change counts. Which alterations your custom class contains depends on the base class you extend from.

Concerning the question. You can set priorities when adding compiler passes

```
class MymoduleServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container) {
    $container->addCompilerPass(new MyCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 128);
  }

```

See https://symfony.com/doc/6.2/components/dependency\_injection/compilation.html#controlling-the-pass-ordering

When you are using the Drupal implementation of altering service definitions this is a predefined compiler pass ModifyServiceDefinitionsPass with default priority.

See also https://www.drupal.org/docs/drupal-apis/services-and-dependency-injection/altering-existing-services-providing-dynamic-services#s-how-to-create-a-custom-compiler-pass
> 3 votes

---
Tags: services
---


title: settings.php permission denied on Mac

text:
# Question
Title: settings.php permission denied on Mac
During a project installation always fails to install correctly.

Let me clarify this is how it should work: Drupal changes the chmod of `settings.php` to 777 and then applies changes for the drupal system, then executes all hook\_install\_tasks in all .profile files and then drupal changes the chmod of `settings.php` to read only (644 i think).

What happens on macbook is that after the drupal changes are applied to `settings.php` drupal changes the chmod to 644 before executing all the hook\_install\_tasks which is wrong because it can't edit the `settings.php` file anymore. But the hooks are required for the project to run properly so now need to be manually executed.

Here is the console

```
 [notice] Starting Drupal installation. This takes a while.
 [notice] Performed install task: install_select_language
 [notice] Performed install task: install_select_profile
 [notice] Performed install task: install_load_profile
 [notice] Performed install task: install_verify_requirements
 [notice] Performed install task: install_settings_form
 [notice] Performed install task: install_verify_database_ready
 [notice] Performed install task: install_base_system
 [notice] Performed install task: install_bootstrap_full
 [notice] Performed install task: install_profile_modules
 [notice] Performed install task: install_profile_themes
 [notice] Performed install task: install_install_profile
 [notice] Performed install task: install_configure_form
 [warning] file_put_contents(sites/default/settings.php): Failed to open stream: Operation not permitted SettingsEditor.php:174
In SettingsEditor.php line 175:

  Failed to modify 'sites/default/settings.php'. Verify the file permissions.

```

Does anyone have a solution for me?

# Answer
Worked on Vanish's answer and ended up using form\_alter hook on install\_settings\_form (SiteSettingsForm.php) to write the settings into the file.

`profiles/indicia/indicia_profile/indicia_profile.profile`

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function indicia_profile_form_install_settings_form_alter(array &$form, FormStateInterface $form_state): void {
  $form_state->loadInclude('indicia_profile', 'inc', 'includes/form_alter.install_settings');
  indicia_profile_install_settings_form_alter($form, $form_state);
}

```

`profiles/indicia/indicia_profile/includes/form_alter.install_settings.inc`

```
function indicia_profile_install_settings_form_alter(array &$form, FormStateInterface $form_state): void {
  array_unshift($form['actions']['save']['#submit'], 'indicia_profile_install_settings_form_submit');
}

function indicia_profile_install_settings_form_submit(array &$form, FormStateInterface $form_state): void {
  if ($form_state->getValue('isDevelopment')) {
    $settings['settings']['skip_permissions_hardening'] = (object) [
      'value' => TRUE,
      'required' => TRUE,
    ];

    SettingsEditor::rewrite(DRUPAL_ROOT . '/sites/default/settings.php', $settings);
  }
}

```
> 0 votes

# Answer
You can use

```
$settings['skip_permissions_hardening'] = TRUE;

```

in your settings.php and Drupal will never manage file permissions
> 1 votes

---
Tags: files, installation
---


# Question
Title: How to send file from React to Webform via Rest
I want to send an attached file in a React form to Drupal Webform via REST , but don't know how. I am sending the other fields successffully. They appear in the List with submissions. Here is my code:

```
//get token
fetch('https://my-site.com/session/token', {
    method: "GET"
})
.then(response => {
    if (200 === response.status) {
        // send submission
        fetch('https://my-site.com/webform_rest/submit?_format=json', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-Token': response
            },
            body: JSON.stringify({
                'webform_id': 'form_id',
                'entity_type': null,
                'entity_id': null,
                'in_draft': false,
                'uri': ['/webform/form_id/api'],
                'email': email,
                'phone': phone,
                'name': name,
            }),
        })
        .then(res => res.json())
        .then(
            (data) => {
                console.log('success', data)
                setMessage('The message was sent!')
            },
            (error) => {
                console.log('error', error)
                setMessage('Network error! The message was not sent!')
            }
        )
    }else{
        // error: didn't manage to get the token
        setMessage('Network error!')
    }
})

```

Please someone to explain the necessary steps or to provide an example.

Thank you!

# Answer
> 1 votes
This answer is about the REST/JSON:API in Drupal generally, and not specifically about Webform REST.

To attach a file via REST/JSON:API, you need two requests:

1. The request to add the file
2. The request to add your entity (the webform/node, etc. that you want to attach the file to)

For REST, see this change record for an example of how to upload a file.

For JSON:API, see this change record for an example.

Work is underway in Core to unify how REST and JSON:API handle file uploads; the issue is postponed but only because it has been broken up into sub-issues.

---
Tags: webforms
---


# Question
Title: Pass value into a view using block input
I have created a Drupal 9 site with articles that belongs to taxonomy terms. I want to give the ability to the administrator of the site to place a block with whatever taxonomy he wants.

How would I set up the block configuration with a drop-down of the taxonomy terms and pass the selected values to the Drupal views and filter based on the selected taxonomy terms?

In the block settings there is not any option to pass the filter to the block.

Any Idea on this using existing module or with custom code?

# Answer
Not answering directly, because I don't know if you could do this with a configurable Views block without custom code.

A different approach only using UI would be on entity level, creating a block type containing two fields, the taxonomy drop-down and an EVA field passing the other field's value via a token. The site admin has then to use the *Custom Block Library* to create a custom block for this block type.

Add the EVA field to the block type with this module: https://www.drupal.org/project/eva
> 2 votes

# Answer
We had a similar requirement on a previous project with Layout Builder: We used a `block_content` entity. We are using the Block field module to create a `field_view` containing a reference to the views block.

Every other field on the custom block content entity basically was a faked Views UI: Every filter that we wanted to expose to the editors, was created as field on the block\_content (mostly taxonomy term references), and then mapped to views exposed filters in a special field formatter widget for the block field.

It is a bit of hack, but our editors were quite happy with it. The field formatter below is tailored to our specfic needs, but might help to get some ideas.

```
<?php

namespace Drupal\wt_dgm\Plugin\Field\FieldFormatter;

use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\block_field\Plugin\Field\FieldFormatter\BlockFieldFormatter;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\views\Element\View;
use Drupal\views\Plugin\Block\ViewsBlock;

/**
 * Plugin implementation of the 'block_field' formatter.
 *
 * @FieldFormatter(
 *   id = "autolist_blockfield",
 *   label = @Translation("Block field with filters from Auto-List block"),
 *   field_types = {
 *     "block_field"
 *   }
 * )
 */
class AutoListBlockField extends BlockFieldFormatter {

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    /** @var $parentEntity \Drupal\block_content\Entity\BlockContent */
    $parentEntity = $items->getEntity();
    if ($parentEntity->getEntityTypeId() != 'block_content' || $items->getFieldDefinition()->getName() != 'field_view') {
      return parent::viewElements($items, $langcode);
    }

    $elements = [];
    foreach ($items as $delta => $item) {
      /** @var \Drupal\block_field\BlockFieldItemInterface $item */
      $block = $item->getBlock();

      if (!($block instanceof ViewsBlock)) {
        continue;
      }

      // copy & paste parent::viewElements()
      if ($block instanceof ContextAwarePluginInterface) {
        try {
          $contexts = \Drupal::service('context.repository')->getRuntimeContexts($block->getContextMapping());
          \Drupal::service('context.handler')->applyContextMapping($block, $contexts);
        }
        catch (ContextException $e) {
          continue;
        }
      }
      if (!$block || !$block->access(\Drupal::currentUser())) {
        continue;
      }

      // apply my custom filters and sort options to the views block
      $view = $block->getViewExecutable();
      $display = $view->current_display;

      $args = [$parentEntity->id()];
      $view->setArguments([$parentEntity->id()]);

      $filters = [];

      /* ### alter views filter ### */
      if ($parentEntity->hasField('field_contentypes')) {
        $filters['type'] = array_column($parentEntity->get('field_contentypes')->getValue(), 'value');
      }
      foreach ($parentEntity->getFields() as $fieldName => $field) {
        if ($field->getFieldDefinition()->getType() == 'entity_reference' && $field->getFieldDefinition()->getSetting('target_type') == 'taxonomy_term') {
          if (!$field->isEmpty()) {
            $filters[$fieldName . '_target_id'] = array_column($field->getValue(), 'target_id');
          }
        }
      }
      /* ### alter views sort ### */
      $sort = $parentEntity->get('field_sort')->value;
      $filters['sort_by'] = $sort;
      $view->setExposedInput($filters);

      $view->setItemsPerPage($parentEntity->get('field_quantity')->value);

      $view->display_handler->setOption('title', $parentEntity->get('field_title')->value);

      //@see \Drupal\views\Plugin\Block\ViewsBlock::build()
      $output = $view->buildRenderable($display, $args, FALSE);
      $output = View::preRenderViewElement($output);

      $elements[$delta] = $output;

      CacheableMetadata::createFromRenderArray($elements[$delta])
        ->addCacheableDependency($parentEntity)
        ->applyTo($elements[$delta]);
    }
    return $elements;
  }

}

```

PS: Ajax has to be enabled on the views block, otherwise setting `$filter` did not work correctly for us.
> 1 votes

# Answer
This module does exactly what you're looking for, though it has no stable release. It looks relatively easy to adapt to Drupal 9/10/11. The functionality is contained in a single block plugin class.

https://www.drupal.org/project/oveo
> 0 votes

---
Tags: views, blocks, 9
---


# Question
Title: Patch drupal.org project (core/module/theme) with issue fork
The new fork based merge request (MR) approach is pretty neat to get the patches created/reviewed/merged. However, if you are using the patch via cweagans/composer-patches, we have a few options.

**Option 1**: we can use the MR to add the patch like this:

```
"drupal/message": {
  "3186091": "https://git.drupalcode.org/project/message/-/merge_requests/1.patch"
}

```

but it means any new change pushed to the fork/branch, would get automatically added. As the patch file gets pulled on `composer install`.

**Option 2**: We could use the fork's branch and commit hash to keep the patch static, but once the MR merged, the fork might get deleted and breaks the build.

**Option 3**: Obviously we can generate the patch from the MR and upload to the issue comment, but it seems a duplicate effort and hard to keep up with an active core issue (right now, we just need to update the patch file in `composer.json` or `composer.patches.json`)

Is there a way to have the current patch file behavior in the new fork based issue queue?

**UPDATE**: Both option 1 and (probably) option 3 are documented on drupal.org

# Answer
> 4 votes
It has been discussed already in the Opt-in to the Drupal.org Issue Forks and Merge Requests beta thread, see 3152637#comment-13820062. As of now there is no straight way to integrate commits in composer patch work flow. You need to download the patch file manually by appending `.patch` to the merge request URL and copy it locally into your project to get it applied in the build process.

```
"patches": {
    "drupal/foobar": {
        "3200808 - Lorem ipsum": "./patches/3200808-3.patch"
    }
}

```

You can get additional information on how to generate patch from the commit Id from the guide: Patch files for use with Composer.

# Answer
> 0 votes
See Drupal documentation to force module installion due to composer restriction. There two options:

* Using Issue Forks directly
* OR Use the composer-drupal-lenient Package

@see https://www.drupal.org/docs/develop/git/using-gitlab-to-contribute-to-drupal/core-version-compatibility-fixes-for-modules-with-unmerged-changes

---
Tags: 8, composer, community-official-site
---


# Question
Title: Can't access data posted from Dialog.ajax to dialog box
I am opening a simple dialog box from Ajax, using the following code-

```
var exportActionDialog = Dialog.ajax({
  dialog: dialogSettings,
  dialogType: 'modal',
  type: 'POST',
  url: '/web/admin/crm/export-dialog',
  data: { whatever: 'itworking' },
  progress: { type: 'throbber'}
});
exportActionDialog.execute();

```

The dialog actually opens successfully and displays the form associated with the url.

But I can't get the value of the `whatever` post variable.

When I do this

```
Public function buildForm(array $form, FormstateInterface $form_state) {
$whatever = $this->getRequest()->request->get('whatever');

dpm($whatever); // returns null

```

The `$whatever` variable returns as null.

Now the actual reason I want to use a post is because I want to pass an array which can contain up to 1000 elements or more. Doing this using Get makes the url unreasonably long.

Just hoping someone could point me in the right direction?

Pls any clues guys?

Thanks...

# Answer
You have to replace the `data` key with `submit`. Drupal.ajax() transfers the submit key to the data key of $.ajax() but ignores a data key already set:

```
var exportActionDialog = Drupal.ajax({
  dialog: dialogSettings,
  dialogType: 'modal',
  httpMethod: 'POST',
  url: '/web/admin/crm/export-dialog',
  submit: { whatever: 'itworking' },
  progress: { type: 'throbber'}
});
exportActionDialog.execute();

```

Similar the legacy jQuery `type` key, now `method`, where Drupal is using `httpMethod`. In this case no problem, POST is default.
> 1 votes

---
Tags: ajax, modal-dialogs, 10
---


# Question
Title: How to have views exposed filter value show as different value in the url?
I have a search page with a Views exposed filter for the name of a taxonomy term. I have added an #autocomplete\_route\_name to the form element to make this an autocomplete selector for my term names. The autocomplete controller returns this:

```
foreach ($terms as $term) {
  if($term->hasTranslation($langcode)){
    $translated_term = \Drupal::service('entity.repository')->getTranslationFromContext($term, $langcode);
    $results[] = [
      'value' => $translated_term->getName(),
      'label' => $translated_term->getName(),
    ];
  }
}
return new JsonResponse($results);

```

this works fine, except the url ends up with the term name in the GET (url). Is there any way to have term id here?

I have seen many answers to this question to use hook\_views\_pre\_view. These are fine to modify the value used in the views query, but has no impact on the url variable.

# Answer
> 0 votes
**#1:** **To alter Query parameter value in the url of View page**: redirect event subscriber approach used

```
<?php

    namespace Drupal\custom_module;

    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Drupal\Core\Routing\RouteMatchInterface;
    use Symfony\Component\HttpFoundation\RequestStack;
    use Drupal\Core\Url;

    /**
     * Execute to changes query parameter value in the url of view page.
     */
    class RedirectSubscriber implements EventSubscriberInterface {

      /**
       * Current Route.
       *
       * @var \Drupal\Core\Routing\RouteMatchInterface
       */
      protected $route;

      /**
       * The request stack.
       *
       * @var \Symfony\Component\HttpFoundation\RequestStack
       */
      protected $requestStack;

      /**
       * Constructs a RedirectSubscriber object.
       *
       * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
       *   The route match.
       * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
       *   The request stack.
       */
      public function __construct(RouteMatchInterface $current_route_match, RequestStack $requestStack) {
        $this->route = $current_route_match;
        $this->requestStack = $requestStack;
      }

      /**
       * {@inheritdoc}
       */
      public function redirect(GetResponseEvent $event) {
        $route_name = $this->route->getRouteName();
        // Get category name
        $term_name = $this->requestStack->getCurrentRequest()->query->get('category_name');
        // Get term id from category name
        $ary = preg_split('/[()]/', $term_name);
        $tid = $ary[1];
        if ($route_name == 'view.speaker.page_2' && isset($term_name)) {
          if (isset($tid)) {
            // Get all paramters page
            $params = $this->requestStack->getCurrentRequest()->query->All();
            // Alter the category_name query parameter value
            if ($params['category_name']) {
              $params['category_name'] = $tid;
            }
            // Set redirect url & pass all parameters to it
            $redirect_url = Url::fromRoute('view.view_bulk_test.page_2')->setOptions(['query' => $params])->toString();
            if ($redirect_url) {
              // Pass Redirect URL.
              $event->setResponse(new RedirectResponse($redirect_url, 301));
            }
          }
        }
      }

      /**
       * {@inheritdoc}
       */
      public static function getSubscribedEvents() {
        $events[KernelEvents::REQUEST][] = ['Redirect', 20];
        return $events;
      }

}

```

**File path:** : module\_name/src/RedirectSubscriber.php

**Define: module\_name.services.yml** (inside custom module)

```
 services:
  module_name.redirect_subscriber:
    class: Drupal\module_name\RedirectSubscriber
    arguments: ['@current_route_match', '@request_stack']
    tags:
      - { name: 'event_subscriber' }

```

**In this scenario query parameter whose value altered is autocomplete taxonomy referenced type field & if tid passed then error 'll display:** There are no taxonomy terms matching "2".

**To fix it:** Used hook hook\_views\_pre\_view():

```
use Drupal\taxonomy\Entity\Term;

function module_name_views_pre_view(ViewExecutable $view, string $display_id, array $args) {
  if (($view->id() == 'speaker')) {
    $exposedInput = $view->getExposedInput();
    // Get term id from category name
    $tid = $exposedInput['category_name'];
    if(isset($tid)){
      // Load term object from term id
      $term = Term::load($tid);
      if(isset($term)){
        // Set value of filter in required format
        $val = $term->label().' '.'('.$tid.')';
        $exposedInput['category_name'] = $val;
      }
      // Set the exposed filter value in the view
      $view->setExposedInput($exposedInput);
    }
  }
}

```

**#2: Query paramter name in the url of view page can be altered by the view UI.**

Steps:

1. Go to the required view and edit the view
2. Click the filter & filter settings 'll open in the modal
3. You will find 'Filter identifier' field , here you can specify the required parameter name.

---
Tags: views, search, 9
---


# Question
Title: Check for active/qualified session in EventSubscriber, destroy session and cookies if not
I have an application that has a custom SSO with a third party service. We are porting Drupal 7 code to Drupal 10 to continue the functionality. Previously we had a hook\_init function that did the following:

* Check if the user is authenticated with specific role
* Check that the user has two valid cookies (used in API calls to the third party)
* If the user is authenticated with specific role but accesses `/user` paths, redirect them
* If the user is authenticated but no cookies, redirect to custom login
* If the user is anonymous but has cookies, unset the cookies to force a login

I am running into two issues, either I get an endless redirect loop or the cookies are not unset. On top of that it seems like the responses get cached - as long as the user is authenticated as this specific role I want to keep evaluating this in every request.

Here is the event subscriber:

```
  /**
   * Kernel request event handler.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   Response event.
   */
  public function checkMemberPresence(RequestEvent $event) {
    if (!$event->isMainRequest()) {
      return;
    }

    $uri = $this->requestStack->getCurrentRequest()->getPathInfo();

    if ($this->isMember() && !$this->requestStack->getCurrentRequest()->cookies->has('session')) {
      user_logout();
      $response = new RedirectResponse('/member/login', 302);
      $response->send();
      $event->stopPropagation();
    }

    if ($this->isMember() && preg_match('/^\/(user$|user\/).+/i', $uri)) {
      $response = new RedirectResponse('/member', 302);
      $response->send();
      $event->stopPropagation();
    }

    if ($this->currentUser->isAnonymous() && ($this->requestStack->getCurrentRequest()->cookies->has('session') || $this->requestStack->getCurrentRequest()->cookies->has('session_expires'))) {
      $options = $this->sessionConfiguration->getOptions($event->getRequest());
      $cookie_domain = $options['cookie_domain'];

      $response = new RedirectResponse('/', 302);
      $response->headers->clearCookie('session', '/', $cookie_domain);
      $response->headers->clearCookie('session_expires', '/', $cookie_domain);
      $response->send();
      $event->stopPropagation();
    }
  }

  /**
   * Helper method to check if the current user is a member.
   *
   * @return bool
   *   If the current user is a member.
   */
  protected function isMember() {
    return $this->currentUser->hasRole('ticketure_member');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::REQUEST => ['checkMemberPresence'],
    ];
  }

```

The first two cases appear to work AFAICT (haven't written the tests yet) but the third does not.

How can I fix this to work and not cache the response? Furthermore, is this a proper porting of hook\_init and should it be done this way in Drupal 10?

Update:

The cookie removal logic now appears to work (domain must be sent) - still unclear on if this is a good implementation.

# Answer
> 1 votes
You could start with setting a higher priority because you only depend on user authentication (priority 300) and want to run before other event subscribers like routing and dynamic caching:

```
KernelEvents::REQUEST => ['checkMemberPresence', 290],

```

Then don't send, return the response with the event:

```
$event->setResponse($response);

```

This stops propagation automatically.

However, this doesn't override the Internal Page Cache for anonymous requests with no Drupal session cookie but third-party cookies. If you want to handle those requests within the Drupal kernel you need to uninstall this module.

---
Tags: authentication-authorization, 10, event-subscribers
---


# Question
Title: How to override thumbnail generation of file type media?
In admin/content/media I need to show file type related icons instead of generic file icon.

From this:

To this:

I tried to edit the related thumbnail field in "media" view but no option is present.

Thanks

# Answer
In the media source plugin for this media type you can find the code generating the thumbnail. See the source code of the "File" media type provider.

To summarize the code, you have to put your thumbnails files for each supported MIME type in the folder configured in the "icon\_base\_uri" configuration (which is stored in the "media.settings.yml" configuration file).

For example, using the default "public://media-icons/generic" folder and inserting a PDF media, you have to store your thumbnail image under the name "public://media-icons/generic/application--pdf.png" for it to be detected and used.
> 6 votes

# Answer
Please. Where can I find what to change in public://media-icons/generic/application--XXX.png I need to change icon for TXT and ODT. application--odt.png, application--txt.png uses generic.png Can you write where to find mimetype to change for another mimetype. Thanks.
> 0 votes

---
Tags: media
---


# Question
Title: Passing variable from parent paragraph to children without using getParentEntity
I have a paragraph called Boxes which is a parent paragraph referencing to many paragraphs of type Box. I have written the preprocess function of paragraph Boxes which contains some logic that can't be done elsewhere. The result of that code is stocked in a variable called custom\_color\_weight.

I wanna access this variable in the box paragraph template but I can't move the code that yielded that variable's value outside the preprocess boxes function.

I was searching for a way to pass the variable from preprocess boxes to the preprocess box and hence to the template of the box paragraph Is there any way to do it?

Ps : I can't use getParentEntity in the preprocess Box function to get each time the parent Boxes entity and calculate the value of custom\_color right there because that way I will be loading the parent paragarph entity multiple times as I have multiple nested paragraphs of type Box inside the paragraph Boxes.

# Answer
> 1 votes
getParentEntity() is not the problem, it always returns a reference to the same instance. There you could use a bundle class to calculate and store the value. See this change record:

https://www.drupal.org/node/3191609

Then you can replace both preprocess hooks by calling the bundle class method directly from the child Twig template

```
{{ paragraph.getparententity.getcustomcolor }}

```

where getCustomColor() is a method of the parent bundle class.

---
Tags: 9, paragraphs
---