# Question
Title: Always keep admin UI in the same language when translating content
I have set up a page with two languages (English, German). I have two users, one should get the German backend and the other user only understands English, he should get the English backend. The frontend should be able to switch between the languages and the backend should always remain the same in the language. I have also set up a language switch for the website and I use the AdminToolbar. I also tried the following, but unfortunately it didn't help:

Always keep admin UI in English when translating content.

At the moment I'm rather confused with the languages. The backend always jumps with the language and the menus can no longer be easily adapted with their translation. I now strongly suspect that this is due to the "recognition and selection" function and the order of the recognition methods. But so far I haven't found an optimal order for the recognition methods myself. So first it should show the language for the backend correctly and then control the frontend via the paths "de" and "en".

But I would be very grateful if you could help me. Oh, I use the latest Drupal 9 and use the Drupal Core standard modules for the translations. So I would be grateful for any tips! I've already done some research, but haven't found the right solution yet.

Thanks and greetings

Bavra

# Answer
> 1 votes
Enable **Account administration pages** in language detection (don't change the priorities, the setup out-of-the-box is optimal). This adds a second language selector for admin pages to the user profile. Then every user with admin privileges can select their preferred language for the admin UI:

To translate then content in different languages while keeping the configured admin language enable *Customize Content language detection to differ from Interface text language detection settings* and enable the **URL** detection method in this section.

Whether this works with specific modules is a different problem and should be solved in the modules issue queue.

---
Tags: i18n-l10n, 9
---


title: Change weight/order of exposed filters

text:
# Question
Title: Change weight/order of exposed filters
I have a view with two exposed filters: one generated using the Views UI, and another filter from custom code.

Can I change the order in which the exposed filters are rendered on the form?

I could not find any property I could use to set the order.

# Answer
There are some possibilities to accomplish this.

1. Rearrange the filters via the Views UI
Will not work if you added a filter via custom code.
2. Create a `hook_form_views_exposed_form_alter` hook and set the `#weight` property to the filters. Maybe you need to do this for every element because the #weight property is not automatically added to the elements. Instead they are added in the selected order.
3. Add a custom `views-exposed-form--VIEW_ID.html.twig` template and render the elements in the desired order.
https://makedrupaleasy.com/articles/drupal-8-9-make-beautiful-views-exposed-filters-form-custom-twig-template-and-bootstrap
> 1 votes

---
Tags: views, 9
---


# Question
Title: Create custom admin theme removes theme-primary-local-tasks from admin view
I am creating an admin theme to manage certain content type. I was able to use Claro as base theme so everything is there. However, The primary-local-tasks items ( edit, view, delete..) are missing. Instead is rendering my Navbar into the admin view.. I am not sure how or what is going on. This is my first time creating an admin theme any guidance would b e appreciate it.

this is before

This is after:

# Answer
> 1 votes
When you install a theme Drupal tries to build a block layout automatically, but the result only works for front-end themes. For admin themes you need to provide a default block layout. See the default config of the base theme:

*core/themes/claro/config/optional/*

```
block.block.claro_breadcrumbs.yml
block.block.claro_content.yml
block.block.claro_help.yml
block.block.claro_local_actions.yml
block.block.claro_messages.yml
block.block.claro_page_title.yml
block.block.claro_primary_local_tasks.yml
block.block.claro_secondary_local_tasks.yml

```

You can copy these files, adjust the file names and replace the theme name within the file. If you copy the files from an exported config then remove UUID and config hash.

If you want to install this only a few times you can also visit the block layout and move/create blocks until it looks the same as the layout of the installed base theme. After that you can always copy the result of the exported config to the themes folder to make further installations easier.

---
Tags: 9
---


# Question
Title: Installing specific git releases via composer
I'm trying to install a specific release version of a library (pdf.js) into my D9 site, to which I've followed this example, and I have this in my composer file

```
"repositories": [
    {
        "type": "package",
        "package": {
            "name": "mozilla/pdf.js",
            "version": "v2.14.305",
            "type": "drupal-library",
            "extra": {
                "installer-name": "pdf.js"
            },
            "dist": {
                "type": "zip",
                "url": "https://github.com/mozilla/pdf.js/releases/download/v2.14.305/pdfjs-2.14.305-dist.zip"
            }
        }
    }
...
...
"require": {
    "mozilla/pdf.js": "v2.14.305",
    ...

```

Except every time I run `composer install` it just gets the current master branch (eg, everything from here), how do I make it get that specific zip I've specified?

# Answer
> 0 votes
Turns out... this is fine, I'd been directly updating the `composer.json` file after my initial attempt to download it failed to get the correct version, and I was just being stupid by only running `composer install` and kept removing the folder manually each time it didn't download what I wanted.

I removed it from composer properly using `composer remove "mozilla/pdf.js"`, and re-ran the require line again, and this time it has worked.

I'll leave it up in case anyone wants to see how to download a specific version

---
Tags: 9, composer
---


# Question
Title: Trim or strip spaces around the email or username on the login page
I know that my Drupal installation (9.3.15) doesn't trim spaces at the login page (form id: user-login-form). I have some code in the `HOOK_form_user_login_form_alter` but in that place in `$form_state` I don't have any `->getValue('%field%')` , it returns NULL. Also I can not modify '$form\['name'\]\['#value'\]' because it is empty in that context.

How do I trim spaces on the user's input? I can do `$form_state->getUserInput();` and I can see what the user has entered but I don't know how to modify it. Because $form\_alter is an object.

# Answer
> 1 votes
In `your_module.module`

1. You create form alter if there is no any (e.g. `HOOK_form_FORM_ID_alter()`)
2. you add a validation callback to a field of the whole form (e.g. `array_unshift($form['#validate'], 'trim_login_credentials');`)
3. create `function trim_login_credentials(&$form, $form_state) {}`
4. add your validation or string operations into that the newly created function;

I do 'array\_unshift()\` because I want my validation *before* Drupal's.

Another way

A question at stackoverflow

---
Tags: forms, 9, authentication-authorization
---


title: How to get the revision of a paragraph

text:
# Question
Title: How to get the revision of a paragraph
I have a code which is running in `hook_node_update`. This code grab the revision of the saved node and compare the values of the fields between current node and its revision to generate some kind of historic log (what is deleted/updated/added).

This is working very well except for the paragraph field... When my code is trying to get the revision of a paragraph (recursively), I got each time the same paragraph instead of the old revision (thus no differences to log)

Here is my code to get the revision of a the saved node (working well). This code is also used for the paragraphs (not working)

`$updated_entity` : the node/paragraph currently in the process to be saved

`$old_entity` : the revision to compare with

```
  $old_entity = $updated_entity->original;
  if (!$old_entity) {
    $storage = $this->getStorage($updated_entity);
    // no need to test if revisionable as we use only Node and Paragraphs
    if ($revision_id = $updated_entity->getLoadedRevisionId()) {
      $old_entity = $storage->loadRevision($revision_id);
     }
    else {
      //... handling new entity
      ]);
    }
  }

```

This code, when applied to the paragraphs, is producing an `$old_entity == $updated_entity`

The paragraphs are extracted from the currently saved node as follow:

```
$paragraphs = $updated_entity->get($paragraph_field)->referencedEntities();

```

after that, they become the `$updated_entity` variable in the upper function which is trying to get the revision...

# Answer
The unnamed *upper* function works only for the one specific node you get via the hook as parameter. Load the old referenced paragraphs via the original entity:

```
$old_paragraphs = $node->original->get($paragraph_field)->referencedEntities();

```

For nested paragraphs you can then apply recursive loading, but each branch (old/new) separately and not with the *upper* function, use -\>referencedEntities() for mulitple and -\>entity for single field items, these functions load revisions.

In a multilingual site you have to get the translation of the paragraph using the node language:

```
$node_language = $node->language()->getId();
$value = $paragraph->getTranslation($node_language)->field_foo->value;

```
> 1 votes

# Answer
One way is to use hook\_ENTITY\_TYPE\_update on the paragraph entity:

```
<?php
   // file mymodule.module

   /**
    * hook_ENTITY_TYPE_update
    *
    * @param \Drupal\paragraphs\Entity\Paragraph $paragraph
    *
    * @return void
    */
    function mymodule_paragraph_update(\Drupal\paragraphs\Entity\Paragraph $paragraph): void {

      // We are only interested by bundle_name paragraph
      if($paragraph->bundle() !== 'bundle_name'){
        return;
      }

      $field_value = $paragraph->get('field_name')->getValue();
      $original_field_value = $paragraph->original->get('field_name')->getValue();

      // You can get the parent node like that
      $node = $paragraph->getParentEntity();

    }

```
> 0 votes

---
Tags: entities
---


# Question
Title: how to change the size of an exposed filter autocomplete form?
the source shows:

```
<input id="edit-field-location-taxonomize-terms-tid" class="form-text form-autocomplete ctools-auto-submit-processed" type="text" maxlength="128" size="60" value="Germany" name="field_location_taxonomize_terms_tid" autocomplete="OFF" aria-autocomplete="list">

```

tried `hook_form_alter` but didn't find `size` or `maxlength` using `drupal_set_message('<pre>' . print_r($form, TRUE) . '</pre>');`

also

```
function modulename_element_info() {
  $types['textfield'] = array(
    '#input' => TRUE,
    '#size' => 20,
    '#maxlength' => 128,
    '#autocomplete_path' => FALSE,
    '#process' => array('ajax_process_form'),
    '#theme' => 'textfield',
    '#theme_wrappers' => array('form_element'),
  );
}

```

didn't work and don't know if/how i can change the size with css.

any help is appreciated. thanks a lot!

# Answer
> 0 votes
There is currently an issue in the Claro theme to reduce the exposed filter size but until then you can use this. Replace MYMODULE, MYVIEWID, and MYBLOCK. Haven't test this but it should work. I know its a lot of code for a small change. You could also do this with CSS. Oh you also have the change `uid` in the form variable.

```
/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function MYMODULE_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
   if ($form_state->getStorage()) {
     $storage = $form_state->getStorage();
     if ($storage['view'] {
       if ($storage['view']->id() == 'MYVIEWID' && $storage['display']['id'] == 'MYBLOCK') {
         // Reduce the size of the input.
         $form['uid']['#size'] = 20;
       }
     }
   }
 }

```

With CSS. Change `#EXPOSEDFILTERID`. I chose `data-drupal-selector` because after submitting the form, the ID changes. You should also change `uid`.

```
#EXPOSEDFILTERID input[data-drupal-selector="edit-uid"]{
  width:150px;
}

```

---
Tags: views, ajax
---


# Question
Title: Difference between drupal-composer vs drupal-recommended
drupal-composer/drupal-project drupal/recommended-project

Which one is the best option to choose & why? on Drupal 9

1. composer create-project drupal/recommended-project:

/vendor: 4485 files, ~21 Mo

2. composer create-project drupal-composer/drupal-project:

/vendor: 12624 files, ~62 Mo

# Answer
> 7 votes
The important difference is that you should use *drupal/recommended-project* as it is recommended and officially supported. *drupal-composer/drupal-project* is outdated for Drupal 8+ and should only be used for Drupal 7.

From the Using Composer to Install Drupal and Manage Dependencies documentation on d.o:

> As of the release of Drupal 8.8.0 - the recommend composer template changed from drupal-composer/drupal-project to the officially supported: drupal/recommended-project
>
> For Drupal 9, use the composer template at drupal/recommended-project. This template ensures Drupal Core dependencies are the exact same version as the official Drupal release.
>
> For Drupal 7, use drupal-composer/drupal-project.

While alluded to in the quote from the d.o documentation, I think it's worth calling out: a key difference between the two templates is that *drupal/recommended-project* includes a `composer.lock` file which "ensures Drupal Core dependencies are the exact same version as the official Drupal release."

---
Tags: 9
---


title: How to show admin bar in custom theme?

text:
# Question
Title: How to show admin bar in custom theme?
I am trying to create custom themes with bootstrap for Drupal 9. If I use the bootstrap5 theme as the base theme, I can access to the admin bar when viewing content. If I use any core themes as base theme, admin bar gone. I have looked up bootstrap5 template codes and functions, googled but couldn't find where to look apparently.

When using stable9 or classy as base theme and write all templates from scratch, how can I show the admin menu on non-admin pages?

# Answer
> 0 votes
Looking at `toolbar.module`, the toolbar is added to the page via `hook_page_top()` and the page\_top area is output via `html.html.twig`.

The following snippet is taken from `html.html.twig` in core's stable9 theme:

```
...
<body{{ attributes }}>
  {#
    Keyboard navigation/accessibility link to main content section in
    page.html.twig.
  #}
  <a href="#main-content" class="visually-hidden focusable">
    {{ 'Skip to main content'|t }}
  </a>
  {# PAGE TOP IS OUTPUT HERE #}
  {{ page_top }}
  {{ page }}
  {{ page_bottom }}
  <js-bottom-placeholder token="{{ placeholder_token|raw }}">
</body>
...

```

Assuming you have the toolbar module enabled AND your theme (or base theme) is outputting `page_top` in its `html.html.twig`, then you should:

1. Check the HTML source content for the toolbar div: per the twig above, it'll likely be directly below the `#main-content` link.
2. Check for any errors in console: the contents of the toolbar are loaded via JS so it may be that toolbar is on the page, but a JS error is preventing it from rendering its contents.
3. Check that the toolbar isn't simply being rendered underneath other content: i.e. a z-index issue.
4. Check for any theme code that may be tampering with the contents of page\_top: Make sure anything implementing `hook_page_top()` isn't overriding the contents of `$page_top`, specifically `$page_top['toolbar']`, make sure it's not doing something like `$page_top = [etc...]`

---
Tags: theming, 9
---


# Question
Title: Behaviors are only executed on some pages, while on others jQuery is not defined
In Drupal 9, I put the following JavaScript code for an image slider and a mobile navigation into a script.js file.

```
(function($, Drupal, drupalSettings) {

  Drupal.behaviors.swiper = {
    attach: function(context, settings) {
      var mainSwiper;
      mainSwiper = new Swiper(".swiper-container", {
        init: false,
        rewind: settings.slide_is_rewind == "0" ? false : true,
      });
      mainSwiper.init();
      // some more code for the slider
    },
  };

  Drupal.behaviors.mobilenav = {
    attach: function(context, settings) {

      $(".mobile-nav-icon").on("click", function(e) {
        console.log('mobile icon clicked');
        // some more code
      });
    },
  };

})(jQuery, Drupal, drupalSettings);

```

While the slider works great, the part of the mobile navigation isn't working as expected. It works only on pages with a slider. In the browser console, this error is thrown out.

> Uncaught ReferenceError: jQuery is not defined

What's wrong with my code?

In case the issue has to do with my libraries.yml, this is its content.

```
global-styling:
    version: 1.x
    css:
      theme:
        css/variables.css: {}
        css/layout.css: {}
    js:
      js/script.js: {}
  global-scripts:
    version: 1.x
    js:
      js/navmenu.js: {}

  custom_swiper:
    version: VERSION
    css:
      theme:
        css/swiper-bundle.min.css: { weight: -100 }
    js:
      js/swiper-bundle.min.js: {}
    dependencies:
      - core/jquery
      - core/drupal
      - core/drupalSettings
      - core/jquery.once

```

# Answer
> 3 votes
Your inconsistent results are because `core/jquery` is being included on some pages by other libraries, and in these cases everything works fine, but you're seeing errors when there is no other library requiring `core/jquery`.

You have three libraries defined in your *libraries.yml*, however only one of them, `custom_swiper`, has dependencies defined. Dependencies need to be defined for each library individually. You need to add `core/jquery` as a dependency of the library that `script.js` is part of; per your code, this is the `global-styling` library.

```
global-styling:
  version: 1.x
  css:
    theme:
      css/variables.css: {}
      css/layout.css: {}
  js:
    js/script.js: {}
  # ADD DEPENDENCIES
  dependencies:
    - core/jquery
    - etc...

```

Additionally, a library can require other custom libraries defined in the same module or theme - libraries do not automagically include other libraries defined in the same *libraries.yml* file. I.e. if your `global-styling` library depends on your other library, `custom_swiper`, it will need to be added as a dependency as well. For example:

```
global-styling:
  version: 1.x
  css:
    theme:
      css/variables.css: {}
      css/layout.css: {}
  js:
    js/script.js: {}
  # ADD DEPENDENCIES
  dependencies:
    - core/jquery
    - my_module/custom_swiper
    - etc...

```

For more information, see the Adding assets (CSS, JS) to a Drupal theme via \*.libraries.yml docs on d.o.

---
Tags: javascript, 9
---


title: Adding fields to custom content entity

text:
# Question
Title: Adding fields to custom content entity
I'm creating a new content entity called *Points*. My code already creates the table and its fields, but i cant see the fields in the entity form. I thought that fields in *baseFieldDefinitions*() should to be shown in the form . What i'm doing wrong? it only shows a pair of these fields:

```
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

    $fields = parent::baseFieldDefinitions($entity_type);

    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
    ->setLabel(t('User ID'))
    ->setDescription(t('The user ID of the operation author.'))
    ->setSettings(array(
      'target_type' => 'user',
      'default_value' => 0,
    ))
    ->setDisplayConfigurable('form', TRUE)
    ->setDisplayConfigurable('view', TRUE);

    $fields['target_type'] = BaseFieldDefinition::create('text')
    ->setLabel(t('Target Type'))
    ->setDescription(t('Tipo de entidad sobre la que se realiza la operación'))
    ->setDefaultValue(0)
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);

    $fields['target_entity'] = BaseFieldDefinition::create('integer')
    ->setLabel(t('Target Entity'))
    ->setDescription(t('ID de la entidad sobre la que se realiza la operación'))
    ->setDefaultValue(0)
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);

    $fields['operacion'] = BaseFieldDefinition::create('list_string')
    ->setLabel(t('Operación Realizada'))
    ->setDescription(t('Operación realizada (create, update, delete)'))
    ->setSettings([
      'allowed_values' => [
        'create' => 'create',
        'update' => 'update',
        'delete' => 'delete',
      ],
    ])
    ->setDisplayOptions('view', [
      'label' => 'visible',
      'type' => 'list_default',
      'weight' => 6,
    ])
    ->setDisplayOptions('form', [
      'type' => 'options_select',
      'weight' => 6,
    ])
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);

    $fields['timestamp'] = BaseFieldDefinition::create('changed')
    ->setLabel(t('Changed'))
    ->setTranslatable(TRUE)
    ->setDescription(t('The time that the points was last edited.'))
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);

    $fields['points'] = BaseFieldDefinition::create('integer')
    ->setLabel(t('Points'))
    ->setDescription(t('Points to grant'))
    ->setDefaultValue(0)
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);

    $fields['langcode'] = BaseFieldDefinition::create('language')
    ->setLabel(t('Language code'))
    ->setDescription(t('The points language code.'))
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);

    return $fields;
  }

```

# Answer
> 0 votes
In order to add new fields to already existing entity you need to write update hook.

Refer https://git.drupalcode.org/sandbox/Bhanu951-3103712/-/blob/8.x-dev/omdb\_api/omdb\_api.install#L178 for sample code

Relevant Change Record #2554097

---
Tags: entities
---


# Question
Title: How to add class to paragraph fields through preprocess hook?
I created a paragraph named flight-search-info-block with two fields: `field_svg_icon` and `field_teaser_text`. Then I created a custom block, where that paragraph was added as an entity reference field. Now I want the structure as

```
<div class="item-wrap">
  <div class="item-img">...field_svg_img....</div>
  <div class="item-text">...field_teaser_text....</div>
<div>

```

I want to do this using `hook_preprocess_paragraph`. With this hook I was able to add the class to the paragraph wrapper div (yellow marked in the attached image). I also tried `hook_preprocess_field`, but again the class was added to the paragraph.

So how can I add the classes to the red marked elements?

# Answer
> 1 votes
Come from the other way. Come from the field. Check the parent entity (paragraph) type and then add the classes:

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_field__MYFIELD(&$variables) {
  /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
  $paragraph = $variables['element']['#object'];
  if ($paragraph->bundle() === 'foobar') {
    foreach ($variables['items'] as $delta => $item) {
      $variables['items'][$delta]['attributes']->addClass(['foo', 'bar', 'item-' . $delta]);
    }
  }
}

```

---
Tags: hooks, 9, paragraphs
---


# Question
Title: How to display in a block the media used in a node?
On my Drupal 9 installation, I created nodes with Media images integrated with CKEditor. This is not an image field in the node type, but an image embedded in node content with Media and CKEditor.

How do I create a block on the node page which displays all the images integrated into the node?

I can display the images of the node that would be used in an image field, but I have not been able to display the ones that are integrated directly into the content with Media and CKEditor.

# Answer
Media images that are embedded with CKEditor into a text field are referenced using `<drupal-media>` tags. These tags are parsed by an input filter when the node is rendered. So, as far as I know, there is no way (in core or in contrib) to generate a list of the embedded media and then process that with the Views module.

With an Image field, it works because there is an entity reference, and Views can handle those.

So, if you need a list of the images used in a node, you could either write code to extend Views to process the `<drupal-media>` tags (probably quite a pain), or restructure your content/don't use the embed feature and use entity references instead.
> 1 votes

---
Tags: views, media, 9
---


# Question
Title: How to disable core JS aggregation and AdvAgg just for admin paths
I help look after a site which uses `$settings['file_public_base_url']` to serve files from a different subdomain on the frontend, but on the backend (admin paths like `node/add` and `node/edit`) this causes our JS to be loaded with absolute rather than relative URLs which seems to cause an issue with JS loaded via AJAX not executing correctly. There are no JS errors in my devtools console, but I suspect the cause is that the JS is being loaded from differing subdomains, as turning AdvAgg and core's JS aggregation off makes the JS files load via relative paths and function as intended.

Without any errors showing in my console or server logs I'm not sure I'm going to be able to get to the bottom of the AJAX issue, so for now a compromise seems to be to turn off aggregation for admin and content editing routes.

What would be the best way to do that? I know I can set `$config['system.performance']['js']['preprocess'] = FALSE;` and presumably a similar config key for AdvAgg's own setting (we have AdvAgg set to optimise/compress JS, so even with `system.performance.js.preprocess` turned off AdvAgg will still manage the files and use absolute paths to include them. Can config settings be altered on a per route/path basis?

# Answer
So, the issue I describe in my question is this Drupal Core issue: Drupal.ajax does not guarantee that "add new JS file to page" commands have finished before calling said JS

So, my solution wasn't to disable the aggregation, but to apply the latest patch provided in the issue on Drupal.org
> 1 votes

# Answer
We have two options:

Option 1: Disable advagg for admin routes: https://www.drupal.org/project/advagg/issues/3226448

Option 2: \[PP-1\] Drupal.ajax does not guarantee that "add new JS file to page" commands have finished before calling said JS: https://www.drupal.org/project/drupal/issues/1988968
> 0 votes

---
Tags: 8, css-js-aggregation
---


# Question
Title: How can get my site out of maintenance mode?
I moved my site from one server to another in the same way I moved another site. But it won't get out of maintenance mode.

I can access phpMyAdmin and I can access the server files easily.

I've tried `/user` and `/q=user`.

Any suggestions?

# Answer
> 13 votes
There is a few things you can try.

**1. Using drush**

Go to root of the website and run this drush commands one by one:

```
drush vset maintenance_mode 0
drush cc all

```

**2. Using database query**

Go to phpmyadmin and run this db statement in order to update the "maintenance\_mode" property in the variable table to "i:0;":

```
UPDATE `variable` SET `value` = 'i:0;' WHERE `name` = 'maintenance_mode';

```

**3. Login as admin programatically**

Make copy of the `index.php` file and call it what every want (`maintenance.php` for example) and at the end of the file replace

```
menu_execute_active_handler();

```

with

```
global $user;
$user = user_load(1);
drupal_session_regenerate();
drupal_goto('user');

```

go to that file (like `[your_website]/maintenance.php`), after that just disable maintenance mode and don't forget to remove this file after you finish.

**4. Manually set `maintenance_mode` variable in `index.php`**

Edit index.php file and put

```
variable_set('maintenance_mode', 0);

```

just before

```
menu_execute_active_handler();

```

**5. Configure maintenance mode in `settings.php` file**

At the end of your `settings.php` file put

```
$conf['maintenance_mode'] = 0;

```

# Answer
> 4 votes
Just go to /user/login, it works even in maintenance mode, and then sign in as an admin.

# Answer
> 2 votes
Using Drush in D8, one can do:

```
drush state-set system.maintenance_mode 0

```

To turn maintenance mode back on:

```
drush state-set system.maintenance_mode 1

```

# Answer
> 1 votes
And you can also get out maintenance mode by **admin/config/development/maintenance** under the tab you can able enable or disabled it.

# Answer
> 1 votes
On Drupal 8

If your drush does not have access to mysql but you have access to mysql console you could try this

```
UPDATE `key_value` SET `value` = 'i:0;' WHERE `name` LIKE '%maintenance_mode%'

```

# Answer
> 0 votes
On Drupal 8.1.1 the following drush commands worked for me:

* change directory to webroot
* drush sset system.maintenance\_mode 0
* drush cache-rebuild
* refresh homepage and login.

# Answer
> 0 votes
I've encountered the OP's issue after moving sites from one server to another, and it was because the database didn't fully import.

Compare the list of DB tables on the new server to the list of tables on the old server. If it's incomplete then it's likely you imported the DB through something like PHP MyAdmin and it wasn't fully imported.

You can import off the filesystem with `mysql -u username -p dbname < filename.sql`, or try using a script like bigdump.php.

You could also try reducing the file size of the imported DB file. Either clean out junk data that you don't need, or export the DB to multiple files with a subset of the tables in each.

# Answer
> 0 votes
As of Drupal 9.3.15, go to http://example.com/user/login

And then go to Configuration -\> Development -\> Maintenance Mode and then uncheck "Put site into maintenance mode"

this has got to be the easiest solution.

but this only works if the user is enabled the "Use the site in maintenance mode". Which is found at Home-\>Administration-\>People-\>System-\>"Use the site in maintenance mode"

---
Tags: maintenance-mode
---


title: How to use date_date_callbacks

text:
# Question
Title: How to use date_date_callbacks
In Datetime.php from Core\Datetime\Element, I read:

```
#date_date_callbacks: Array of optional callbacks for the date element.
    Can be used to add a jQuery datepicker.

```

What does it mean? How am I supposed to add a jQuery datepicker from a PHP function? Right now I am doing from a JS file included as a library, but I'd like to keep my custom widget more self contained (I am developing a custom widget to select weeks using jQuery datepicker).

# Answer
> 1 votes
The first argument those callbacks get is `$element` which, essentially, is a render array as described in Render API overview. This means, for example, that a #date\_date\_callbacks callback could use code similar to the following one.

```
function mymodule_date_callback($element, $form_state, $date) {
  $element['date']['#attached']['library'][] = 'mymodule/mylibrary';
  // Optionally, the callback can pass values to the JavaScript code.
  $element['date']['#attached']['drupalSettings']['foo'] = 'bar';
}

```

# Answer
> 1 votes
Checking the official documentation of DateTime class, it appears that it calls all the function names passed as string in the `#date_date_callback` array (check `processDatetime` function).

```
// Allows custom callbacks to alter the element.
if (!empty($element['#date_date_callbacks'])) {
  foreach ($element['#date_date_callbacks'] as $callback) {
    if (function_exists($callback)) {
      $callback($element, $form_state, $date);
    }
  }
}

```

The callback function accepts three arguments `$element` (the main element array), `$form_state` (the current form state) and `$date` (the Date object). So, a typical situation you would implement `hook_form_alter()` in your module and add your custom callback there.

```
/**
 * Implements hook_form_alter().
 */
function custom_module_form_alter(&$form, &form_state, $form_id) {
  ..
  $form['field_name']['...']['value']['#date_date_callbacks'][] = 'custom_module_date_date_custom_callback';
  ..
}

/**
 * Implements custom date_date callback function.
 */
function custom_module_date_date_custom_callback(&$element, &form_state, $date) {
  ..
  // Do whatever changes you want to do with $element or $form_state.
  ..
}

```

Keep in mind that the `$element` and the `$form_state` are passed by reference here. This is a very important step which ensures that whatever changes you do inside the callback are permanent and are passed to the final rendering of the form element.

---
Tags: 8, javascript, datetime
---


title: remove cache in hook_preprocess_node

text:
# Question
Title: remove cache in hook_preprocess_node
I'm using hook\_preprocess\_node to get node field and make some processes, then pass a variable to the node to use it in the node twig template. The problem with me that when I edit this node, it doesn't affect on the view, I have to clear cache to see this change on the node view.

```
function THEME_preprocess_node(&$variables) {

    if (isset($variables['elements']['#node'])) {
        $node = $variables['elements']['#node'];
        $bundle = $node->bundle();
    }
    if (isset($bundle) && $bundle == 'crse') {
        $course_schedules = array();
        foreach ($node->get('crse_sched') as $schedule_item) {
            $schedule_entity = \Drupal\node\Entity\Node::load($schedule_item->target_id);
            $schedule = new stdClass();
            $schedule->title = $schedule_entity->get('title')->getValue()[0]['value'];
            $schedule->seats = $schedule_entity->get('seats')->getValue()[0]['value'];
            $schedule->state = $schedule_entity->get('moderation_state')->getValue()[0]['value'];
            $course_schedules[] = $schedule;
        }
        $variables['schedules'] = $course_schedules;
    }
}

```

# Answer
> 9 votes
You have to add cache tags of all entities you get data from. Add this line to the foreach loop:

```
$variables['#cache']['tags'][] = 'node:' . $schedule_entity->id();

```

The parent node is already tagged, which would also happen for the schedule entities if rendered normally.

This is all you need to do, adding the tags of the entities you use to build the rendered output. The entity system invalidates cache items, which are tagged correctly, automatically on all CRUD operations.

# Answer
> 3 votes
Every entity has cache tags to get the cache tags of the current entity use

```
$cache_tags = $entity->getCacheTags();

```

You need to invalidate the cache so you have to call

```
\Drupal\Core\Cache\Cache::invalidateTags($cache_tags);

```

Than the cache for these cache\_tags will be invalidated.

# Answer
> 0 votes
Just add in your `hook_preprocess_node` to prevent it be cached

```
$variables['#cache']['max-age'] = 0;

```

# Answer
> 0 votes
In `THEME_preprocess_node` hook you can add the below code to disable the variable cache for particular content type.

```
if($variables['node']->getType() == 'content_type_machine_name') {
    $variables['#cache']['max-age'] = 0;
}

```

---
Tags: 8, theming, entities, hooks
---


# Question
Title: How to show a view instead of the node when the user click on the title
I am using a node to represent a subsite on my website. The node has just two fields: `title`and `field_subsite`. The titles are all listed on the front page.

The subsites are constructed using a View: I.e.: Each leaf node has a taxonomy field, which hold the subsite identifier. I use a contextual filter in a page View that picks up the subsite identifier to display a page with all the nodes that belongs to a particular subsite. For example: `example.com/subsite/1` shows all the nodes belonging to subsite with taxonomy term 1. All this works fine.

However, the missing bit is that when the user clicks on the title on the front page that identifies a subsite, they are taking to the node with the subsite identifier exposed. They have to click on this to see the actual subsite with taxonomy term 1.

Is there a way to set this up so that when clicking on title, the user is taken directly to the subsite represented by that title.

So far, all this has been created in the UI, but I guess that I should be able to solve this by implementing `hook_node_view()` and redirecting to the view from there?

However, I would like to know is there is a better solution.

# Answer
> 1 votes
The way I see it, you have two options here:

1. Replace the front page with a view of nodes, in the view render fields, and set the title of the display to link to the subsite for the node.
2. Use outbound link re-writing to rewrite node links to the subsite: https://www.drupal.org/node/2238759

---
Tags: 9, subsites
---


# Question
Title: TrustedResponseRedirect failing - how to prevent cache metadata?
I am getting the following when trying to redirect to an external site from my controller function defined in my routing file:

```
return new TrustedRedirectResponse($my_ext_url);

```

> LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\Core\Routing\TrustedRedirectResponse. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>wrapControllerExecutionInRenderContext() (line 159 of core\lib\Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber.php).

This is clearly related to cache metadata - but how do i switch this off for a trusted redirect?

Edit: There is currently no constructor on the controller and therefore no injection going on. Routing looks like:

```
tocyn_payment.paypal_checkout:
  path: 'test/{order_id}'
  defaults:
    _controller: 'Drupal\my_module\Controller\MyController::handle'
    _title: 'Test Tite'
  requirements:
    _permission: 'access content'

```

# Answer
> 11 votes
You mentioned the URL generator, which is one of the two ways this happens.

In short, you need to do something like my patch in this issue: https://www.drupal.org/node/2630808

Pass TRUE to toString(), then you get a different object back that you need to add as a cacheable dependency. You can do that with such GeneratedUrl objects, entity and config objects and you should do that whenever your response depends on them.

# Answer
> 0 votes
Many people may tell you this is what NOT to do, but for exotic and incomprehensible reasons, TrustedRedirectResponse can cause your controller to throw the error about metadata leaking "somewhere". I checked all around my desk and on the floor, and I couldn't find any metadata :) This can happen even if you disable caching for your route in every conceivable way.

So I thought well I'll create my trusted response but wrapping it in RenderContext bubble wrap. No dice. Maybe my situation is exotic, and the controller I'm working in does use code that's not in my control.

So if you get sick of Drupal telling you you can't do something, or want to skip hours of debugging leaky cache metadata whatever errors. Just make your own dang response..*Symfony is under the hood and it's much less bossy*. I added this method to my controller, and return the response, and boo-yeah, I can redirect to external sites. I just looked into the setTargetUrl() method of the RedirectResponse object.

I know that I only need to redirect to a small, finite number of external urls, so I can sanitize and white list the url input, so I only run this code to build a redirect for urls I trust.

```
private function createExternalRedirectResponse($url) {
    $response = new Response('', 302, []);
    $response->targetUrl = $url;
    $response->setContent(sprintf('<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url=%1$s" />

        <title>Redirecting to %1$s</title>
    </head>
    <body>
        Redirecting to <a href="%1$s">%1$s</a>.
    </body>
</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')));
    $response->headers->set('Location', $url);
    return $response;
  }

```

# Answer
> 0 votes
Since Drupal's `TrustedRedirectResponse` object extends `CacheableSecuredRedirectResponse`, I believe that is the source of the issue. This object is adding cache-related metadata to the response, which is what triggers the issue in this case.

I have a controller with actions that ONLY redirect - nothing is ever rendered. The simple solution I found is to just use Symfony's `RedirectResponse` directly and not use Drupal's `TrustedRedirectResponse` and then no cache metadata will be involved.

```
use Symfony\Component\HttpFoundation\RedirectResponse;

```

Hope this helps.

---
Tags: 8, caching, redirection
---


# Question
Title: Drupal.Behavior fires multiple times while logged in
Some of my Drupal behaviors are firing multiple times while as a logged-in user:

```
(function myFunction (Drupal) {
  "use strict";
  Drupal.behaviors.myBehavior = {
    attach: function attach (context) {

      console.log("Hello world");
    }
  };
}(Drupal));

```

The above will log "Hello world" multiple times in console while logged in, only once while logged out.

I've been working through updating scripts to use Drupal's `once()` library, but am unsure if this is the fix or just a patch.

Is there a higher context I could look at that might be causing this? I'm unsure of the difference between logged-in and logged-out here.

# Answer
`Drupal.behaviors` does not only fire on page load, it fires on ajax calls or whenever new elements are inserted into the DOM. The `once` library is built to handle this - you attach handlers to only fire a single time.

You can read more about using `once` here: https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview
> 1 votes

---
Tags: javascript, 9
---


# Question
Title: Is there a function to get the list of nodes by type?
Is there a function like `node_load()` that returns a list of nodes by a given content type?

I've tried `$nodes = node_load(array("type" => 'student_vote'))`, but it only returns one node.

I know I could code up something like `node_load()`, but I wanted to see if there might be anything like that out there already.

# Answer
> 46 votes
The code to use depends from the Drupal version.

### Drupal 6

```
$nodes = db_query('SELECT nid FROM {node} WHERE type="%s"', $type);

```

### Drupal 7

```
$nodes = node_load_multiple(array(), array('type' => $type));

```

### Drupal 8

```
$nids = \Drupal::entityQuery('node')
  ->condition('type', 'NODETYPE')
  ->execute();
$nodes = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadMultiple($nids);

```

# Answer
> 13 votes
There is no such API for Drupal 6. The closest you can do is to properly query for all node ID for the content type then load each one using node\_load() but this will require n+1 queries and is not very efficient.

```
function node_load_by_type($type, $limit = 15, $offset = 0) {
  $nodes = array();
  $query = db_rewrite_sql("SELECT nid FROM {node} n WHERE type = '%s'", 'n');
  $results = db_query_range($query, $type, $offset, $limit);
  while($nid = db_result($results)) {
    $nodes[] = node_load($nid);
  }
  return $nodes;
}

```

Note: `db_rewrite_sql` will ensure access check and other module provided filtering (such as language filtering provided by the i18n module).

For Drupal 7, you can use `$nodes = node_load_multiple(array(), array('type' => $type));`but the `$conditions` argument of `node_load_multiple()` is deprecated. Instead, you should use EntityFieldQuery to query for the node IDs then use `node_load_multiple()` but without a `$condition`s argument.

```
function node_load_by_type($type, $limit = 15, $offset = 0) {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', $type)
    ->range($offset, $limit);
  $results = $query->execute();
  return node_load_multiple(array_keys($results['node']));
}

```

# Answer
> 7 votes
There's several good answers already, but they take the question literally and refer to nodes only.

Since D6 doesn't have an API for doing what is being asked for, and it's not necessary to limit oneself to nodes in D7 and forward, I feel a good answer should be entity generic.

```
function entity_load_by_type($entity_type, $bundle, $limit = 10, $offset = 0) {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', $entity_type)
    ->entityCondition('bundle', $bundle)
    ->range($offset, $limit);
  $results = $query->execute();
  return entity_load($entity_type, array_keys($results[$]));
}

```

# Answer
> 0 votes
Drupal 8+

```
$content_type = 'article';
$articles = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties([
  'type' => $content_type,
]);

```

# Answer
> 0 votes
At the end, Drupal 8 deprecated functions like `node_load_multiple()`, `user_load_multiple()`, not just the `$conditions` parameter they used. This means it isn't possible to write Drupal 7 code that is compatible with Drupal 8, as the classes used in Drupal 8 aren't available on Drupal 7.

Drupal 7 code can still use `node_load_multiple()` and its `$conditions` parameter. To load all the nodes whose content type is `$content_type`, it's sufficient to use the following code.

```
$nodes = node_load_multiple(array(), array('type' => $content_type));

```

A more generic code that works for any entity would be the following one.

```
$entities = entity_load($entity_type, array(), array('type' => $bundle);

```

Despite the name, `entity_load()` loads more entities. It's the function used from `node_load_multiple()`.

```
function node_load_multiple($nids = array(), $conditions = array(), $reset = FALSE) {
  return entity_load('node', $nids, $conditions, $reset);
}

```

---
Tags: nodes
---


title: Title fields are displayed as a link

text:
# Question
Title: Title fields are displayed as a link
For me, all referenced fields or all title fields are displayed as links. This fits in the node as well as in views. However, I don't want this at all, but I would like these fields to be displayed exclusively as text fields. How can I prevent this?

# Answer
You can override node.html.twig from whatever base theme you are using, and alter it so the title does not display as a link.
> 0 votes

---
Tags: nodes
---


# Question
Title: Determine which region a menu block is rendered in
I need to re-use the same menu in two different regions, with slightly different markup. My thought was to simply check which region the block was being rendered in, and use if statements to modify the classes/structure as needed.

I've hit a roadblock; I was able to find a way to get what region a block is in, but I can't figure out how to pass that data to the menu. Here's my current code:

```
// Add a region variable to a block.
function theme_preprocess_block(&$variables, $hook) {
    $block_id = $variables["elements"]["#id"];
    $block = \Drupal\block\Entity\Block::load($block_id);
    $variables["region"] = $block->getRegion();
}

```

I can output the `region` variable just fine in `block--system-menu-block.html.twig`, but trying the variable doesn't get passed to `menu.html.twig`, which is where I need it.

I feel like I'm a stones through form an answer for this, if someone could point me in the right direction I'd be greatly appreciative.

Quick side note: I'm very new to Drupal, coming from WordPress development. So far it's been a difficult transition, so please assume I know nothing about themeing :)

# Answer
> 9 votes
Figured this out with the help of an article!

http://kristiankaa.dk/article/drupal8-region-specific-menu-theme-hook-suggestion

```
// Add a region variable to a block.
// http://kristiankaa.dk/article/drupal8-region-specific-menu-theme-hook-suggestion
function THEMENAME_preprocess_block(&$variables) {
    if (isset($variables["elements"]["#id"])) {
        $block_id = $variables["elements"]["#id"];
        $block = \Drupal\block\Entity\Block::load($block_id);

        if ($block) {
            $variables["content"]["#attributes"]["region"] = $block->getRegion();
        }
    }
}

// add a template suggestion based on region name
// http://kristiankaa.dk/article/drupal8-region-specific-menu-theme-hook-suggestion
function THEMENAME_theme_suggestions_menu_alter(array &$suggestions, array $variables) {
    if (isset($variables["attributes"]["region"])) {
        $suggestions[] = $variables["theme_hook_original"] . "__" . $variables["attributes"]["region"];
    }
}

```

That doesn't do *exactly* what I was trying for, but it does let me use different templates based on which region a block is being rendered in. Close enough for me :)

# Answer
> 0 votes
The `$variables["content"]["#attributes"]` seem not to work anymore in all cases. The attribute tag has to be targeted to the specific content within the block.

Hence `$variables["content"][0]["#attributes"]["region"] = $block->getRegion();` would work for those the previous answer didn't work.

---
Tags: 8, blocks, navigation, theming
---


# Question
Title: How to generate templates suggestion for media.html.twig for a specific field in a content type?
I have a content type (say Article) with an entity reference field to another content type (Author). I have used layout builder together with a view mode to display the content of the Author field in the Article content type.

One of the fields in Author is an image which is rendered via media.html.twig. Coincidentally there is also an image in Article rendered via media.html.twig

I used hook\_theme\_suggestions\_media\_alter to provide a new suggestion.

```
/**
 * Purpose: Adds theme suggestions for media.html.twig that are more specific to the content type.
 */
function custom_default_theme_suggestions_media_alter(array &$suggestions, array $variables) {

  if ($node = \Drupal::routeMatch()->getParameter('node')) {
    $content_type = $node->bundle();
    if($content_type == 'article') {
      $suggestions[] = 'media__' . $content_type;
    }
  }

}

```

but as the Author content type is rendered on the Article page I can't seem to get a suggestion for the Author page. Is is possible to generate a suggestion for media.html.twig for a particular field in a content type referencing another content type?

# Answer
> 0 votes
I found a workaround for this by using the view mode along with the content type. So the new code would be

```
/**
 * Adds theme suggestions for media.html.twig
 */
function my_custom_theme_suggestions_media_alter(array &$suggestions, array $variables) {

  if ($node = \Drupal::routeMatch()->getParameter('node')) {
    $content_type = $node->bundle();

    // Adding suggestion for article page.
    if($content_type === 'article_page' && ($variables['elements']['#view_mode'] === 'full')) {
      $suggestions[] = 'media__' . $content_type;
    }

    // Adding suggestion for author block in article page.
    if($content_type === 'article_page' && ($variables['elements']['#view_mode'] === 'responsive_image')) {
      $suggestions[] = 'media__author_block__' . $content_type;
    }
  }

```

---
Tags: 8, theming
---


# Question
Title: Get the node ID value after submitting an attached Webform to that node
I have a Webform attached as a field to a specific content type.

After the node is loaded and the Webform is submitted, I am using the below custom webform handler to get the `$webform_submission` values.

```
<?php

namespace Drupal\my_custom_module\Plugin\WebformHandler;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Form\FormStateInterface;

use Drupal\node\Entity\Node;

use Drupal\webform\WebformInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\webformSubmissionInterface;
use Drupal\webform\Entity\WebformSubmission;

/**
 * Do something when a webform submission is submitted.
 *
 * @WebformHandler(
 *   id = "Do something",
 *   label = @Translation("Do something"),
 *   category = @Translation("any category"),
 *   description = @Translation("Do something"),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_UNLIMITED,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 *   submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_REQUIRED,
 * )
 */

class customWebformHandler extends WebformHandlerBase {

  /**
   * {@inheritdoc}
   */

  // Function to be fired while submitting the Webform.
  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    // Get an array of the values from the submission.
    $values = $webform_submission->getData();

    // Get (Full Name) from (full_name) text element available on the webform.
    $fullnamevalue = $values["full_name"];

```

However, I would like to get the "nid" of that node from where the Webform is submitted, so I can load this node by nid to use it in my custom code.

How to get the "nid" of that node from where the Webform is submitted ?

# Answer
> 1 votes
I have found an answer here: https://www.drupal.org/project/webform/issues/3046808

```
if ($source_entity = $webform_submission->getSourceEntity()) {
   $nid = $source_entity->id();
}
else {
  $nid = NULL;
}

```

# Answer
> 0 votes
I found only the **real Node-ID** with the **referenced webform submission** with this code:

```
$source_entity = $request_handler->getCurrentSourceEntity('webform');
$arrayData = $source_entity->toArray();
$nodeId = intval($arrayData['entity_id'][0]['value']);

```

***$nodeId** will be the node where the webform was in.*

---
Tags: 8, nodes, webforms
---


# Question
Title: Programmatically check the checkbox of an exposed filter
I need to check a checkbox on an exposed filter for a view based on the url. I can't seem to figure out how to do that. If x is detected in the url, I want to set one of the fields of an exposed filter to have the status checked="checked." It seems like that would be pretty easy, but I can't seem to figure it out.

I have tried various ways through:

* `hook_views_pre_view()`
* `hook_views_pre_build()`
* `hook_form_views_exposed_form_alter()` (I feel like this should be the best way.)

I've found that I can effectively alter the results through `hook_views_pre_view()`, but I can't figure out how to check that freaking checkbox on the exposed filter.

Varioush failed attempts via `hook_form_alter()`:

* `$form["field_intended_use_target_id"]["#default_value"] = ['357'];`
* `$form_state->input["field_intended_use_target_id"][356] = '356';`
* `$form['field_intended_use_target_id']['widget'][0]['value']['#default_value'] = ['357'];`

Can anyone please help?

# Answer
I was finally able to achieve what I need via the hook\_views\_pre\_build() hook.

Please let me know if this is wrong or if there is a better way, but from what I can tell this is the best way to achieve this.

```
function module_views_pre_build(ViewExecutable $view) {
  $termId = 357;
  $view->setExposedInput(['field_name' => [$termId => $termId]]);
}

```
> 1 votes

# Answer
You can use `hook_form_alter()` by adding view id condition. The use the code below, replacing `FILTER_NAME` with the name of your filter and set the necessary options.

```
$request = \Drupal::request();
if (!$request->get(FILTER_NAME, NULL)) {
  $input = &$form_state->getUserInput();
  $input[FILTER_NAME] = [
    'opt1' => 'opt1',
    'opt2' => 'opt2',
  ];
}

```
> 0 votes

---
Tags: views, 8
---


# Question
Title: Site errors out when trying to create a subtheme based on Classy
I'm creating a custom theme in Drupal 9 and am trying to use classy as my subtheme but get the following error:

```
The website encountered an unexpected error. Please try again later.

Drupal\Core\Theme\MissingThemeDependencyException: Base theme classy has not been installed. in Drupal\Core\Theme\ThemeInitialization->getActiveThemeByName() (line 122 of core\lib\Drupal\Core\Theme\ThemeInitialization.php).

Drupal\Core\Theme\ThemeInitialization->initTheme('custom_theme') (Line: 406)
Drupal\Core\Theme\ThemeManager->initTheme(Object) (Line: 96)
Drupal\Core\Theme\ThemeManager->getActiveTheme() (Line: 214)
Drupal\Core\Theme\Registry->init(NULL) (Line: 258)
Drupal\Core\Theme\Registry->getRuntime() (Line: 194)
Drupal\Core\Entity\EntityViewBuilder->getBuildDefaults(Object, 'full') (Line: 61)
Drupal\node\NodeViewBuilder->getBuildDefaults(Object, 'full') (Line: 157)
Drupal\Core\Entity\EntityViewBuilder->viewMultiple(Array, 'full', NULL) (Line: 123)
Drupal\Core\Entity\EntityViewBuilder->view(Object, 'full') (Line: 98)
Drupal\Core\Entity\Controller\EntityViewController->view(Object, 'full', NULL) (Line: 66)
Drupal\node\Controller\NodeViewController->view(Object, 'full', NULL)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 705)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

Below is my `theme.info.yml` info:

```
name: Custom Theme
type: theme
description: "This is a custom theme for the company"
version: "1.0.0"
core: 8.x
package: "Custom"
core_version_requirement: ^8 || ^9
base theme: classy

# libraries:
#   - custom_theme/bootstrap_cdn
#   - custom_theme/global-styling

regions:
  search: Hidden Search Bar
  branding_navigation: Branding & Main Navigation
  header: Header
  primary_menu: Primary menu
  secondary_menu: Secondary menu
  content: Content
  footer: Footer

```

Why is it saying that 'Base theme classy' isn't installed? I've never run into this issue before. Does it have something to do with Drupal 9? (This is my first time starting from scratch in D9)

I see that classy is in the core files so not sure why I'm getting this error?

Any help/suggestions?

**EDIT:** I'm using Acquia Dev Desktop if that makes any difference.

# Answer
> 0 votes
**The root of problem**: base theme changing after the theme has been installed.

**How to change base theme**:

* Enable another theme;
* Click on "Uninstall theme";
* Change base theme;
* Click on "Install and set default";

---
Tags: theming, 9
---


title: How do I filter by year?

text:
# Question
Title: How do I filter by year?
I'm finding a lot of resources for 7 but not much for Drupal 8.

I'm displaying a content type with a date field in a view. I'd like a drop-down that presents users with a list of years for filtering purposes.

When I add that field as a filter I'm presented with two options:

1. A text input date, preferably in machine-readable format
2. An offset from the current date, also text input

Neither of these are very useful in an exposed filter. Is there a way I can filter only on the year using a drop-down?

# Answer
> 2 votes
Perhaps not the most elegant, but I used the following on the date field:

# Answer
> 0 votes
I think we should use the **regular expression** operator because it is easier to change the year:

Or you can use Views year filter module

---
Tags: views, 8
---


# Question
Title: Filter webform options from external source by field value
I have an options field which is sourced from an external json file using the following code.

```
$nsbooks_url = 'https://mysite.com/myjson.json';
$preoptions = json_decode(file_get_contents($nsbooks_url), TRUE);
$options = array_column($preoptions, 'Document Number');
\Drupal::cache()->set('nsbooks', $options);

```

The JSON file contains these lines.

```
[{
    "custid": "88149",
    "recordType": "salesorder",
    "Document Number": "SO7878"
}, {
    "custid": "89757",
    "recordType": "salesorder",
    "Document Number": "SO1226"
}]

```

In the webform, I have another field where the user enters their customer ID number. (*custid* in the JSON file.)

What I am trying to do is filter the JSON file so that only document numbers that match that customer ID number are shown as an option. How can I achieve this?

# Answer
> 0 votes
I think thats not possible without writing own code.

Try to alter the webform with the hook `your_module_webform_submission_form_alter` and add an ajax callback to the customer ID number field, which updates the options. To accomplish this, you can take a look at https://www.hashbangcode.com/article/drupal-9-cascading-ajax-select-forms.

---
Tags: webforms
---


# Question
Title: add wrapper div to form element in content type
Is there a way to add wrapper div around few form element in admin theme? I have a content type that i want to style its admin theme. I already have m sub-theme. I couldn't find the file that is rendering that page only. I thought i can style it using the same method as doing front end for content type. ( finding the html comment to where the files are and access each element using content.field.). So i am pretty lost on how to do this...

# Answer
> 2 votes
You can add theme suggestions to the form element and add the wrapper divs to the elements template. See How do I write a template file for a specific input field?

Or you can style the entire node edit form by copying this twig file into the theme folder:

*/my\_admin\_theme/templates/node-edit-form.html.twig*

```
{#
/**
 * @file
 * Theme override for a node edit form.
 *
 * Two column template for the node add/edit form.
 *
 * This template will be used when a node edit form specifies 'node_edit_form'
 * as its #theme callback.  Otherwise, by default, node add/edit forms will be
 * themed by form.html.twig.
 *
 * Available variables:
 * - form: The node add/edit form.
 *
 * @see claro_form_node_form_alter()
 */
#}
<div class="layout-node-form clearfix">
  <div class="layout-region layout-region--node-main">
    <div class="layout-region__content">
      {{ form|without('advanced', 'footer', 'actions') }}
    </div>
  </div>
  <div class="layout-region layout-region--node-secondary">
    <div class="layout-region__content">
      {{ form.advanced }}
    </div>
  </div>
  <div class="layout-region layout-region--node-footer">
    <div class="layout-region__content">
      <div class="divider"></div>
      {{ form.footer }}
      {{ form.actions }}
    </div>
  </div>
</div>

```

Seven and Claro have already implemented this for the node form. How to implement it for other forms see How to render specific form elements from the \*.theme file

---
Tags: theming
---


# Question
Title: Getting two errors when trying to click Extend and Config tabs
I'm getting the following errors:

> Drupal\Core\Extension\Exception\UnknownExtensionException: The profile does not exist or is not installed. in Drupal\Core\Extension\ExtensionList-\>getExtensionInfo() (line 346 of /app/drupal/core/lib/Drupal/Core/Extension/ExtensionList.php). Drupal\Core\Extension\Exception\UnknownExtensionException: The module does not exist or is not installed. in Drupal\Core\Extension\ExtensionList-\>getExtensionInfo() (line 346 of /app/drupal/core/lib/Drupal/Core/Extension/ExtensionList.php).

These errors are not telling me what module is missing. I have not installed any modules. The only thing that I've done is update core from 8.7 to 8.8.1 The only thing that I've done is update from Drupal 8.7 to 8.8.1. Is there anything I can do to find what module is causing the issue?

# Answer
> 3 votes
I found this Gist about Fixing a Drupal 8 site with an empty install profile related to your problem (which I also have). The guide solved the problems, but created another.

> Drupal\Core\Extension\Exception\UnknownExtensionException: The module minimal does not exist or is not installed. in Drupal\Core\Extension\ExtensionList-\>getExtensionInfo() (linea 346 di /var/www/html/web/core/lib/Drupal/Core/Extension/ExtensionList.php).

Looking for the second problem, I found this issue and patch #112 should solve all your problems without using the first guide I mentioned.

If instead you want to follow the guide, which I think is the best way to go, to solve the new problem do what comment #110 says. By adding the line `minimal: 1000` to the `core.extension.yml` file

# Answer
> 0 votes
You can fix this with Drush.

Please go to command line.

Change directory to document root.

Run this command:

`drush eval "\Drupal::service('extension.list.module')->reset()->getList();"`

This will fix the error.

PS: I am using `drush9`. So, please use correct version of `drush`.

---
Tags: 8
---


title: Error with Entity Bundle Classes

text:
# Question
Title: Error with Entity Bundle Classes
I created a bundle class that extends the taxonomy term class, but I get this error.

> Error: Interface 'Drupal\my\_artists\Entity\ArtistTermInterface' not found in include() (line 15 of /xxx/drupal/web/modules/private/my\_artists/src/Entity/ArtistTerm.php)

I set the bundle class in the *my\_artists.module* file.

```
use Drupal\my_artists\Entity\ArtistTerm;

function my_artists_entity_bundle_info_alter(array &$bundles): void {
  $bundles['taxonomy_term']['artist']['class'] = ArtistTerm::class;
}

```

In /src/ArtistTermInterface.php I defined the bundle class interface.

```
namespace Drupal\my_artists\Entity;

use Drupal\taxonomy\TermInterface;

/**
  * Represents a ArtistTerm entity.
  */
interface ArtistTermInterface extends TermInterface {}

```

In /src/Entity/ArtistTerm.php, I defined the bundle class.

```
namespace Drupal\my_artists\Entity;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\taxonomy\Entity\Term;

/**
 * Defines the ArtistTerm class.
 */
class ArtistTerm extends Term implements ArtistTermInterface {

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) {
    $this->set('field_some_field', 'some value');
    parent::preSave($storage);
  }

}

```

Why do I get the error?

# Answer
Entity bundle classes go in `/mymodule/src/Entity/Bundle/MyClass.php`.

To easily generate the bundle class and see what may be wrong, try the drush command `drush generate entity:bundle-class` and follow the prompts.

Drush docs
> 1 votes

---
Tags: 9
---


# Question
Title: Adding related user fields to comment field
I have a content type which has a field that prints post related comments. My users have a couple of extra fields like name and last\_name. Is there a possibility to add the first and last name of a user to a comment they've written, instead of just the username and profile picture?

```
function mysite_preprocess_node(&$variables) {
    $node = \Drupal::routeMatch()->getParameter('node');
    if($node && $node->getType() == 'berichten'){
        $variables['user'] = User::load($node->getOwnerId());

        $variables['field_reacties'] = $node->field_reacties->view('full');

    }

}

```

This is how I currently receive the comments view and show it to the related post.

# Answer
> 0 votes
I figured out that I can just receive user related fields from a comment by doing this `{{ comment.getOwner.field_naam.value }}` took me a while to figure that out, but it's handy for custom templates! :D

---
Tags: 9
---


title: How to access taxonomy term field?

text:
# Question
Title: How to access taxonomy term field?
I added two fields to my vocabulary terms field management. How do I get these values? There is no fields like color or Image in my Taxonomy Term vocabulary dump.

How does Drupal 8 store these additional fields?

```
$terms = $this->taxonomyStorage->loadTree($vocabularyName);

//CAN ACCESS
$terms[0]->name

//CAN'T ACCESS
$terms[0]->color

```

# Answer
> 3 votes
Its similar to any other entity on Drupal 8

```
$name = $terms[0]->name;

//simple text field
$color = $terms[0]->field_color->value;

//multivalue field - get array of values
$color = $terms[0]->get('field_color')->getValue();

//entity reference field
$entity = $terms[0]->field_color->entity;

//image field
$image = $terms[0]->get('field_image')->entity;
$image_uri = $image->getFileUri();

//get color entity id
$entity_id = $entity->id();

```

I think at least your **color** field is actually an entity reference

# Answer
> 0 votes
First of all, invoke the related class

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

```

and then try this code and just replace VID with your machine

```
    $taxonomy_terms_vocabularies = \Drupal::entityTypeManager()
         ->getStorage('taxonomy_term')
         ->loadByProperties([
         'vid' => 'car_sub_type'
     ]);
      $taxonomy_terms_vocabularies = array_keys($taxonomy_terms_vocabularies);
      $taxonomy_terms_vocabularies_opt = [];
      foreach($taxonomy_terms_vocabularies as $key => $val){
        $term = Term::load($val);
        $name = $term->getName();

          $taxonomy_terms_vocabularies_opt[] = array(
            'id' => $val,
            'name' =>  $name
            'abc' =>   $term->get('field_machine_name')->value
          );
      }

```

# Answer
> 0 votes
if the taxonomy is a entity reference field :

```
 $current_entity_lang = $entity->get('langcode')->value;
    //version and so current revision
    $translated_entity = $entity->getTranslation($current_entity_lang);
    // if single value for the taxo
    $value=$translated_entity->get('field_name')->referencedEntities()[0]->getName();
    //else loop the values to get name
    $values=$translated_entity->get('field_name')->referencedEntities();

```

---
Tags: 8, taxonomy-terms, entities
---


title: Add custom actions

text:
# Question
Title: Add custom actions
In our website, I created a webform to allow users to ask for permission to purchase items; then, I created a view to show a table of records with the values in the fields contained in the webform submissions.

How can I add a custom button next to each record of the view to make our chief accountant able to authorize the requests, one by one?

I mean, clicking the custom button an e-mail should be sent to the authors of the requests notifying them they can proceed to buy the items they need, or eventually they can't, if only I could even add a *Yes/No* radio button besides the *Authorize* button.

# Answer
> 0 votes
Possibly another, simpler, approach might be to use VBO (views\_bulk\_operations) and a custom action. VBO will give you checkboxes beside each row of your view and then a button at the top/bottom of the view to run a single action "Authorize". That is the easy part. The tricky part is then to create a custom "action" which sends the email (with info from that record). Take a look under VBO's src/Plugins/Actions folder to see some example actions.

---
Tags: views
---


# Question
Title: How to prevent a node from being saved/updated by using the Rules module?
I've created a content type 'H'. The following rule (using the Rules module) has been built to prevent the node from being saved/updated if the field 'a' is larger than 5.

Event: Before saving content of type 'H'.

Condition: Data Comparison - Node field 'a' is larger than 5.

Action: Show a message on the site - Message type: Error.

Action: Go back to the front page.

It will show the error message if the condition is TRUE. However, the node is still being saved/updated.

Is it possible to control this without programming?

# Answer
> The following rule (using the Rules module) has been built to prevent the node from being saved/updated if the field 'a' is larger than 5.

Rules is absolutely the wrong place to be doing this. Once the save has been triggered by Drupal core, you can't stop that from happening. You need to prevent the invalid data from being saved in the first place.

This kind of validation needs to be done on the front end, when the user provides input. By the time Rules gets a chance to see this input data, the node IS ALREADY IN THE PROCESS OF BEING SAVED. At this point, you can't stop the save.

If you want to restrict the value of a field or a form element, the proper way to do that is with a field validation function or a form validation function. Yes, you will need to write code to do this. There may be other contributed modules that allow you to set constraints on form input values or field input values. Rules is not one of them.
> 1 votes

# Answer
I'm not aware of a way to do what you're asking for by only using the Rules module ... And the (old) issue about "Prevent Node from being saved" (with confusing status "Closed (fixed)" ...) somehow seems to confirm you'd need "a bit more" ...

You can try to make it work by ALSO using the Conditional Rules module for this. Some more details about this module (from its project page):

> ... provides Rules plugins for conditionally altering execution flow directly inside a group of **actions**.

Here is a screenprint of a rule with an action that uses Conditional Rules (though only with an "if"-part here, no "else"):
> 0 votes

---
Tags: 7, nodes, rules
---


title: Is there a "Block HTML tags" filter?

text:
# Question
Title: Is there a "Block HTML tags" filter?
I am wondering if there is a contrib module which does the reverse of the core "Limit allowed HTML tags" (poorly named oxymoron, this should just be "Allow HTML tags") by allowing me to simply list the tags which I do not want allowed?

Basically I am trying to only block H1s (obviously editors should never be adding H1s to Body fields) and also EM tags. At the moment I need to enable the "limit allow" filter and add a full list of tags except the 2 I want to block. And every couple weeks the editors come up with another tag or attr which needs to be allowed. This would be much simpler to just have a "Block HTML tags" filter. Ideally this would just be a change to the core filter to have a block/allow option with this filter.

I suspect writing this isn't too difficult (just copy the core "allow" one and modify) but thought I would check if anyone knows of an existing contrib module which already exists.

# Answer
> 0 votes
I don't know of a general purpose "block HTML tags" module, but the Markdown module has a **Disallowed Raw HTML** setting for escaping certain tags. However, this uses the League\Commonmark library and so is limited to Commonmark Markdown.

---
Tags: 9
---


# Question
Title: Do I have to sanitize value parameters in a QueryInterface::condition statement?
Do I need to sanitize `$userinput` in this code, or is it done by Drupal?

```
$nids = \Drupal::entityQuery('node')
  ->condition('type','my_node_type')
  ->condition('field_myfield', $userinput)
  ->execute();

```

In my case, `$userinput` is a path parameter from the .routing.yml file.

If necessary, how do I sanitize it? I found `RequestSanitizer::sanitize()`. Is that enough to protect against SQL injections?

# Answer
> 3 votes
As shown in Writing secure code for Drupal / Use the database abstraction layer to avoid SQL injection attacks, it's not necessary to sanitize user input used in the `condition()` method, as long as the user input isn't used to select the operator to apply. This means that the code shown in the question is fine, but the following code is not.

```
\Database::getConnection()
  ->select('table', 't')
  ->condition('t.field', $value, $userInput)
  ->execute();

```

What reported in that documentation is for the database classes, but it's also valid for the methods exposed from the instance returned by `\Drupal::entityQuery()`.

---
Tags: entities, 9
---


# Question
Title: Run hook_preprocess_node only for main page
Is it possible to run `hook_preprocess_node()` only for the main page, and not for the referenced nodes that are on that same page?

I am using the following code, but it doesn't feel like the best option.

```
function mymodule_preprocess_node(&$variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $current_alias = \Drupal::service('path_alias.manager')->getAliasByPath($current_path);
  if ($current_alias === $variables['url']) {
    //run code
  }
}

```

# Answer
> 2 votes
If the other nodes are rendered using a different view mode, you can check that `$variables['view_mode']` is `'full'` or the view mode used for rending nodes on /node/\[nid\].

Otherwise, you can verify the node ID that appears in the URL is equal to `$variables['node']->id()`. You should not need to check path aliases, as Drupal should internally convert the path alias to the normal path.

---
Tags: nodes, hooks, 9
---


# Question
Title: Correct approach to extend webform submission purge conditions?
I'd like to extend the behavior of WebformSubmissionStorage's purge method (e.g. to prevent locked submissions from being purged), and add the corresponding elements in the "basic" configuration form for purge options.

The configuration form can probably be enriched by implementing hook\_form\_alter. But what is the correct approach to extend the purge method ? I don't see how overriding the class could help, so there has to be another way.

Antoine

# Answer
Try following the buildForm override approach described here: Override buildForm() in another module

This would include overriding the route `entity.webform_submission.collection_purge` defined in webform.routing.yml
> 0 votes

---
Tags: webforms
---


title: Current user filter

text:
# Question
Title: Current user filter
I have a web form, and I want to filter records by current user from views module, when I select filter "submitted by" and use equal to \[current-user:uid\], I don't get any results, can someone help me, I don't realize what I'm doing wrong. Thank you

# Answer
The way to do this is to not use a query filter for the user id, but to use a contextual filter on the current user instead. This will grab the current users ID as a dynamic filter in a View.
> 0 votes

---
Tags: webforms
---


# Question
Title: Faster phpunit-bootstraping for single Unit-Tests
My team and I started on Drupal some months ago. As we began creating our own modules, I also wanted to test them, but was very annoyed by the Performance of the tests - or better: of the Performance of core/tests/bootstrap.php:

* It takes about 35 seconds after entering the phpunit-command until the tests have passed.
* The Unit-Tests themselves in my modules take 1-2 Seconds to pass.
* All the other time is spent in building up phpunit, especially in `core/tests/bootstrap.php`#`drupal_phpunit_populate_class_loader()`

The reason: Although I only want to test my module, bootstrap.php scans every path in all the modules, profiles and themes in core and contrib for populating `$GLOBALS['namespaces']`. IMHO, 30seconds of bootstraping for any tests prohibits fast and often testing and therefor makes test-driven development impossible.

I found that I can significantly improve the performance by calling phpunit with the UnitTest-Folder as argument (`phpunit modules/custom/modulename/tests/src/Unit`) and changing `$paths` in `drupal_phpunit_contrib_extension_directory_roots()`:

```
  $paths = [
//    $root . '/core/modules',
//    $root . '/core/profiles',
//    $root . '/core/themes',
//    $root . '/modules',
//    $root . '/profiles',
//    $root . '/themes',
      $root . '/modules/custom',
      $root . '/themes/custom'

```

With this change, bootstraping the tests takes about 1-2 seconds, which would be accetable for me. But it works only for UnitTest, Kernel- and Browser-Tests run no more.

So my questions:

1. Is bootstraping of around 30sec for running of phpunit under drupal considered as 'normal' or is this a sign of something broken in my installation?
2. Is there any proposed way to reduce bootstraping time when doing only UnitTests?
3. I suppose I could create a second phpunit.xml, referring to an alternative core/tests/bootstrap.php with a $paths, which is reduced to our custom modules. And then, I would call phpunit with `-c`-option for the alternate phpunit.xml and the Unittest-Folder as argument. Is this a good idea or a sure way to shoot myself in the foot?

======
Update: Thanks to the Feedback from Kevin, I once more investigated why core/tests/bootstrap.php took so long to populate the classloader: The culprit is not bootstrap.php/drupal, but vagrant/virtualbox:

If I run the unit-tests from outside vagrant, they run in 1-2 seconds, as it seems normal to me (and is along what Kevin said)
If I run them inside the vagrant, the they take \>30seconds.
The difference is in bootstrap.php, when `drupal_phpunit_find_extension_directories()` iterates over all Module-, Profile- and Theme-Directories in core, contrib and sites. Those directories are mounted via the Sync Folder-Feature by Vagrant, where there is a known performance-issue with Virtualbox.

Therefore, I renounce from hacking core :)

# Answer
> 3 votes
Kernel and Functional tests are expected to take longer because of a full Drupal bootstrap and site scaffolding per run to test in a clean environment. Unit tests are running raw code and should execute very quickly. I can run a few hundred of them in a matter of seconds.

Ensure your phpunit.xml file is set up correctly. For example, scanning for tests only in the custom module directory:

```
<testsuites>
    <testsuite name="unit">
      <directory>web/modules/custom/*/tests/src/Unit</directory>
    </testsuite>
    <testsuite name="kernel">
      <directory>web/modules/custom/*/tests/src/Kernel</directory>
    </testsuite>
    <testsuite name="functional">
      <directory>web/modules/custom/*/tests/src/Functional</directory>
    </testsuite>
  </testsuites>

```

Or running a specific kind of test:

```
phpunit --testsuite unit

```

Other than that something is wrong with your setup. It should never take 30 seconds to kickstart a unit test. Make sure you are not running with xdebug enabled and listening, etc.

(also, dont hack core!)

---
Tags: testing
---


# Question
Title: Send array from twig to controller via route
I have in my twig a link as shown below and I would like to send a lot of data (array) to a controller. How do I go about it ? Do I use params? what is the best way to handle this in your opinion? Thanks.

In my twig:

```
 <a href="{{ path('mymodule.send') }}">Send</a>

```

Routing file:

```
mymodule.send:
  path: '/admin/send'
      defaults:
        _controller: '\Drupal\mymodule\Controller\MyController::myFunction'
        _title: 'Send data'
      requirements:
        _permission: 'administer site configuration'
      options:
        _admin_route: TRUE

```

My controller where I want to send data:

```
class MyController extends ControllerBase {

      public function myFunction() {
        }

    }

```

# Answer
A lot of data should typically be in the body of an HTTP message, so a POST with data as JSON, application/x-www-form-urlencoded, or multipart/form-data is the way.

If there is not so much data, and it is a one-dimension array, and it is acceptable that it will be logged in webserver access logs, you can use query strings.
> 0 votes

---
Tags: routes, 9
---


# Question
Title: Installing configuration from a module that is tracked in configuration on deployment
I am trying to install a module on a higher level environment. The module installs configuration in its config/install directory, and that configuration was also exported to the main site configuration folder. On the upper environment, I cannot install the module now (configuration already exists). How do you support this case? Do you deploy the install first (core.extention.yml), then come in behind it with the additional config it exports to the normal Drupal configuration directory?

# Answer
You have to remove the module’s exported config first then re-add it along with the module activation.

Technically all you have to do is remove the module’s configuration from active configuration, which you can do with Drush.
> 1 votes

---
Tags: 9, configuration
---


# Question
Title: How do I set the default value for a user entity reference field in hook_form_alter()?
I tried the following code, but it doesn't work.

```
$form['field_name']['widget'][0]['target_id']['#default_value'] = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

```

# Answer
The default widget used for the entity reference fields (with the exception of entity reference fields for taxonomy tags) is implemented by the `EntityReferenceAutocompleteWidget` class which, in its `formElement()` implementation, returns the following form element.

```
$element += [
  '#type' => 'entity_autocomplete',
  '#target_type' => $this->getFieldSetting('target_type'),
  '#selection_handler' => $this->getFieldSetting('handler'),
  '#selection_settings' => $selection_settings,
  // Entity reference field items are handling validation themselves via
  // the 'ValidReference' constraint.
  '#validate_reference' => FALSE,
  '#maxlength' => 1024,
  '#default_value' => isset($referenced_entities[$delta]) ? $referenced_entities[$delta] : NULL,
  '#size' => $this->getSetting('size'),
  '#placeholder' => $this->getSetting('placeholder'),
];

```

Instead of `$form['field_name']['widget'][0]['target_id']['#default_value']`, the code should set `$form['field_name']['widget'][0]['#default_value']`.

```
$form['field_name']['widget'][0]['#default_value'] = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

```

As side note, to alter the form element(s) returned from a field widget, Drupal uses `hook_field_widget_complete_form_alter()` (and `hook_field_widget_complete_WIDGET_TYPE_form_alter()`). It has access to the following information.

* The widget plugin instance (`$context['widget']`), which allows to access the widget ID (for example, *entity\_reference\_autocomplete*, *entity\_reference\_autocomplete\_tags*) with `$context['widget']->getPluginId()`
* The field values (`$context['items']`), which allows to get the target type of the reference field (`$context['items']->getFieldDefinition()->getFieldStorageDefinition()->getSetting('target_type')`)or the field type (`$context['items']->getFieldDefinition()->getType()`), for example

When possible, it should preferable to use this hook for field widgets, instead of `hook_form_alter()`.

`media_field_widget_complete_form_alter()` is the implementation of that hook done by the Media module.
> 1 votes

# Answer
I know this is tagged for Drupal 9, but if anyone finds this page from Google looking for a **Drupal 7** solution, it took me about an hour of searching, but I finally found this:

```
function mymodule_form_alter(&$form, $form_state, $form_id) {
    // .... //
    $whatever_node = node_load($whatever_nid);
    $form['field_event']['und'][0]['target_id']['#default_value'] = array ($whatever_node->nid => $whatever_node->title);
}

```

To clarify-- this is for when your entity reference is an auto-complete field.

This is for an Entity Reference, not a node reference. Also, if you're doing anything to the title of the node in hook\_node\_load, make sure you are setting the original node title.
> 0 votes

---
Tags: entities, forms, 9
---


# Question
Title: How do I programmatically add fields to a custom entity bundle?
I created a custom Entity, using the following code in the *CustomEntity.php* file.

```
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
  $fields = parent::baseFieldDefinitions($entity_type);

  $fields['name'] = BaseFieldDefinition::create('string')
    ->setLabel(t('Name'))
    ->setDescription(t('Name'))
    ->setSettings([
      'max_length' => 50,
      'text_processing' => 0,
    ])
    ->setDefaultValue('')
    ->setDisplayOptions('view', [
      'label' => 'above',
      'type' => 'string',
      'weight' => -4,
    ])
    ->setDisplayOptions('form', [
      'type' => 'string_textfield',
      'weight' => -4,
    ])
    ->setDisplayConfigurable('form', TRUE)
    ->setDisplayConfigurable('view', TRUE);

  return $fields;
}

```

We can add fields for the entity and all bundles will automatically inherit them.

I set a bundle in the myModule/config/install/myModule.customEntity.bundleA.yml file.

```
uuid: db129d12-849a-4e68-bb56-d787b4b0cf42
langcode: en
status: true
dependencies: {  }
id: bundleA
label: bundleA

```

How can I programmatically add fields to that bundle?

# Answer
An entity class can implement `FieldableEntityInterface::bundleFieldDefinitions()` to add fields to a bundle, but as that documentation page says, the recommended approach is another one.

> This function can return definitions both for bundle fields (fields that are not defined in `$base_field_definitions`, and therefore might not exist on some bundles) as well as bundle-specific overrides of base fields (fields that are defined in `$base_field_definitions`, and therefore exist for all bundles). However, bundle-specific base field overrides can also **be provided by 'base\_field\_override' configuration entities, and that is the recommended approach** except in cases where an entity type needs to provide a bundle-specific base field override that is decoupled from configuration.

As for decoupling the bundle fields from the configuration, the same page says:

> Note that for most entity types, the bundles themselves are derived from configuration (e.g., 'node' bundles are managed via 'node\_type' configuration entities), so decoupling bundle-specific base field overrides from configuration only makes sense for entity types that also decouple their bundles from configuration.

Finalize API for creating, overriding, and altering code-defined bundle fields could change how bundle fields are created. That issue isn't yet marked as fixed, and it has been opened 8 years ago.
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Programmatic webform redirect on submission not redirecting
I have a webform with the confirmation set to redirect to URL (redirects to a custom path or URL) In my webform handler, I have the following:

```
public function confirmForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
  $url = "https://SOMEURL.com";
  $url = Url::fromUri($url);
  $form_state->setRedirectUrl($url);
}

```

I verify with xDebug that $url contains a valid Url object with the correct value in its uri property, but the form then redirects to the path in the placeholder and not the new one.

# Answer
> 1 votes
The issue was the setting in the UI for the webform confirmation. Instead of selecting redirect to a URL (which is actually what it needs to do), 'none' should be selected, which then adds a description implying that the selection will result in control of confirmation being turned over to a handler.

That is, the other selections will cause whatever the handler does to be overridden, where 'none' will leave alone whatever the handler does to form\_state.

---
Tags: webforms, 9, redirection
---


title: Access preprocess variable globally

text:
# Question
Title: Access preprocess variable globally
I am trying to get the Custom Block type fields using a preprocess hook. I can successfully use the following code.

```
function theme_preprocess_block(&$variables) {
  $content = $variables['elements']['content'];
  if (isset($content['#block_content']) && $content['#block_content'] instanceof BlockContentInterface) {
    $blockType = $content['#block_content']->bundle();

    if ($blockType == 'image_and_video') {
        $variables['title_test'] = $content['#block_content']->get('field_title')->value;
    }
  }
}

```

Using `{{ title_test }}` in any of the block templates works well, but I want to use this variable in layout--twocol-section.html.twig for some purpose.

Is there any other way I can use this variable other than the block template?

# Answer
> 1 votes
`$variables['elements']['content']['#block_content']` is not available in other templates, which you can target directly or via the general `HOOK_preprocess((&$variables, $hook)` and `$hook != 'block'`. This general hook is only useful for globally available information.

The block entity here is local to the specific block template. A page can have dozens of blocks, each with its own local variables. Blocks are rendered (which includes the execution of preprocess hooks) and then cached, isolated from the rest of the page. Not only in the scope of the variables but also in time. Normally an entity block depends only on the database and unless the database item is not changed it can stay in cache forever.

---
Tags: blocks, hooks, layout-builder
---


# Question
Title: How do i change date format in View Exposed Date filter?
How do I change date format in View Exposed Date filter? By default it's in d/m/Y format, I want to make it Y.m.d format, without changing the query parameter date format (Y-m-d).

Any suggestion, how can I achieve this?

# Answer
> 2 votes
To make it easy let's disable Drupal datepicker and make it with javascript.

First disable jquery ui datepicker from exposed filter (like picture below)

Then create a module with libraries in file my\_module.libraries.yml like below

```
d8_datepicker:
  version: 1.x
  js:
    https://code.jquery.com/ui/1.12.0/jquery-ui.min.js: { type: external, minified: true }
    js/datepicker.js: {}

```

And in our my\_module.module let's alter the exposed form and add line below :

```
  function my_module_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
     if ($form_id == 'views_exposed_form') {
      $form['field_date_value']['#type'] = 'textfield';
      $form['field_date_value']['#attributes']['class'][] = 'datepicker-text';
      $form['field_date_value']['#attributes']['placeholder'] = 'yyyy-dd-mm';
      $form['#attached']['library'][] = 'd8/d8_datepicker';
      $form['#validate'][] = 'my_exposed_validate';
     }

```

In our validate form function we will change date from our custom format to format needed by drupal :

```
function my_exposed_validate(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  if(!empty($form['field_date_value']['#value'])) {
    $dt = date_create_from_format('Y-d-m', $form['field_date_value']['#value']);
    if($dt!==FALSE) {
      $value = $dt->format("Y-m-d");
      $form_state->setValue('field_date_value', $value);
    }
  }
}

```

And finaly in our file datepicker.js add this line :

```
(function($) {
    $('.datepicker-text').datepicker({ dateFormat: 'yy-dd-mm' });
})(jQuery);

```

Hope this helpful and if you wan't to go further, alter a form validation to check if the format sended is date or not ;)

# Answer
> 1 votes
In Drupal 8, Better Exposed Filter - To change the date format in jQuery Calender,use the following,

In custom module -

```
function MODULE_NAME_js_alter(&$js) {
  $js['settings']['data'][] = array('better_exposed_filters'=> array('bef_dateformat'=>'dd/mm/yy'));
}

```

In Js -

```
$('.bef-datepicker').datepicker({ dateFormat: 'dd/mm/yy' });

```

# Answer
> 0 votes
Drupal 8 uses html5 date fields and can have custom (browser) settings. The format you see is 'dd/mm/yyyy'. Users surfing with Chrome using default language will see 'mm/dd/yyyy'. The advantage here is that the browser uses their default pop-up for date fields and you do not have to add them yourself.
So in order to achieve what you want, you would have to do something custom, this could help as a starter http://form.guide/html5/html-input-type-date-format.html.
Keep in mind that date fields have validators that expect the HTML5 format on the backend.

# Answer
> 0 votes
I'm expanding on Wasim Khan's response, as it worked well for me. First, the Better Exposed Filters module needs to be enabled, and the exposed form display needs to be set as BEF rather than the default. Then the following can be done for the field:

```
function MODULE_NAME_js_alter(&$js) {
  if (isset($js['settings']['data']['better_exposed_filters'])) {
    $js['settings']['data']['better_exposed_filters']['bef_dateformat'] = 'yy/mm/dd'
  }
}

```

Note that `yy` expands to a 4-digit year, so if you put `yyyy` it will use the 4-digit year twice, like `20222022`. Therefor `yy` is what you will want, whichever location in the date you put it.

Then you can add the following JS script in a library:

```
(function ($, Drupal) {

  "use strict";

  function befDateFilterWatcher(context) {
    $(context).find('.bef-datepicker').once('bef-date-filter-watcher').each(function () {
      $(this).datepicker({ dateFormat: 'yy/mm/dd' });
    });
  }

  Drupal.behaviors.customModuleBefFilterFormat = {
    attach: function (context) {
      befDateFilterWatcher(context);
    }
  };

}(jQuery, Drupal));

```

And make sure to declare dependencies on `core/jquery` and `core/once` for the JS library this is attached to.

As an added benefit for the UX, you can edit the BEF settings for any fields and add `YYYY/MM/DD` as a placeholder for the field, letting users understand the expected format.

---
Tags: 8, views
---