# Question
Title: Extracting user field values from dynamic SQL queries
### Aim

I have successfully written a fairly long dynamic sql query, however am struggling with a seemingly simple part at the end.

Although, I am able to successfully extract `mail` and `name` from the `users` table, when I try to extract `field_first_name` it returns the error below.

The users table has a column with the machine name: field\_first\_name

### Code

```
    $database = \Drupal::service('database');

    $select = $database->select('flagging', 'f');
    $select->fields('f', array('uid', 'entity_id'));
    $select->leftJoin('node__field_start_datetime', 'nfds', 'nfds.entity_id = f.entity_id');
    $select->fields('nfds', array('field_start_datetime_value'));
    $select->leftJoin('node_field_data', 'nfd', 'nfd.nid = f.entity_id');
    $select->fields('nfd', array('title'));
    $select->leftJoin('users_field_data', 'ufd', 'ufd.uid = f.uid');
    // TODO extract first name
    $select->fields('ufd', ['mail', 'name', 'field_first_name']);

    $executed = $select->execute();
    $results = $executed->fetchAll(\PDO::FETCH_ASSOC);

    $username = $result['name'];
    $email = $result['mail'];
    $first_name = $result['field_first_name'];

```

### Error

```
Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ufd.field_first_name' in 'field list': SELECT f.uid AS uid, f.entity_id AS entity_id, nfds.field_start_datetime_value AS field_start_datetime_value, nfd.title AS title, ufd.mail AS mail, ufd.name AS name, ufd.field_first_name AS field_first_name FROM {flagging} f LEFT OUTER JOIN {node__field_start_datetime} nfds ON nfds.entity_id = f.entity_id LEFT OUTER JOIN {node_field_data} nfd ON nfd.nid = f.entity_id LEFT OUTER JOIN {users_field_data} ufd ON ufd.uid = f.uid; Array ( ) in event_notification_cron() (line 63 of /app/modules/custom/event_notification/event_notification.module).

```

### Field

# Answer
* Assuming your field is a string, the field in the database will be `field_first_name_value`
* Assuming the field is attached to a user entity, the table for that field should be `user__field_first_name` (2 underscores between user and the field name) your need one more join to get that field value, it's not stored in `users_field_data`

```
$database = \Drupal::service('database');

$select = $database->select('flagging', 'f');
$select->fields('f', array('uid', 'entity_id'));
$select->leftJoin('node__field_start_datetime', 'nfds', 'nfds.entity_id = f.entity_id');
$select->fields('nfds', array('field_start_datetime_value'));
$select->leftJoin('node_field_data', 'nfd', 'nfd.nid = f.entity_id');
$select->fields('nfd', array('title'));
$select->leftJoin('users_field_data', 'ufd', 'ufd.uid = f.uid');
$select->leftJoin('user__field_first_name', 'uffn', 'uffn.uid = f.uid');
// TODO extract first name
$select->fields('ufd', ['mail', 'name']);
$select->fields('uffn', ['field_first_name_value']);

$executed = $select->execute();
$results = $executed->fetchAll(\PDO::FETCH_ASSOC);

$username = $result['name'];
$email = $result['mail'];
$first_name = $result['field_first_name_value'];

```
> 2 votes

---
Tags: 8, database
---


title: Set disabled cache but it's not working

text:
# Question
Title: Set disabled cache but it's not working
I'm a newbie in Drupal site development and I'm using Drupal 9.x. In directory web/sites/default I have 2 files:

**settings.php**

```
if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  include $app_root . '/' . $site_path . '/settings.local.php';
}

```

**settings.local.php**

```
<?php

assert_options(ASSERT_ACTIVE, TRUE);
\Drupal\Component\Assertion\Handle::register();

$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';
$config['system.logging']['error_level'] = 'verbose';
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['discovery_migration'] = 'cache.backend.memory';
$settings['cache']['bins']['page'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
$settings['rebuild_access'] = TRUE;
$settings['skip_permissions_hardening'] = TRUE;
?>

```

I think this settings are okay but everytime I modify template and reload page it doesnt change, I must go to admin and then clear cache. Please tell me how do I fix it?

# Answer
In /sites/default/**settings.local.php** make sure you have

```
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';

```

You need to go to /sites/**development.services.yml** and turn off Twig's cache by adding

```
Parameters:
    twig.config: { debug: true, auto_reload: true, cache: false }

```

This is what mine looks like:

```
# Local development services.
#
# To activate this feature, follow the instructions at the top of the
# 'example.settings.local.php' file, which sits next to this file.
parameters:
    twig.config: { debug: true, auto_reload: true, cache: false }
    http.response.debug_cacheability_headers: true
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory

```

For more info, see Disable Drupal 8 caching during development
> 1 votes

---
Tags: configuration
---


# Question
Title: How do I add a button with a custom redirect to a node view?
I'd like to add a "More info" button to the bottom of a node view. The button should redirect the user to a URL based on the current node, e.g. `node/1/info`:

```
/**
 * Implements hook_node_view
 *
 * Add the "More Info" button to idea content
 */

function implementations_node_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {

  $build['implementations_addition'] = [
    '#type' => 'button',
    '#value' => t('More Info'),
    '#submit' => ['implementations_submit_impl'],
    '#weight' => 1000,
    '#attributes' => [
      'class' => ['btn', 'btn-primary'],
      //'onclick' => "location.href='https://google.com'" # dirty hack I really want to avoid
    ],
  ];
}

function implementations_submit_impl(array $form, \Drupal\Core\Form\FormStateInterface $form_state) {
  # just a mock redirect for now
  return new Symfony\Component\HttpFoundation\RedirectResponse(\Drupal\Core\Url::fromRoute('user.page'));
}

```

The above code results in the button correctly appearing, but when I click on it, nothing happens. What am I doing wrong here? Is there a better way?

# Answer
> 3 votes
You can use a link and add css classes needed to fake a button.

```
function implementations_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  $url = Url::fromRoute('your.route', ['node' => $entity]);
  $url_options = [
    'attributes' => [
      'class' => [
        // Add or remove CSS classes here
        'button',
        'button-action',
        'button--primary',
        'button--small',
      ],
    ],
  ];
  $url->setOptions($url_options);

  $build['more_info'] = [
    '#type' => 'link',
    '#title' => t('More Info'),
    '#url' => $url,
  ];
}

```

---
Tags: 8, hooks
---


# Question
Title: Using an authentication provider to keep a user permanently logged in eventually causes session problems
Because I got fed up of having to log in to my local development sites every however long, I tried making a simple custom module that just has an Authentication Provider service that always returns user 1, like this:

```
  /**
   * {@inheritdoc}
   */
  public function applies(Request $request) {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function authenticate(Request $request) {
    return $this->entityTypeManager->getStorage('user')->load(1);
  }

```

The idea being that with this module enabled, every page load considers the authenticated user to be user 1. In theory, I'd be logged in for ever!

However, after a few weeks of this working fine, all my form submissions broke! Every form submission fails with:

> The form has become outdated. Press the back button, copy any unsaved work in the form, and then reload the page

This turns out to be because CsrfTokenGenerator::validate() fails. Specifically, the $seed in this bit is just NULL:

```
  public function validate($token, $value = '') {
    $seed = $this->sessionMetadata->getCsrfTokenSeed();
    if (empty($seed)) {
      return FALSE;
    }

```

I presume it's because the session has expired in some way? The time this has taken to stop working is roughly the amount of time it would have taken the site to log me out automatically.

How can I fix this?

# Answer
> I presume it's because the session has expired in some way?

First you need to understand how this happens.

> ### Configuring Garbage Collection
>
> When a session opens, PHP will call the `gc` handler randomly according to the probability set by `session.gc_probability` / `session.gc_divisor`. For example if these were set to 5/100 respectively, it would mean a probability of 5%. Similarly, 3/4 would mean a 3 in 4 chance of being called, i.e. 75%.
>
> If the garbage collection handler is invoked, PHP will pass the value stored in the **php.ini** directive `session.gc_maxlifetime`. The meaning in this context is that any stored session that was saved more than `gc_maxlifetime` ago should be deleted. This allows one to expire records based on idle time.
>
> However, some operating systems (e.g. Debian) do their own session handling and set the `session.gc_probability` variable to 0 to stop PHP doing garbage collection. That's why Symfony now overwrites this value to 1.
>
> If you wish to use the original value set in your **php.ini**, add the following configuration:
>
> ```
> # config/packages/framework.yaml
> framework:
>     session:
>         gc_probability: null
>
> ```
>
> Source: Symphony's official docs on Configuring Sessions and Save Handlers

In Drupal 8 & 9 you can see these gc settings in default.services.yml

### Possible Solutions on how to stay logged in longer.

In /sites/default/**settings.php** uncomment

```
 if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
   include $app_root . '/' . $site_path . '/settings.local.php';
 }

```

then copy **/sites/example.settings.local.php** and rename to **/sites/default/settings.local.php**

Now you can use **/sites/development.services.yml** to override those settings, for example

(I used these numbers for testing so it logs me out after 2 seconds):

```
parameters:
  session.storage.options:
    gc_probability: 1
    gc_divisor: 1
    gc_maxlifetime: 2
    cookie_lifetime: 2

```

I tried setting `gc_probability` to `0` or `null`, which should stop it, but the `gc()` function still fired. Perhaps it's reading the value from php.ini

So alternatively you could set the `gc_maxlifetime` and `cookie_lifetime` to not expire decades from now. See set a cookie to never expire.
> 0 votes

---
Tags: authentication-authorization, sessions
---


# Question
Title: Drupal way of storing data related to a node
I want to store some data that is related to a node and trying to figure out the best way of doing it. For example, I send emails related to a node and I want to save details such as:

* To Email address
* Cc Email Addresses
* Date sent
* User
* Email type
* Other chosen email options etc

In the past I would use Paragraphs to have an unlimited field but this will, over time, grow to have a lot of entries. I'm also using Revisions on the node so I think this will slow everything down when saving the node.

My question is... should I create my own entity for this? One that doesn't have a page like a node does? Or is there a better way of storing the data? I could create a custom table, store it there, and maybe register that with Views but I would like to have the entity API available on the content and maybe add fields in future using the UI. Any ideas?

Is there a module similar to Paragraphs but is not a Entity Reference Revision type? Or is the Drupal way to create a custom entity in a module?

# Answer
Create a custom content entity with `entity_reference` fields relating each "email" entity to a node and a user.

The information you're saving is neither part of the node's content nor part of the node's metadata. It is metadata about an email that has been sent. Since the email records aren't related to any particular revision of the node, you want the email records to remain even if the node is reverted to a previous revision. So you shouldn't put the email records in a node field of any kind.

Creating a custom content entity is more useful than creating a custom table, because - as you have pointed out - you can make use of the built-in Entity API, which allows you to add field bundles, but also makes it easy to relate your records to node and user entities, and optionally do cleanup if those users or nodes are deleted. If you generate your custom entity using Drupal Console then it will work out of the box with views.
> 6 votes

---
Tags: 8, entities
---


# Question
Title: How do I run a BrowserTestBase functional test with blocks?
I have a module that defines a custom block and places it using a `block.block.block_name.yml` file that I generated by exporting the placement of the block on a dev site. I've unit-tested the block code, but now I want a functional test that will tell me whether the block is correctly placed and rendering to the right users;

```
<?php

namespace Drupal\Tests\my_module\Functional;

use Drupal\Tests\BrowserTestBase;
use Drupal\my_module\EnablerService;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\user\Entity\User;

/**
 * Main test class for the my_module module
 *
 * @group my_module
 */

class ImplementationTests extends BrowserTestBase {

  public $defaultTheme = 'bootstrap';

  /**
   * Modules to enable.
   *
   * @var array
   */

  public static $modules = ['block', 'node', 'my_module', 'user'];

  private NodeInterface $node;
  private User $user;

  # from https://www.drupal.org/project/bootstrap/issues/2860072#comment-12287718
  protected function getConfigSchemaExclusions() {
    return array_merge(parent::getConfigSchemaExclusions(), ['bootstrap.settings']);
  }
  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
  }

  /**
   * some test
   */
  public function test_nothing() {
    $this->assertTrue(true);
  }
}

```

However, when I run this, I get this error:

> Drupal\Tests\my\_module\Functional\ImplementationTests::test\_nothing Trying to access array offset on value of type null
>
> /opt/drupal/web/core/lib/Drupal/Core/Block/BlockPluginTrait.php:90 /opt/drupal/web/core/lib/Drupal/Core/Block/BlockPluginTrait.php:74 /opt/drupal/web/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php:85 /opt/drupal/web/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php:99 /opt/drupal/web/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php:55 /opt/drupal/web/core/modules/block/src/BlockPluginCollection.php:34 /opt/drupal/web/core/modules/block/src/Entity/Block.php:156 /opt/drupal/web/core/modules/block/src/Entity/Block.php:166 /opt/drupal/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:291 /opt/drupal/web/core/modules/block/src/Entity/Block.php:344 /opt/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:494 /opt/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:449 /opt/drupal/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:263 /opt/drupal/web/core/lib/Drupal/Core/Entity/EntityBase.php:339 /opt/drupal/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:591 /opt/drupal/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:373 /opt/drupal/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:248 /opt/drupal/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:152 /opt/drupal/web/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php:75 /opt/drupal/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:287 /opt/drupal/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83 /opt/drupal/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:464 /opt/drupal/web/core/tests/Drupal/Tests/BrowserTestBase.php:581 /opt/drupal/web/core/tests/Drupal/Tests/BrowserTestBase.php:400 /opt/drupal/web/modules/custom/implementations/tests/src/Functional/ImplementationTests.php:40 /opt/drupal/vendor/phpunit/phpunit/src/Framework/TestResult.php:685

Looking at the first file in the stack (`/opt/drupal/web/core/lib/Drupal/Core/Block/BlockPluginTrait.php:90`), I see this:

```
 80   /**
 81    * Returns generic default configuration for block plugins.
 82    *
 83    * @return array
 84    *   An associative array with the default configuration.
 85    */
 86   protected function baseConfigurationDefaults() {
 87     return [
 88       'id' => $this->getPluginId(),
 89       'label' => '',
 90       'provider' => $this->pluginDefinition['provider'],
 91       'label_display' => BlockPluginInterface::BLOCK_LABEL_VISIBLE,
 92     ];
 93   }

```

Here is the contents of my `block.block.my_block.yml` file:

```
langcode: en
status: true
dependencies:
  module:
    - node
  theme:
    - bootstrap
id: my_block
theme: bootstrap
region: content
weight: 10
provider: null
plugin: my_module_my_block
settings:
  id: my_module_my_block
  label: 'My Block'
  provider: null
  label_display: '0'
visibility:
  node_type:
    id: node_type
    bundles:
      idea: idea
    negate: false
    context_mapping:
      node: '@node.node_route_context:node'

```

My guess is that BrowserTestBase needs some additional code to properly set up the `blocks` module, but I'm not sure what else I need to do. Any ideas?

# Answer
In `setUp()` you need `$this->drupalPlaceBlock('block_name');`

Possibly other things are wrong - you didn't show the code where the failure occurs so it's hard to say.
> -1 votes

---
Tags: blocks, testing, 9
---


# Question
Title: How to send e-mail in users selected languages
* I have created two users and my site supported two languages(English,Spanish).
* In every 5 hours CRON will be run,I have wrote a custom module and every CRON run users are getting Emails thats fine.
* But here is the problem is Emails are not sended to users prefered languages,it takes admin default language and sended to users.

I have installled multilingual module also.

I want Emails should be in users prefered languages only.

**Code:-**

```
function sendmail($from, $to, $firstname, $message, $user,$language) {
  $module = "my_mail_example";
  $key = "mail_example";
  $language = user_preferred_language();
  $send = TRUE;
  $params = array(
    'body' => $message,
    'subject' => 'Hello from Bright Ideas'
  );
  $result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
  $current_messages = $user -> field_reminder_messages_received[LANGUAGE_NONE][0]['value'];
  $updated_messages = $current_messages.'\r\n'.$logmessage;
  $edit = array(
      'field_reminder_messages_received' => array(LANGUAGE_NONE => array(0 => array('value' => $updated_messages, ), ), ),
    );
  user_save($user, $edit);
}

```

# Answer
Cron runs as the anonymous user, so any emails sent by cron will use the site's default language.

Your code snippet has the following:

```
 $language = user_preferred_language();

```

This is wrong. It will get the preferred language of the anonymous user, not the user you're sending the mail to.

Instead: figure out the recipient's preferred language:

```
$userobj = user_load($user);
$language = user_preferred_language($userobj);

```

Now, you can send mail with the correct language:

```
$result = drupal_mail($module, $key, $to, $language, $params, $from, $send);

```
> 2 votes

# Answer
You are passing the receiver email in the $to variable, so...

```
//here you load the user that has the $to email
$receiver = user_load_by_mail($to);

//here you have the preferred language of that user
$langcode = $receiver->getPreferredLangcode();

```

this worked for me.
> 0 votes

---
Tags: 7, emails
---


# Question
Title: How State is specific to the specific environment, when its actually pushed to all environments with DB sync?
I am working with a Drupal 8 setup when production, test and development environments which periodically sync database. In Drupal 7 it was easy to override the $conf variables in `settings.php` to force a site in maintenance mode. However, in Drupal 8, the maintenance\_mode is not a configuration anymore, but a state that is not possible to override from settings.php, so we have to use additional `drush` command after each sync to put one of the environments to maintenance mode.

And I am confused how come State API documentation asserts it's environment-specific, when in fact, it gets synced together with database and it is not easy to keep environment-specific settings using State API.

On the contrary, $config is easy to override in `settings.php` (which is excluded during sync), so it does provide easy way of setting environment-specific configurations.

# Answer
> 3 votes
When you copy your development/testing database to your production database, you're effectively replacing your production site's state with your development site's state. Therefore if you put your production site in maintenance mode, then import a database that says the site is not in maintenance mode, then your site will stop being in maintenance mode.

Conceptually, state is specific to an environment, so long as you aren't copying your database when you push changes from development to production.

Your solution may be to avoid doing these database imports altogether. If you are just making configuration changes on your local development site and just need to push those, you can export the site's configuration to code, commit it to version control, push that config to production and then import it. (See https://www.drupal.org/docs/configuration-management for info.)

If you are creating content in the local development environment that you need to push to production, then you may want to look at using the Migrate API.

If you absolutely must push these database updates but want the production site to remain in maintenance mode when you do it, then you'll need to put your development site into maintenance mode before copying its database to production.

---
Tags: 8
---


title: Custom template for 404 error pages

text:
# Question
Title: Custom template for 404 error pages
A quick noob question here! How to set a theme to use a custom template for 404 error pages instead of using page.tpl ?

# Answer
> 10 votes
Follow these steps:

1. Make a new page using the Panels module (Empty page or put in it any content)
2. In admin/config/system/site-information set Default 404 (not found) page to your new page
3. Override the template file for that page (page--error.tpl.php)
4. Remove all the regions you don't need and put your code

# Answer
> 27 votes
Yet another solution from this discussion that works without panels or other custom modules.

In your theme folder locate `template.php` and write this code. Replace `YOURTHEME` with the name of your theme:

```
function YOURTHEME_preprocess_page(&$vars) {
  $header = drupal_get_http_header('status');
  if ($header == '404 Not Found') {
    $vars['theme_hook_suggestions'][] = 'page__404';
  }
}

```

Whenever 404 occurs your `page--404.tpl.php` will be used. Remember to put "--" not "\__" in your template file name.

# Answer
> 3 votes
If you want to have a customized 404 page that doesn't involve creating a page (node), use the customerror module.

If you have a 404 page in Drupal, then it's going to show up in search results, and/or your Views listings.

When using the customerror module, you can override the template by creating a page--customerror.tpl.php in your theme folder. Remember also to flush your cache after you've created new template file.

# Answer
> 1 votes
These days you get a `page--404.html.tpl` and a `page--4xx.html.tpl` theme suggestion out of the box.

# Answer
> 0 votes
Without assuming any convention which may exist in your theme base, the question is finally how can I get to know for sure what template file to use ...

Here are the steps :

1. Create a basic base and call it as you want.
2. Assign that page to the 404 response admin/config/system/site-information
3. Enable the theme\_debug mode.
4. Type a stupid url in your address bar.
5. You arrive on your page initially created
6. Look at the source and the templates suggestion, you will get something like :
7. That's straight forward, no preprocess file or template.php to modify.

Myself I have choseen the one marked by a x, as I wanted something naked with afull frame pic and just a link to back.

---
Tags: theming
---


# Question
Title: Change field settings for text field from plain to formatted while data exists
anyone know of a quick example of how to change the field settings for a text area (plain) to formatted and set the input formatter (or maybe it will use default)? Will this require a resave of all the data or can it just be changed for the entity type? I currently have a lot of existing data on this site.

The field is currently stored as the type `string`, Text (plain). I need to change it to `text_long`, Text (formatted, long).

Thanks

# Answer
> 4 votes
Attention for Drupal 8:

You need to update at least 3 or 4 yml files

field.field.node.page.field\_description.yml

```
(same change)

```

field.storage.node.field\_description.yml

```
--- a/config/default/field.storage.node.field_description.yml
+++ b/config/default/field.storage.node.field_description.yml
@@ -4,13 +4,13 @@
 dependencies:
   module:
     - node
+    - text
 id: node.field_description
 field_name: field_description
 entity_type: node
-type: string_long
-settings:
-  case_sensitive: false
-module: core
+type: text_long
+settings: {  }
+module: text
 locked: false
 cardinality: 1
 translatable: true

```

core.entity\_form\_display.node.page.default.yml

```
-type: string_textarea
+type: text_textarea

```

core.entity\_view\_display.node.page.default.yml

```
-type: basic_string
+type: text_default

```

Maybe the last 2 ones you can deal with those changes on UI(go to each teaser and save). But I did in config folder.

# Answer
> 1 votes
Oh wow, I just tried something in hopes of it being easy and it was a breeze!...

I already have all my config exported to code so I compared a `text_long` field to my current `string_long` field and just merged the differences, it worked beautifully. Something like the changes in the following example patch:

```
--- config/prod/field.field.node.page.field_description.yml (revision 3ef14eada9090087d33a10ec532732e515fef151)
+++ config/prod/field.field.node.page.field_description.yml (revision )
@@ -5,6 +5,8 @@
   config:
     - field.storage.node.field_description
     - node.type.page
+  module:
+    - text
 id: node.researcher.field_description
 field_name: field_description
 entity_type: node
@@ -16,4 +18,4 @@
 default_value: {  }
 default_value_callback: ''
 settings: {  }
-field_type: string_long
+field_type: text_long

```

imported the changed config et voila! Just beautiful.

# Answer
> 0 votes
You can use the module Druidfire by CHX.

https://gitlab.com/chx\_/druidfire

Drush 10 command: `drush druidfire:string2formatted entity_type field_name`

It's not hosted on drupal.org and is unlikely to be. Use with caution.

Example update hook for your `module_name.install` file:

```
/**
 * Change field my_field to formatted text.
 */
function module_namee_update_8001() {
  \Drupal::service('druidfire')->kaboom('string2formatted', 'node', 'field_my_field');
}

```

---
Tags: 8, entities, input-formats
---


title: Filter views for same taxonomy term

text:
# Question
Title: Filter views for same taxonomy term
I am using D8. I have two views (articles and videos) sharing the same taxonomy (segments). How can I filter the views based on the view type? For example, if I am on the articles page, I would need to filter only articles when I select any of the taxonomy term. Right now, by default both articles and videos linked to the taxonomy term are shown.

I am using Taxonomy Menu to display the terms in a block.

# Answer
> 0 votes
Term pages that list all the content that has been tagged with that term are built with "Taxonomy term" Views. You can edit that View to change what those pages show (`/admin/structure/views/view/taxonomy_term`).

---

## Filter

The easiest change for you would be to add the `Content type` Filter (from the "Content" Category) to your Views so your visitors can choose manually which types to see listed.

Expose it to your visitors (this option is in the Filter Settings). This will show a filter at the top of each Taxonomy term page that will allow visitors to limit the content to only the chosen content types.

I recommend cloning (duplicating) the Taxonomy term Views, disabling the original and working on the duplicate so you can always refer back to it.

---

## Contextual Filter

For a more automatic solution you can add a Contextual filter instead of a regular one (Contextuals are under Advanced View settings) to filter the results, and build a new Views Display to list the new taxonomy term links that are sensitive to the types of content.

There is already the "Has taxonomy term" contextual filter present there, you need to keep it.

Add another Contextual filter, named `Content type`, configure it with these options:
`When the filter value is NOT in the URL`
**Hide view**
`When the filter value IS in the URL or a default is provided`
**Specify validation criteria**
`Validator` **Content type**
`Case in path` **Lower case**
`More`
**Transform spaces to dashes in URL**

Rearrange the Contextuals so the type one comes up first, and the "Has taxonomy term ID" comes second.

Edit the "Has taxonomy term ID" Contextual filter and change its option under `When the filter value is NOT in the URL` from "Hide view" to "Display all results for the specified field".

This will enable you to add the content type into your path to have it automatically filtered by the type: `/taxonomy/term/[ContentType]/[TID]`, for example: `/taxonomy/term/article/5`.

There is also an option to override the Title if you need to correct it to name only the content types filtered out.

To test that your Contextual filter is working you can enter the argument for it in the `Preview with contextual filters:` field and hit the `Update preview` button if you don't have it set automatically. To view all the results without filtering simply delete the argument or enter `all` at the Preview or at the end of your path. In this case Views takes 2 arguments so you need to include both of them, separated by `/`, e.g.: `article/5`, `article/all`.

---

## List all links

You can now use Views to build a list of all links to your terms for each content type. It can be a Block Display where you override the "Has taxonomy term ID" to display a Summary, and adjust the Content type Contextual to provide a Fixed Default value, add another Display for your second content type (it doesn't have to be automatic since you only have two types).

There is more than one way of doing this, it's out of scope of this question, but it gives you enough to know which direction to take and learn more.

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


# Question
Title: How can i remove title requirement for content type
For example i have content type `article` i need to remove requirement for title, right now its a `Node module element` and i can not edit it. I found module title but when i installed id and tried to change title, my site crashed.

Is there any solution to achieve this?

Should i remove title on content type edit page and replace it with editable field?

*UPDATE:*

Some of you maybe do not understand me right). So i have content type `Answer` and this c.type has two fields `title` and `body`. When someone want to `answer` atm he needs to fill `title` field every time he wants to answer, but i need to give user a choice to just fill only `body` field OR `body` and `title` if user want to fill the `title`. The title field should be displayed on node edit every time!

So only way i see viable is to create new `field` and hide `title` with automatic-node-title module...

# Answer
I dont' think you can entirely remove the title from the nodes but you may hide it and automatically populate it, as is below:

Auto node titles and Title override

I have used the first one before.
> 1 votes

# Answer
How to hide or remove title for content type.

1 Install Automatic Entity Label

2 Install Token

**For Content Type News** go to

**D7** admin/structure/types/manage/news/auto\_label

**D8/9** admin/structure/types/manage/news/auto-label

Then select an option that fit your solution, in my case I selected: **Automatically generate the label and hide the label field**

In the **Pattern for the label** enter field token to replace the **Title**.

in my case I entered `[node:filed_slogan]`.
> 0 votes

---
Tags: 7, nodes
---


# Question
Title: How to properly manage field types for a content type created by a module?
I'm a bit confused about two different errors I get, which seem to contradict each other. I guess I didn't register my field types properly. The first one appears when I try to uninstall my module.

```
Drupal\Core\Field\FieldException: Attempt to create a field field_example that does not exist on entity type node. in Drupal\field\Entity\FieldConfig->getFieldStorageDefinition() (line 312 of core\modules\field\src\Entity\FieldConfig.php).

```

The second one appears as an error message within the UI when I try to fix it by introducing another module which should only create the field type.

```
Unable to install Helper, field.field.node.content_type_example.field_example already exists in active configuration.

```

In general, the module calls an external API and fetches data which is then used to create nodes with several fields. These are defined inside the `config/install` directory. Furthermore, inside `src/Plugin/Field` there are `FieldType`, `FieldFormatter` and `FieldWidget` classes, more or less as described here.

I used this module when I tried to fix the first error without a helper module. With its help, I removed the field types created by my module in the first place. Unfortunately, I don't know a lot about drush, which seems to be capable of solving the issue. On the other hand, it would be great if it was possible to "reset" the content type and the field types programmatically whenever the module is installed or uninstalled. So far, I tried the following code, without much luck:

```
<?php
// mymodule.install file
use \Drupal\field\Entity\FieldStorageConfig;

function mymodule_install() {
  if (FieldStorageConfig::loadByName('node', 'field_example')) {
    FieldStorageConfig::loadByName('node', 'field_example')->delete();
  }
}

```

Does someone know how I can fix the error and how I should manage these fields in the future? Thanks!

# Answer
> 5 votes
To properly manage fields added by a module, so that a field is added and removed when the module is installed and uninstalled, add an enforced dependency for your own module to the yaml file:

*/config/install/field.storage.node.field\_example.yml*

```
...
dependencies:
  enforced:
    module:
      - mymodule

```

See https://www.drupal.org/node/2404447

---
Tags: nodes, 9
---


# Question
Title: Getting Bootstrap Carousel to set Active class?
I have a Drupal 7 site that has 2 Bootstrap carousels.

1. One that rotates automatically and takes up the width of the page.
2. One that has 3 smaller items and only when the page is narrowed (e.g. on mobile device) does it need to rotate.

The first carousel works fine.

The second carousel does rotate until I manually add the "Active" to the class. Once I do it then begins to auto-rotate between the items.

```
<div id="carousel-posts" class="carousel slide carousel-posts" data-ride="carousel">
  <!-- Carousel items -->
  <div class="carousel-inner">
    <div class="item ">...</div>
    <div class="item ">...</div>
    <div class="item active">...</div>
    <div class="item ">...</div>
  </div>
</div>

```

I am trying to figure out how to set one of the items as " active" when the page loads so that if the page is on mobile or resized to small enough it begins to auto-rotate.

I use nodequeue to order the items and bootstrap view to lay them out.

Thank you for any direction you can point me to.

# Answer
> Looks like a bug occurs on this line for the 2nd Carousel where $key never equals $first\_key – No Sssweat

That's exactly the answer!

```
  <!-- Carousel items -->
  <div class="carousel-inner" role="listbox">
    <?php foreach ($rows as $key => $row): ?>
      <div class="item <?php if ($key == $first_key) {print 'active';
     } ?>">
        <?php print $row ?>
      </div>
    <?php endforeach ?>
  </div>

```

Whoever set up the site or theme commented out the part about printing "active" in the class list. Probably so it wouldn't auto-rotate, but unfortunately it also made it become hidden when the screen is made narrow.
> 0 votes

---
Tags: 7, bootstrap-theme
---


title: How to delete a field programmatically

text:
# Question
Title: How to delete a field programmatically
I've got a service managing the install/uninstall of my module.

Install create a field attached to the user but I am not able to delete it during the uninstall process...

**stacko.services.yml**

```
services:
  stacko.module_installer:
    class: Drupal\stacko\ModuleInstaller
    arguments:
      - '@entity_type.manager'
    tags:
      - { name: service_collector, tag: 'module_install.uninstall_validator', call: addUninstallValidator }

```

**stacko.install**

```
/**
 * Implements hook_install().
 */
function stacko_install() {
  $module_installer = Drupal::service('stacko.module_installer');
  $module_installer->install([]);
}

/**
 * Implements hook_uninstall().
 */
function stacko_uninstall() {
  $module_installer = Drupal::service('stacko.module_installer');
  $module_installer->uninstall([]);
}

```

**src/ModuleInstaller.php**

```
namespace Drupal\stacko;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleInstallerInterface;
use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
use Drupal\field\Entity\FieldStorageConfig;

/**
 * Module installer.
 */
class ModuleInstaller implements ModuleInstallerInterface {

  /**
   * Field storage config manager.
   *
   * @var \Drupal\field\FieldStorageConfigStorage
   */
  protected $fieldStorageConfigManager;

  /**
   * Field config manager.
   *
   * @var \Drupal\field\FieldConfigInterface
   */
  protected $fieldConfigManager;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entityt type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->fieldStorageConfigManager = $entity_type_manager->getStorage('field_storage_config');
    $this->fieldConfigManager = $entity_type_manager->getStorage('field_config');
  }

  /**
   * {@inheritdoc}
   */
  public function install(array $module_list, $enable_dependencies = TRUE) {
    $this->createFields();
  }

  /**
   * {@inheritdoc}
   */
  public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    $this->deleteFields();
  }

  /**
   * {@inheritdoc}
   */
  public function addUninstallValidator(ModuleUninstallValidatorInterface $uninstall_validator) {
  }

  /**
   * {@inheritdoc}
   */
  public function validateUninstall(array $module_list) {
  }

  /**
   * Create all fields.
   */
  protected function createFields() {
    $this->createStackoField();
  }

  /**
   * Create Stacko field.
   */
  protected function createStackoField() {
    $this->createStackoFieldStorage();
    $this->createStackoFieldInstance();
  }

  /**
   * Delete all fields.
   */
  protected function deleteFields() {
    $this->deleteStackoField();
  }

  /**
   * Create Stacko field storage.
   */
  protected function createStackoFieldStorage() {
    try {
      $this->fieldStorageConfigManager->create([
        'field_name' => 'field_stacko',
        'entity_type' => 'user',
        'type' => 'text',
        'cardinality' => 1,
        'locked' => FALSE,
        'indexes' => [],
        'settings' => [
          'max_length' => 14,
          'is_ascii' => false,
          'case_sensitive' => false,
        ],
      ])->save();
    }
    catch (\Exception $e) {
      if (PHP_SAPI === 'cli') {
        drush_print_r('Either the field_stacko storage already exists or an error occured and it has not been created.');
      }
    }
  }

  /**
   * Create Stacko field instance.
   */
  protected function createStackoFieldInstance() {
    try {
      $this->fieldConfigManager->create([
        'field_name' => 'field_stacko',
        'entity_type' => 'user',
        'bundle' => 'user',
        'label' => 'The stacko',
        'required' => FALSE,
        'settings' => [],
      ])->save();
    }
    catch (\Exception $e) {
      if (PHP_SAPI === 'cli') {
        drush_print_r('Either the field_stacko instance already exists or an error occured and it has not been created.');
      }
    }
  }

  /**
   * Delete Stacko field storage.
   */
  protected function deleteStackoField() {
    // Leads to Error: Call to undefined method Drupal\field\FieldStorageConfigStorage::loadByName()
    /* if ($this->fieldStorageConfigManager->loadByName('user', 'field_stacko')) {
      $field_storage->delete();
    } */
    // Doesn't load the field storage | doesn't delete the field.
    /* if ($field_storage = $this->fieldStorageConfigManager->loadByProperties([
      'entity_type' => 'user',
      'field_name' => 'field_stacko',
    ])) {
      kint('test 1');
      $field_storage->delete();
    }
    kint('test 2'); */
    // Doesn't load the field storage | doesn't delete the field.
    if ($field_storage = FieldStorageConfig::loadByName('user', 'field_stacko')) {
      kint('test 1');
      $field_storage->delete();
    }
    kint('test 2');
  }

}

```

While running `deleteStackoField()` I only have the 'test 2' message. As it's unable to load the field storage, the field is not deleted.

So I am wondering how can I properly delete my field programmatically ?

# Answer
So I followed @4k4 advices.

Best way to create and delete a field during install/uninstall process is to add the field storage and config yml files to the config/install folder of the module and enforce a dependency to the module.

**config/install/field.field.user.user.field\_stacko.yml**

```
langcode: fr
status: true
dependencies:
  config:
    - field.storage.user.field_stacko
  module:
    - text
    - user
  enforced:
    module:
      - stacko
id: user.user.field_stacko
field_name: field_stacko
entity_type: user
bundle: user
label: 'The stacko'
description: ''
required: false
translatable: true
default_value: {  }
default_value_callback: ''
settings: {  }
field_type: text

```

**config/install/field.storage.user.field\_stacko.yml**

```
langcode: fr
status: true
dependencies:
  module:
    - text
    - user
  enforced:
    module:
      - stacko
id: user.field_stacko
field_name: field_stacko
entity_type: user
type: text
settings:
  max_length: 14
module: text
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

```
> 1 votes

---
Tags: 8, users
---


# Question
Title: How to display default drupal search block in twig template
In twig\_tweak module before version 2 (for Drupal 8) I could place the following code in my page twig template and it would work:

```
{{ drupal_block('exposedformsearch_contentpage_1') }}

```

This would display put the default site search box.

After upgrading to version 2, this doesn't work anymore and see the following message on the page:

```
This block is broken or missing. You may be missing content or you might need to enable the original module.

```

I tried using the command:

```
{{ drupal_block('search_form_block') }}

```

That displays the same error message.

Does anyone know what the the correct call is? I can't seem to find any documentation anywhere as to what the replacement call should be.

Thanks.

# Answer
> 0 votes
Ok I have found the solution after playing around for a bit. The correct call now is:

```
{{ drupal_entity('block', 'exposedformsearch_contentpage_1') }}

```

---
Tags: 8, theming, search
---


# Question
Title: Adding attributes to a link to an uploaded file
I have been asked to add target="\_blank" to the links that are produced when a user uploads a file on a Drupal 8 site.

The field type is "File". Multiple uploads are allowed.

Twig debug shows me that the field is being produced by the core template "file-link.html.twig". The entire uncommented contents of that template are:

```
<span{{ attributes }}>{{ link }}</span>
{% if file_size %}
  {# @todo remove class before Drupal 9.0.0 #}
  <span class="file-size">({{ file_size }})</span>
{% endif %}

```

I brought that template into my custom theme and tried to add the attribute to the link. I thought I'd be editing the {{ link }} part of the template, changing it to attach attributes. I did variations of this:

{{ link(item.title, item.url, attributes.setAttribute('target','\_blank')) }}

Every syntax I tried produced a fatal PHP error. Thinking I was doing the attribute syntax wrong, I tested by simply trying to add a single class.

```
{{ link(item.title, item.url, { 'class': ['bananas'] }) }}

```

That was still a white screen of death, so I guess I can't use that syntax on the {{ link }} field in my file-link template.

I've been googling my eyeballs out of my head. I found this cool idea:

```
{% for item in items %}
  {{ item.content|merge({'#attributes': {'class': ['button', 'button--arrow', 'button--centered']}}) }}
{% endfor %}

```

so I adapted it for my field.html.twig template like so, changing this part:

```
{% for item in items %}
    <div{{ item.attributes }}>{{ item.content }}</div>
{% endfor %}

```

to this:

```
{% for item in items %}
      <div{{ item.attributes }}>{{ item.content|merge({'#attributes': {'target': ['_blank']}}) }}</div>
{% endfor %}

```

And while at least the page loaded and didn't have a fatal error, the target attribute did not appear on the link.

Does anyone have any advice for me getting an attribute onto a file upload link? Almost everything I've found has to do with the link field, not the file upload field. Thanks for your time.

# Answer
**file-link.html.twig**

```
<span{{ attributes }}>{{ link|merge({'#attributes': {'target': '_blank'}}) }}</span>
{% if file_size %}
  {# @todo remove class before Drupal 9.0.0 #}
  <span class="file-size">({{ file_size }})</span>
{% endif %}

```

---

Alternatively, you can also solve this via preprocess.

**mytheme.theme**

```
/**
 * Implements hook_preprocess_HOOK().
 */
function mytheme_preprocess_file_link(&$variables) {
  $variables['link']['#url']->setOption('attributes', ['target' => '_blank']);
}

```
> 7 votes

---
Tags: 8, theming
---


title: Webform export to other website or pc

text:
# Question
Title: Webform export to other website or pc
I have tested a webform module on my localhost and because I have created a fully-functional and complex form (using conditional logic, dropdown menus, radio buttons, etc.) I don't want to loose, I want to export this form to a completely different computer or website via USB stick (for example).

Is there a way I can export my webform with all the settings I have created, without loosing anything ?

I have tried to export **single item** via `Home >> Administration >> Configuration >> Development >> Synchronize` and then import those data to other computer, but did not suceeded.

# Answer
Drupal in D8 added UUID to identify & differentiate one Drupal from another and was also added so people don't accidentally add config to the wrong site.

So you already got an export from site A.

Now on site B do an export for an existing webform, like Contact (which was created by default when you installed webform) and copy its UUID value.

Now use this UUID and replace site A's export UUID with it.

### Important

If this is a one time thing, the above is alright. But if you're going to constantly export config from site A to site B multiple times, then perhaps chaging site's B UUID to A's (so they are identical) is the better solution, see How can I import the configuration on a different site?
> 1 votes

---
Tags: webforms, importing-exporting
---


# Question
Title: Date field as dynamic source for contextual filter
I need a views block with a contextual date filter, based upon a date field of the currently viewed node.

What I've got so far:

1. I already have created my base view with base filters and sorting.
2. I've added a relation to the current node ("Get the actual content from a content revision")
3. I've added a contextual filter Content ID, using Content ID from URL as default value

But I don't want the current node in my views block, I need the next two nodes in my views block, and I don't know how to do this part of the contextual filter:

`views_node.field_date > contextual_node.field_date`

Concrete use case:

I'm displaying the full view of "event node A", and on that full view of node A, I want to embed a views block, showing the next two "event nodes B and C" after the date of event node A (for selecting and ordering nodes B and C I want something similar to this pseudo-query: `select * from view_nodes where view_nodes.field_mydate > context_node.field_mydate order by view_nodes.field_mydate limit 2`)

# Answer
> 2 votes
Use **hook\_views\_query\_alter** to alter query filter based on current node id or created date of node and put limit 2.

*Where clause will be Like:*

1. nid \> current\_nid
2. created date \> current node created date (this may create issue if we have imported node in bulk)

**Also we can do it from contextual filter as well** just add contextual filter for current node id, greater than current node id.

# Answer
> 0 votes
Would this not work with tokens? It provides the created-date for the current page/node. Then create a view showing nodes sorted by date. Add a filter where date is \>= the node date or \<= the node date. For the pager, chose show 1 and offset 1, so that only the "prev" or "next" item displays.

To filter starting from a certain date you'd use the token value. https://www.drupal.org/project/token

Another approach is setting filter values programmatically.There are some examples here: How to get contextual filter in hook\_views\_query\_alter or hook\_views\_pre\_execute?

Pseudo code:

```
$node = \Drupal::routeMatch()->getParameter('node');
$view = Views::getView('test_view');

if (is_object($view) && is_object($node)) {
  $view->setArguments($args);
  $view->setDisplay('block');

  // Filter is applied by reference (no need for setHandler()).
  $filter = $view->display_handler->getHandler('filter', 'created');
  $filter->value['value'] = \Drupal::service('date.formatter')->format($node->created->value, 'custom', 'Y-m-d H:i:s');
  // Good to change options too.
  $filter->options['value'] = $filter->value;

  $view->preExecute();
  $view->execute();

  print $view->render();
}

```

# Answer
> 0 votes
For my use case, I want to filter pages than are older than current page.

Contextual filter cannot work as we don't have access to the operator : @see Is there a specific reason that views contextual filters lack the ability to specify the operator?

So I have for my work around:

1x contextual filter:

* Use content Id from URL + content validator content (exclude from results)

1x normal views filter:

* filter by created date is less than current with dummy value "2020-10-20 00:00:00"

On the block layout -\> block settings I use "Content: ID Node from ID".

Then in the theme layer to override "2020-10-20 00:00:00" with node created date:

```

use Drupal\Core\Plugin\ContextAwarePluginInterface;

/**
 * Implements hook_preprocess_block__views_block__VIEW_ID__DISPLAY_ID().
 */
function mytheme_preprocess_block__views_block__alumni_hub_previous_lessons_block_1(&$variables, $hook) {
  if (!isset($variables['elements']['#plugin_id'])
    || !isset($variables['elements']['#configuration'])) {
    return;
  }
  $block_manager = \Drupal::service('plugin.manager.block');
  // Plugin ID format is: views_block:VIEW_ID-DISPLAY_ID.
  $plugin_block = $block_manager->createInstance($variables['elements']['#plugin_id'], $variables['elements']['#configuration']);
  // Inject runtime contexts.
  if ($plugin_block instanceof ContextAwarePluginInterface) {
    $contexts = \Drupal::service('context.repository')->getRuntimeContexts($plugin_block->getContextMapping());
    \Drupal::service('context.handler')->applyContextMapping($plugin_block, $contexts);
    // Get the node entity from the contextual value now.
    $contextual_values = $plugin_block->getContextValues();
    if (isset($contextual_values['nid'])
      && $contextual_values['nid']->hasField('created')
      && !$contextual_values['nid']->get('created')->isEmpty()) {

      $date_timestamp = $contextual_values['nid']->created->value;
      $plugin_view = $plugin_block->getViewExecutable();
      $filter = $plugin_view->display_handler->getHandler('filter', 'created');
      // Actually line that changes stuff.
      // Set filter to show nodes earlier than current ndoe.
      $filter->value['value'] = \Drupal::service('date.formatter')->format($date_timestamp, 'custom', 'Y-m-d H:i:s');
      // Good to change options too.
      $filter->options['value'] = $filter->value;
      // Override render array.
      $variables['content'] = $plugin_block->build();
    }
  }
}

```

---
Tags: views, 8
---


# Question
Title: How do I disable the default node creation form for a particular node type?
I have a node type `recipe`, which should only ever be created via a custom route that causes it to be linked to a parent food type, ie. if the user visits `node/add/recipe/1` they will see a `recipe` creation form that is linked to node `1` of type `food`.

Now I want to disable the `/node/add/recipe` route and prevent the `recipe` node from appearing on `node/add`. What's the best way to do this?

Note that this is *not* just a permissions issue - with my module it simply doesn't make sense for a `recipe` type to be created without a `food` that is linked to it, so visiting the `node/add/recipe` page simply doesn't make sense, even for an administrator.

# Answer
> 3 votes
A different approach would be to deny access by throwing an exception, which also affects admins:

```
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_node_recipe_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  throw new AccessDeniedHttpException();
}

```

The Form ID consists of ENTITY\_TYPE\_BUNDLE\_FORM\_MODE\_form. This assumes you use for your specific recipe form a different form mode. If not, you can check the reference field value in `$form_state->getFormObject()->getEntity()` before throwing the exception.

By the way, the hook name doesn't contain a form mode because nodes use the form mode `default` for the add form, which is omitted in the Form ID. The node edit form for example has the form mode `edit`, so the form alter hook would then be named `mymodule_form_node_recipe_edit_form_alter`.

Since this approach is not based on entity access permissions it doesn't remove the link from the node add list. You can do this in a separate hook:

```
/**
 * Implements hook_preprocess_HOOK() for list of available node type templates
 */
function mymodule_preprocess_node_add_list(&$variables) {
  unset($variables['content']['recipe']);
  unset($variables['types']['recipe']);
}

```

# Answer
> 3 votes
You need to create a RouteSubscriber service to override the default behavior to access this page (flush the cache to use it).

Denying the access this way will automatically remove the links to add this type of nodes.

**mymodule.services**

```
services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\MymoduleRouteSubscriber
    tags:
      - { name: event_subscriber, priority: 1 }

```

**src/Routing/MymoduleRouteSubscriber.php**

```
<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Custom route subscriber.
 */
class MymoduleRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('node.add')) {
      $requirements = $route->getRequirements();
      $requirements['_custom_access'] = '\Drupal\mymodule\Access\MymoduleNodeAddAccessCheck::access';
      $route->setRequirements($requirements);
    }
  }

}

```

**src/mymodule/Access/MymoduleNodeAddAccessCheck.php**

```
<?php

namespace Drupal\mymodule\Access;

use Drupal\Core\Access\AccessCheckInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\Access\NodeAddAccessCheck;
use Drupal\node\NodeTypeInterface;
use Symfony\Component\Routing\Route;

/**
 * Custom access check for /node/add route.
 */
class MymoduleNodeAddAccessCheck implements AccessCheckInterface {

  /**
   * {@inheritdoc}
   */
  public function applies(Route $route) {
    return NULL;
  }

  /**
   * Checks access to the node add page for the node type.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The currently logged in account.
   * @param \Drupal\node\NodeTypeInterface $node_type
   *   (optional) The node type. If not specified, access is allowed if there
   *   exists at least one node type for which the user may create a node.
   *
   * @return string
   *   A \Drupal\Core\Access\AccessInterface constant value.
   */
  public function access(AccountInterface $account, NodeTypeInterface $node_type = NULL) {
    if ($node_type == 'recipe') {
      return AccessResult::forbidden();
    }
    // Else call the normal access check.
    return NodeAddAccessCheck::access($account, $node_type);
  }

}

```

---
Tags: 8
---


# Question
Title: How can I add a filter to an export display?
I have a view "Nearest Dealers" that lists all the near dealers. There are two displays - `Page & REST Export`. I've added a filter(exposed to visitors) that lets customer search dealers based on current location and distance(eg: 10km radius). Filter works perfectly, but I want to show the same filtered results in REST Export display for the same view. Is it possible to do so because I have no clue how to make this work. Or is there any way to add the same filter for the REST Export display ?

# Answer
> 2 votes
> is there any way to add the same filter for the REST Export display ?

On your regular View page, apply filter for something, and you'll see a URL query gets appended to your URL. For example, when I'm filtering by content type, for mine, I see:

mysite.com/page-view`?title=&type=article&status=All&langcode=All` (This is based on the view filters I have).

Then all you have to do is append this query to your REST export URL.

mysite.com/rest-export`?title=&type=article&status=All&langcode=All` (Assuming you have the same filters as your page view, they should've been added by default when you added the REST view).

You'll need to create documentation for this. So people that are using your API know what parameter names & values are accepted.

---
Tags: views, 8
---


# Question
Title: Views Accordion to be accessible by keyboard
I need the Views Accordion module in Drupal 7 and what is in it to be accessible by the keyboard. When you are tabbing, it skips it completely. Also the screen reader does not recognize the closed items.

Anything I can modify to achieve this?

# Answer
iput this in a block

```
<script type="text/javascript">
(function ($) {
  $(document).ready(function(){
$('a')

 .each(function(){ // loop through all matched elements

  $(this).removeAttr("tabindex");

});

});

})(jQuery);
</script>

```
> 1 votes

# Answer
The accordion is not accessible because it uses an extremely old version of Jquery UI that is included in Drupal core. The latest version of JqueryUI fixes several accessibility issues.

You need to

* Install the v3 series of Jquery update module. Unfortunately the jquery update module has at the moment still a very old version of JQueryUI (but there are some issues working on it)
* Until jquery update offers a recent version of JQueryUI you need to patch the module so you connect to the CDN of the latest JQueryUI version, see this issue: in jquery\_update.module around line 529, just change the number of the latest version you want to use (see https://code.jquery.com/ui/). Depending on what of JQueryUI you are using you might also take an older version if you have issues.

```
 case 'google':
   $cdn = '//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui' . $min . '.js';
   ...............

 case 'microsoft':
   $cdn = '//ajax.aspnetcdn.com/ajax/jquery.ui/1.12.1/jquery-ui' . $min . '.js';
   ...............

 case 'jquery':
   $cdn = '//code.jquery.com/ui/1.12.1/jquery-ui' . $min . '.js';
   ...............

```
* Then go to /admin/config/development/jquery\_update and select to use the CDN
* Clear caches
> 0 votes

---
Tags: 7, views, navigation
---


# Question
Title: How can I link the file name to the file?
I created a content type with a "file" *field type*. This to upload a pdf file. Now I want to create a link to open that specific file, in my twig.

If I do this : `<div>{{content.field_menukaart}}</div>`, it opens my file correctly. But I want another link text other than my filename. For example "open here".

This is where I get stuck. How could I do this ?

This is not working : `<div><a href="{{content.field_menukaart}}">open here</a></div>`

Thank you for your help, Basiel

# Answer
You can solve by implementing a preprocess function

/themes/mytheme/**mytheme.theme**

```
<?php

/**
 * Implements hook_preprocess_HOOK().
 */
function mytheme_preprocess_file_link(&$variables) {
  $variables['link']['#title'] = t('Open Here'); // change title
  $variables['link']['#url']->setOption('attributes', ['target' => '_blank']); // open in a new browser tab
}

```

Rename `mytheme` to your actual theme name and clear/flush caches so hook gets picked up.
> 0 votes

---
Tags: 8, theming, files
---


# Question
Title: Custom block with a field value that can be used in other twig template
I am creating a **custom block** with fields:

* field\_items\_to\_show (items to show)
* field\_logos (images, multiple)

**The site editor must have the option to set the amount of items to show in a field.**

in the twig field template `field_logos` I need the value from `field_items_to_show`

```
<div class="logos-slide-out">
    <div class="more-less wrapper d-flex-new flex-column align-items-center">
        <div class="itemstoshow row d-flex-new">
            {% for item in items %}
            {% if loop.index == 9 %} // this value must be set from field_items_to_show
        </div>
        <div class="more-content itemstohide row d-flex-new">
            {% endif %}
            <div class="item col-sm-3 mb-30">{{ item.content }}</div>
            {% endfor %}
        </div>
    </div>
</div>

```

# Answer
> 1 votes
In a field template you find the parent entity in the variable `element['#object']`, from where you can get field values of other fields:

```
{% set field_foo_value = element['#object'].field_foo.value %}

```

---
Tags: entities, blocks
---


# Question
Title: How do I apply a patch with Composer workflow?
I need to include a patch in my project. I have included cweagans/composer-patches in composer.json and added the following lines in the extra section (example is from when trying to enable distribution in the Configuration installer).

```
"patches": {
        "drupal/config_installer": {
            "Enable distribution for Configuration installer profile": "patches/config_installer_enable_distribution.patch"
        }
    }

```

Afterwards, I run `composer update`.

```
- Installing drupal/config_installer (1.5.0): Loading from cache
- Applying patches for drupal/config_installer
    patches/config_installer_enable_distribution.patch (Enable distribution for Configuration installer profile)

```

So I get no errors and the patch seems to have been applied successfully. Also the file `PATCHES.txt` is successfully created in the package's root directory. Still, **the patch hasn't been applied**.

I've tried this method with other packages which come from Github and it works, however every time I try this with a module or a profile from drupal.org then the patch isn't being applied.

Am I missing anything?

When I ran `composer update -vvv`, I saw the command which is running for the patch is indeed with Git.

```
git -C 'web/profiles/contrib/config_installer' apply '-p1' '/path/to/project/patches/config_installer_enable_distribution.patch'

```

I've tried running the command by itself; again, it didn't change the file.

# Answer
> 15 votes
**First**, run

```
composer require cweagans/composer-patches

```

Now you have a package installed that enables you to patch core, libraries or modules.

**Second**, add a patch to a folder named 'patches' in the root (where your composer.json file is).

**Third**, add an "extras" section in composer with a patch:

```
"extra": {
    "patches": {
        "drupal/core": {
            "Undocumented title variable in feed-icon.html.twig": "patches/3156260-11.patch"
        }
    }
}

```

OR

```
"extra": {
    "patches-file": "composer.patches.json"
}

```

with a composer.patches.json file that contains patches like this:

```
{
    "patches": {
        "drupal/core": {
            "Undocumented title variable in feed-icon.html.twig": "patches/3156260-11.patch"
        }
    }
}

```

**Fourth**, run

```
composer install

```

This will remove the core, re-download and patch it. Same goes for modules and libraries.

**Side note**: you can also use an external url of the patch instead of a local file in your patches folder.

**Source**: section 1.1.3 of https://stefvanlooveren.me/courses/drupal-9-framework#toc

# Answer
> 10 votes
The issue is that composer is applying patches using `git apply` which is not working for packages that are not installed from source.

Therefore the solution is to install the packages from source. This way the package will fetch the package along with its repository (when available) thus enabling it to be patched.

So...

## How to install/update a package from source

### For new packages:

Use

```
composer require vendor/package --prefer-source

```

### For existing packages

If your package is already installed then you need to delete it so that you can re-fetch it with `composer install` (there is no `composer reinstall` command). Do so and then use

```
composer install vendor/package --prefer-source

```

### Set it as the default behavior

You can also set it up as the default behavior for the project in the `config` section of `composer.json`:

```
"config": {
      "preferred-install": "source"
    },

```

Update:

### Set it as the default behavior for a specific package

In case you don't want to set your entire project to install from source, you can do so for a specific package only. To do so you need to specify the VCS Branch in the Version constrain of the package.

```
"require": {
        "vendor/package": "dev-branch#branch-hash"
}

```

# Answer
> 9 votes
To apply a patch in drupal 8, edit the composer.json file and find the extra section -

```
"extra": {
    .
    .
    .
    "patches": {
        "drupal/MODULE_NAME": {
            "ANY_STRING_TO_NAME_THE_APPLYING_PATCH": "PATCH URL"
        }
    },
    "enable-patching": true
}

```

For Example -

```
"extra": {
    "installer-types": [
        "bower-asset",
        "npm-asset"
    ],
    "patches": {
        "drupal/recaptcha": {
            "Drupal recaptcha ajax fix syncing": "https://www.drupal.org/files/issues/2019-04-17/recaptcha-ajax-2493183-172.patch"
        }
    },
    "enable-patching": true
}

```

Then, run composer install and your patch is applied.

If you want to apply multiple patches for same package, add new key inside the package name

Example :-

```
"patches": {
   "drupal/MODULE_NAME": {
          "Patch name 1": "Patch 1 Url",
          "Patch name 2": "Patch 2 Url"
        }
    },

```

---
Tags: 8, composer, version-control
---


# Question
Title: How to use Vertical Tabs on ConfigEntity Form
how are you?

I've created a ConfigEntity and there a Configuration Form with Fieldsets and Fields.

Example:

But now I want to change this form to Vertical Tabs, like that:

Do you know how can I do this?

P.s. It is for the Contrib project if you want to test it is: https://www.drupal.org/project/modal\_page

# Answer
Use the vertical\_tabs form element. There is an example shown in the API documentation for this form element: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21VerticalTabs.php/class/VerticalTabs

In short, instead of using nested fieldsets, create a 'vertical\_tabs' form element as the container then put multiple 'details' form elements inside it. Each of the 'details' elements will serve as the container for one vertical tab. See the example in the API documentation for the exact syntax.
> 3 votes

---
Tags: entities, forms
---


# Question
Title: File Field related issue / How to hide file size information?
I used CDN option while creating my sub-theme. I find less and sass things pretty confusing since I am someone who haven't mastered the css yet. What I have found out so far is:

* I can edit some styling copying some css lines from "/libraries/bootstrap/css/bootstrap-theme.css" to "subtheme/css/style.css" file.

What I want to do is to remove / disable / hide the file size information which shows up next to the file link which is the product of 'file-field' of Drupal. This is viewed using bootstrap's table styling / template or whatsoever you call it.

Is this something that should be accomplished using css or it is a template file or maybe it can only be modified in module?

# Answer
Copy your parent's theme **file-html.twig** and place in it your subtheme's /templates folder.

Remove line that has `{{ file_size }}`, example:

```
<span class="file-size">{{ file_size }}</span>

```

Flush cache.
> 2 votes

---
Tags: files
---


title: Missing updates for Media

text:
# Question
Title: Missing updates for Media
After much package dependency finagling via composer, updating PHP, updating MariaDb, etc.. (not as bad as D7 =\> D8 but still harder than I'd hoped) I managed to update from 8.9 =\> 9.0.7. I was able to run update.php, clear cache, etc. site seemed to be working ok, no errors. I enabled the core Media module as apparently blazy now depends on it. Now I'm getting:

> Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE\[42S02\]: Base table or view not found: 1146 Table ‘########.media' doesn't exist: SELECT "base\_table"."vid" AS "vid", "base\_table"."mid" AS "mid" FROM {media} "base\_table" GROUP BY base\_table.vid, base\_table.mid LIMIT 1 OFFSET 0; Array ( ) in Drupal\Core\Entity\EntityStorageBase-\>hasData() (line 583 of /var/www/sites/#####.test/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php).\`\`\`

If I try to run update php I see:

> MISSING UPDATES FOR: MEDIA The installed version of the Media module is too old to update. Update to a version prior to 9.0.0 first (missing updates: media\_post\_update\_collection\_route, media\_post\_update\_storage\_handler, media\_post\_update\_enable\_standalone\_url, media\_post\_update\_add\_status\_extra\_filter).

> MISSING UPDATES FOR: MEDIA LIBRARY The installed version of the Media Library module is too old to update. Update to a version prior to 9.0.0 first (missing updates: media\_library\_post\_update\_display\_modes, media\_library\_post\_update\_table\_display, media\_library\_post\_update\_add\_media\_library\_image\_style, media\_library\_post\_update\_add\_status\_extra\_filter, media\_library\_post\_update\_add\_buttons\_to\_page\_view, media\_library\_post\_update\_update\_8001\_checkbox\_classes, media\_library\_post\_update\_default\_administrative\_list\_to\_table\_display, media\_library\_post\_update\_add\_langcode\_filters).

I'd rather not take core back to an earlier version to resolve this as I'd have to also downgrade some modules, namely Solr which was not super easy to configure.

Can anyone suggest how I might go about resolving this? Is there a way to update a core module without updating core? I thought of just copying and pasting but obviously that wouldn't resolve my missing table issue.

Any pointers in the right direction would be immensely appreciated.

# Answer
> 2 votes
D9 modules will work on D8. You'll have to go back to a D8 core and then go to */update.php* or if you have Drush, run `drush updb`; otherwise, you'll have to manually do the changes to your DB that those updates execute.

---
Tags: media, updating, 9
---


title: Changing existing date time field

text:
# Question
Title: Changing existing date time field
I am working on an already existing site that has content.

There is a content type with field date and time. **I need to remove the time component and just be Date only** without deleting any content along the way. If the time data is lost, that is fine.

Can I simply delete the field and recreate it with date only? Or will that delete the existing data?

# Answer
> 2 votes
Unfortunately, as suggested, programmatically changing the config won't work, as all dates will show empty. Which explains why it's locked in the UI.

You'll need to browse your DB and find the `node__{field_date}` table and manually remove the time part for all values.

Then make a sql export of this table.

Repeat the above with `node_revision__{field_date}`.

In Drupal, manage fields, delete your field\_date. Recreate field\_date with Date only. Import your sql db table exports you had made.

Flush cache in Drupal.

---
Tags: 8, entities, datetime
---


# Question
Title: How to detect order type (recurring or not) in order confirmation and shipping confirmation email templates?
When order is placed an emails is sent to the user generated with template **commerce-order-receipt--default.html.twig**

When order is shipped another email is sent to the user, now generated with template file **commerce-shipment-notification.html.twig**

How to detect from those 2 files if it's a first order (generated by user action) or it was recurring order (generated automatically, by cron)?

I need a way to display different content inside those emails based on this criteria.

# Answer
> 1 votes
Found the way - I can check variable `order_entity.bundle` for order type and it's value can be "default" or "recurring".

However order receipt email is sent only once, when order is placed and not when recurring order is created, so it's not used for recurring order types at all. I guess that's normal.

---
Tags: 8, commerce, emails
---


# Question
Title: How can I update the name of a taxonomy term using hook_update_N?
I have taxonomy terms of color and I made a typo in one of the color name. It should be 'Crystal Black Pearl' instead of 'Crsytal Black Pearl'. How do I change it using hook\_update\_N ? Thank you in advance.

```
function honda_model_install() {
  $term = \Drupal\taxonomy\Entity\Term::create([
    'vid' => 'honda-color',
    'name' => 'Crsytal Black Pearl',
  ]);
  $term->save();
}

```

# Answer
> 4 votes
**honda\_model.install**

```
/**
* Fix typo of term name.
*/
function honda_model_update_8101() {
  $terms = \Drupal::entityTypeManager()
    ->getStorage('taxonomy_term')
    ->loadByProperties([
        'name' => 'Crsytal Black Pearl',
        'vid' => 'honda-color'
      ]); // load using typo
  if (!empty($terms)) {
    $term = reset($terms);
    $term->setName('Crystal Black Pearl'); // make correction
    $term->save();
  }
}

```

Make sure you include the block comment, as that's what gets displayed to the user when they go to /update.php

Flush all caches so hook gets pickedup.

**PS:** once update.php runs it gets recorded in the DB that it ran and it will not run this again. So if you later on need todo another update, you need to add a new hook and increase the number, EX: `honda_model_update_8102`.

---
Tags: 8, taxonomy-terms, updating
---


# Question
Title: How to exclude contributed modules from being upgraded when we run composer install or composer update?
I want to exclude contributed module Ubercart from being upgraded when we run composer install or composer update ? What change should I add in the composer.json so that it ignores ubercart contributed module ? Seems to be simple question, but I have not been able to figure it out.

# Answer
In composer.json, you remove the `^` and specify the version

Ex: Normally most modules are like this:

```
"require": {
    "drupal/commerce: "^2.21",
},

```

and to lock it, you change to

```
"require": {
    "drupal/commerce: "2.20", // will always install version 2.20 and never update.
},

```

But because Ubercart is in Alpha, you'll see its currently

```
"require": {
    "drupal/ubercart: "^4.0@alpha",
},

```

And to lock needs to be

```
"require": {
    "drupal/ubercart": "4.0-alpha3", // will always install alpha 3 and never update.
},

```
> 1 votes

---
Tags: 8, ubercart, composer
---


# Question
Title: Exported feature with roles not imported when loading module
**TLDR;** I'd like to export the permissions I've added to the `authenticated` role, and have them appear on a different server when installing the custom module. However, when I install the module on a fresh server, the permissions for the `authenticated` user remain as default, but I can see in `admin/config/development/features` that there are pending changes, and once I import them the settings are correctly applied. Why aren't they applied on loading the module?

# Steps to reproduce

First I log into a blank dev site, navigate to `admin/people/permissions` and add the *Article: Create new content* permission for the `authenticated` user (which I know is `create article content` from looking at the page source in my browser).

I now navigate to `admin/config/development/features/edit` and select *Roles-\>Authenticate user (authenticated)*, pick a module name, enable *Mark all config as required* and click *Download Archive*.

The result is a module that contains 3 files:

### my\_module.features.yml

```
required: true

```

### my\_module.info.yml

```
name: 'my module'
type: module
core: 8.x
dependencies:
  - user

```

Since I'm using `9.0.7` I changed this to;

```
name: 'my module'
type: module
core_version_requirement: '^8 || ^9'
dependencies:
  - user

```

### config/install/user.role.authenticated.yml

```
langcode: en
status: true
dependencies: {  }
id: authenticated
label: 'Authenticated user'
weight: 1
is_admin: false

```

For some reason `Features` didn't pick up my permission changes, so I changed this manually to;

```
langcode: en
status: true
dependencies: {  }
id: authenticated
label: 'Authenticated user'
weight: 1
is_admin: false
permissions:
  - 'create article content'

```

Now I tried to install the module by copying it to `/modules/custom/my_module` and running `drush en my_module` on a completely clean site. However, when I navigate to `admin/people/permissions` I see this:

When I go to `admin/config/development/features/diff/my_module` I can see that my features were correctly interpreted, just not applied:

If I now select *Import Changes* the permissions apply correctly. But why aren't they already applied, when the `my_module` module is clearly enabled?

I tried playing around with the `weight` value in `user.role.authenticated.yml` to no avail (I changed it to 9999 and -9999 but it didn't seem to have any impact).

The fact that I had to modify my `user.role.authenticated.yml` indicates that something has perhaps gone wrong at the export step, but I don't know enough about the features module to know if these events are related.

# Answer
This is only a workaround. If leymannx or someone else come up with a better solution I'll mark it as the answer, but in the meantime I thought I'd provide my hack-around to get this working:

### my\_module.install

```
<?php

/**
 * @file
 *
 * Install functions for my_module
 */

use Drupal\user\Entity\Role;

/**
 * Implements hook_install().
 *
 * Perform actions to set up the site for this profile.
 *
 * @see system_install()
 */
function my_module_install() {
  $role_object = Role::load('authenticated');
  $role_object->grantPermission('create article content');
  $role_object->save();
}

```

This causes the permission to be correctly applied.
> 2 votes

# Answer
You need to un-exclude user permissions first.

Go to /admin/config/development/features \> Select your bundle \> (Tab) Configure Bundles \> Alter (Configure) \> Uncheck "Strip out user permissions."

Then recreate the feature.

---

I've also already been there.
> 2 votes

# Answer
I would highly suggest you to stop using features and use drush instead You can easily export your config using `drush cex -y` (cex = config export) and import it using `drush cim -y` (cim = config import).
> 0 votes

---
Tags: 8, features
---


# Question
Title: Private tempstore storage contains data for previous anonymous user
I have an issue with private tempstore storage that I wasn't able to solve. I've implemented a webform handler, which populates data in this storage and then I'm creating tokens out of the saved values. This works fine, however, **when anonymous user comes to page where token value is used, he/she sees last value saved in to the storage, before his/her session has been created**.

This is strange, because setting a value for anonymous user should create a session for user, if it doesn't exist, yet: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21TempStore%21PrivateTempStore.php/function/PrivateTempStore%3A%3Aset/8.6.x Do you have any idea why this happens, please? Should I use module https://www.drupal.org/project/session\_based\_temp\_store? Should I consider using Sessions directly (https://drupal.stackexchange.com/a/246268/7580)?

# Answer
> 0 votes
Yes, this looks very much like a caching problem. You don't need to disable the anonymous page cache, though, this happens automatically for requests with a session cookie. What you need is a cache context `session` in render arrays containing session data, no matter whether you serve anonymous or authenticated users:

```
public function build() {
  $session = \Drupal::request()->getSession();
  $build = [
   '#markup' => $session->get('value'),
  ];
  $build['#cache']['contexts'][] = 'session';
  return $build;
}

```

The private tempstore is for large amounts of data. See What is the difference between \Drupal::request()-\>getSession() and \Drupal::service('user.private\_tempstore')?

---
Tags: sessions
---


# Question
Title: How do I ensure new dependencies added to the info.yml of an existing enabled module are picked up?
I've added

```
dependencies:
 - core/jquery
 - core/drupal

```

to `mymodule.info.yml`

(where `mymodule` is my module name).

How do I ensure Drupal "sees" these new dependencies?

For example, can I clear the cache, `drush cr` ?

Or is there another drush command to run or something else to do?

When does Drupal read the `info.yml` file? When module enabled - yes - but what other times?

I would prefer a command to get it to read that file rather than uninstall my module and reenable my module as this could be inconvenient with regard to config/content needing to be re-setup.

Thank you.

**Background**

I'm working on solving a problem where anonymous users see `Uncaught ReferenceError: Drupal is not defined` in console, based on a solution that adds the dependencies I mentioned above: Anonymous Users See Uncaught ReferenceError: Drupal is not defined In console.

**Potentially related:** jQuery not Loading for “Anonymous” Users

# Answer
> 1 votes
I think you are mixing dependencies to modules with dependency to libraries. Your code adds a PHP module dependency to `core/jquery`, and I don't know any module of this name.

(When in module.info.yml)
If you want to add a (JS or CSS) library dependency, use the `libraries:` key and not `dependencies:`

(When in module.libraries.yml)
Remember that just defining a library does not automatically load it, you still must add it in module.info (or load it dynamically)

---
Tags: javascript, 9
---


# Question
Title: How can I attach the same library with Javascript multiple times on the same page with different settings?
I have a custom field formatter that attaches a library that includes a javascript file. It uses drupalSettings to pass some values to the script.

The first time the field formatter appears on a page, it works as expected. However, subsequent appearances of the formatter behave as if they have no script attached.

A simplified example:

```
(function ($, Drupal, drupalSettings) {
  $(document).ready(function () {
    var selector = drupalSettings.gallery.id + ' .foo';
    alert(selector);
  });
})(jQuery, Drupal, drupalSettings);

```

If the field formatter appears three times on a page, I would expect to get three alerts with three (slightly) different strings. Instead, I only get one, with the ID I expect for the first string.

It seems like the easy way to deal with this is to use inline scripts, but I know that's strongly discouraged. Is there a right way to do this?

**Edit:** updating the code to use drupalBehaviors, I now have:

```
(function ($) {
  Drupal.behaviors.galleryBehavior = {
    attach: function (context, settings) {
      $.each(settings.gallery.id, function(index, item) {
        alert(item);
      });
    }
  };
})(jQuery);

```

I'm now getting multiple alerts instead of one, but they still all contain the same string. Dumping the contents of settings.gallery shows that only one ID has been inserted into the array, which suggests to me that subsequent instances of the formatter aren't adding attachments? The PHP code looks like so:

```
$id = $items[0]->getEntity()->uuid() . '__' . $this->fieldDefinition->getName();
ksm($id); // just to make sure I'm actually generating the expected number of unique IDs
$elements['#attached']['drupalSettings']['gallery']['id'][] = $id;

```

This appears to be the right way to populate an attached drupalSettings array, based on one somewhat similar question I was able to find this morning, but clearly I'm missing something.

# Answer
Thanks to responses from 4k4, the following works:

```
$id = $items[0]->getEntity()->uuid() . '__' . $this->fieldDefinition->getName();
$settings = [
  'id' => '#' . $id,
  'setting1' => 'foo',
  'setting2' => 'bar',
];
$elements['#attached']['drupalSettings']['gallery'][$id] = $settings;

```

And then in the javascript:

```
(function ($) {
  Drupal.behaviors.galleryBehavior = {
    attach: function (context, settings) {
      $.each(settings.gallery, function(key, item) {
        var main_selector = item.id + ' .gallery-main';
        alert(main_selector);
      });
    }
  };
})(jQuery);

```
> 2 votes

---
Tags: 8, javascript
---


# Question
Title: How can I change the date format for user submitted data in confirmation emails
The confirmation emails sent by webform (running under Drupal 8.9.7) on submission are in the USA format (m/d/Y) for all date fields submitted by users on the form, differently from the system generated dates, like the the form submission date, which are in UK format).

I need to change the format for the dates submitted by user to the UK format too, as that is what my users expect.

Web research tells me that the Webform module picks the date format for emails from the system's *default medium date*, but this doesn't happen in my case, as that is set to *D d/m/Y - H:i*. What I get for the user submitted date fields is *D, m/d/Y - H:i*.

I have changed the default date format, but nothing changes.

Guidance on how to fix or on a workaround would be appreciated.

# Answer
> 2 votes
I have a work-around, but not a solution:

* Go to /admin/structure/webform/config/elements
* In the section "Element Formats" change "Date/Time" from "- default -" to "Default medium date (medium)"

---
Tags: 8, webforms, emails, datetime
---


title: Alter a module's setting

text:
# Question
Title: Alter a module's setting
I am using the Entity background module, which at the start of its .module file has a line which defines an image style constant.

```
define('EB_IMAGE_STYLE', 'large');

```

I don't want to use that image style, and I don't want to alter the original .module file.

I thought I could write a tiny module just to redefine that line, to alter it. After hours of trying to search for and understand hooks, I am no closer to a solution.

How can I correctly achieve what I want?

# Answer
> 2 votes
There is no need to programmatically alter it, as there is a configuration form that allows you to change it, the README.txt says

> The image style used for the background image can be changed by going to "admin/config/system/entity\_background\_image"

There is also a link to it in configuration

---
Tags: 7
---


# Question
Title: ShippingOrderProcessor not registered well?
I'm trying to implement @jsacksick solution which should force displaying shipping costs on cart page (normally it doesn't exist at that step yet). I created a new module for this and it's structure is simple:

```
shipping_fix
  src
    ShippingOrderProcessor.php
  shipping_fix.info.yml
  shipping_fix.module
  shipping_fix.services.yml

```

ShippingOrderProcessor.php is exact copy of @jsacksick class: https://gist.github.com/jsacksick/fde031197df92236ef5a916775e17a2e

info file contains:

```
name: Shipping fix
description: Fixes missing shipping info on cart page
type: module
core: 8.x
dependencies:

```

module file is empty and services file contains:

```
services:
  shipping_fix.shipping_order_processor:
    class: Drupal\shipping_fix\ShippingOrderProcessor
    tags:
      - { name: commerce_shipping.shipping_order_processor, priority: -300 }

```

But it's not working. I tried setting break points inside `__construct()` and `process()` methods of that class, but they are never reached.

Tried changing last row here to:

```
 - { name: commerce_order.order_processor, priority: -300 }

```

as explained here: https://docs.drupalcommerce.org/commerce2/developer-guide/orders/order-refresh-and-process

but then my site crashes when I try to clear the cache?

So to me it looks like that I didn't register this processor object well. Most likely problem is in services file, but I can't figure out what it is ("**commerce\_shipping.shipping\_order\_processor**" is correct value?).

Tried dumping services with drush like:

```
drush devel:services
drush devel-container-services
drush devel-services

```

and even devel mode is turned on for each try I get: *Command "devel-container-services" is not defined.* or similar.

I activated the my module of course, tried clearing caches, but didn't help.

**Update:** The error which I get when I change last row of services file to:

```
 - { name: commerce_order.order_processor, priority: -300 }

```

is:

*Service 'shipping\_fix.shipping\_order\_processor' for consumer 'commerce\_order.order\_refresh' does not implement Drupal\commerce\_order\OrderProcessorInterface.*

And ShippingOrderProcess.php file starts with:

```
<?php declare(strict_types=1);

namespace Drupal\my_module\OrderProcessor;

use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\OrderProcessorInterface;
use Drupal\commerce_shipping\ShipmentManagerInterface;
use Drupal\commerce_shipping\ShippingOrderManagerInterface;
use Drupal\profile\Entity\Profile;

/**
 * Ensures there are shipments from the start.
 */
final class ShippingProcessor implements OrderProcessorInterface {

  /**
   * The shipping order manager.
   *
   * @var \Drupal\commerce_shipping\ShippingOrderManagerInterface
   */
  protected $shippingOrderManager;

  /**
   * The shipment manager.
   *
   * @var \Drupal\commerce_shipping\ShipmentManagerInterface
   */
  protected $shipmentManager;

  public function __construct(ShippingOrderManagerInterface $shippingOrderManager, ShipmentManagerInterface $shipmentManager) {
    $this->shippingOrderManager = $shippingOrderManager;
    $this->shipmentManager = $shipmentManager;
  }

...

```

**Update 2:**

Managed to clear the cache: For my file structure name space has to be:

```
namespace Drupal\shipping_fix;

```

Also changed servies file and now it looks like:

```
services:
  shipping_fix.shipping_order_processor:
    class: Drupal\shipping_fix\ShippingProcessor
    arguments: ['@commerce_shipping.order_manager', '@commerce_shipping.shipment_manager']
    tags:
      - { name: commerce_order.order_processor, priority: -300 }

```

Now cache clearing works, but I still don't see shipping costs on cart page...

# Answer
In this case, you'll want to run this before the `commerce_shipping.early_order_processor`, set priority to 300

```
services:
  shipping_fix.shipping_order_processor:
    class: Drupal\shipping_fix\ShippingProcessor
    arguments: ['@commerce_shipping.order_manager', '@commerce_shipping.shipment_manager']
    tags:
      - { name: commerce_order.order_processor, priority: 300 }

```
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: hook_field_formatter_third_party_settings_form doesn't fire
I'm attempting to add a checkbox to a field settings form in D9. I have the following code:

```
function my_module_field_formatter_third_party_settings_form(\Drupal\Core\Field\FormatterInterface $plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $view_mode, $form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $element = array();
  print '<h1>HERE</h1>';

  if ($plugin
    ->getPluginId() == 'text_textarea_with_summary') {
    $element['my_setting'] = array(
      '#type' => 'checkbox',
      '#title' => t('test'),
      '#default_value' => $plugin
        ->getThirdPartySetting('my_module', 'my_setting'),
    );
  }
  return $element;
}

```

I then edit an instance of a body field (admin/structure/types/manage/article/fields/node.article.body), and the hook doesn't fire...no debug text nor stopping at the breakpoint on that same line.

# Answer
> 1 votes
There are two problems.

*/admin/structure/types/manage/article/fields/node.article.body* is the path of a field setting. To trigger the hook you need to visit */admin/structure/types/manage/article/display*.

The plugin ID is wrong, too. `text_textarea_with_summary` is the plugin ID of a widget. What you are looking for is probably the formatter `text_summary_or_trimmed`.

If this is neither formatter nor widget, but the content type specific field definition, then use a normal form alter hook, because there is no specific hook to add third party settings:

```
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_form_FORM_ID_form_alter().
 */
function my_module_form_field_config_edit_form_alter(array &$form, FormStateInterface $form_state) {
  /** @var \Drupal\Core\Field\FieldConfigInterface $field */
  $field = $form_state->getFormObject()->getEntity();
  if ($field->getType() == 'text_with_summary') {
    $form['third_party_settings']['my_module']['my_setting'] = [
      '#type' => 'checkbox',
      '#title' => t('test'),
      '#default_value' => $field->getThirdPartySetting('my_module', 'my_setting'),
    ];
  }
}

```

Edit: The form keys $form\['third\_party\_settings'\]\['my\_module'\]\['my\_setting'\] are important. They are used to submit the third party settings.

---
Tags: hooks
---


# Question
Title: Get the form to add a term to a vocabulary programmatically
I am working on Drupal 8.9.6.

I am trying to retrieve the form to add a term to a vocabulary programmatically. I know how to do it for a content type:

```
    $values = array('type' => $content_type);

    $node = \Drupal::entityTypeManager()
      ->getStorage('node')
      ->create($values);

    $form = \Drupal::entityTypeManager()
      ->getFormObject('node', 'default')
      ->setEntity($node);
    $modal_form =  \Drupal::formBuilder()->getForm($form);

```

Nevertheless, I am not able to do the same for the form of adding a term to a vocabulary. Any hint would be more than welcome.

Thanks!

# Answer
```
$vocab_machine_name = 'tags';
$values = array('vid' => $vocab_machine_name);

$term = \Drupal::entityTypeManager()
  ->getStorage('taxonomy_term')
  ->create($values);

$form = \Drupal::entityTypeManager()
  ->getFormObject('taxonomy_term', 'default')
  ->setEntity($term);

$term_form =  \Drupal::formBuilder()->getForm($form);

```

---

### Shorter way

```
$vocab_machine_name = 'tags';

$term = \Drupal\taxonomy\Entity\Term::create([
  'vid' => $vocab_machine_name,
]);

$term_form = \Drupal::service('entity.form_builder')->getForm($term, 'default');

```
> 2 votes

---
Tags: taxonomy-terms
---


# Question
Title: Load Bootstrap CDN only if not is loaded before from another project
I want to load Bootstrap CDN but only if is not loaded before. How can I do this?

Today I'm loading on Libraries.yml like this:

And it works. But the problem is: in some cases the Drupal site already have another project that loads Bootstrap CDN and it is a conflict.

Is there a way to load Bootstrap CDN only if not exists?

# Answer
One approach:

Attach the `modal-page-bootstrap` library as you are doing, and *don't* also load `bootstrap.js` in another way.

Don't worry about adding libraries multiple times to the same page. Drupal is smart enough to only load that library once, and at the right time and order.

The conflict will only arise if you are loading `bootstrap.js` some other way besides attaching a library. If this is the case, then as @leymannx says above you need to find where the extra bootstrap is coming from.

If the Bootstrap CDN is loaded by a script tag in a Twig template, just remove that script tag and only load the CDN via the library, allowing Drupal to keep track of it.

Another approach:

If `another_project` is a theme or contrib module, then it has probably already defined the Bootstrap CDN as a library. If this is the case, you could just attach that library wherever you need it to prevent conflicts. Take a look at the `another_project.libraries.yml` file to see the name of the library, and then load *that* library wherever you need it in your custom theme or module. Again, as above, this will allow Drupal to manage the library so that it will only be loaded once, and only where it is needed.

Note, however, that by doing so you will create a dependency on `another_project`. If you do this in a custom theme or module, then you should make that dependency explicit by declaring the dependency in your `info.yml`. Otherwise, if `another_project` is not present for any reason, you won't be able to load the library.
> 1 votes

---
Tags: 8, theming
---