# Question
Title: Redirect to a specific tab in a page after node submit
I'm working on Drupal 8.9.6.

I'm trying to redirect users to a particular page after they add a node. I can do that without any problem, by adding the following information in the form's URL:

```
/node/add/author/edit?destination=/author-list

```

However, when I try to have a specific **tab** of the destination page opened, as follows:

```
/node/add/author/edit?destination=/author-list#tab2

```

It directly redirects me to `/author-list`, ignoring the `#tab2` part. While if I enter in the browser `/author-list#tab2` I get the `/author-list` page with the `#tab2` active without problem.

Does anyone know what could be happening?

Thank you!

# Answer
> 2 votes
Most if not all browsers strip the hash (fragment) and this information is lost so you can't rely on hash being in the URL.

RFC 3986 states:

> the fragment identifier is not used in the scheme-specific processing of a URI; instead, the fragment identifier is separated from the rest of the URI prior to a dereference, and thus the identifying information within the fragment itself is dereferenced solely by the user agent, regardless of the URI scheme. Although this separate handling is often perceived to be a loss of information, particularly for accurate redirection of references as resources move over time, it also serves to prevent information providers from denying reference authors the right to refer to information within a resource selectively.

**Possible workaround:** Create a hidden input field *url\_fragment* and make sure it passes as a URL parameter (&url\_fragment=hashvalue). Have some javascript execute on load of this page and if it finds the url\_fragment in the URL make it do a scrollTop and opening of the specific tab.

Here is a question and answer that does the scrollTop if the urlParemeter EXISTS. You need to modify this script to get the actual value and also click the Tab.

---
Tags: forms, redirection
---


# Question
Title: Best practice approach for environment specific keys
I'm using encrypt/key/real\_aes and lockr to create environment specific encryption profiles. Ie, prod data should never be accessible on UAT, dev, local etc.

What I'm wondering about is whether I can easily swap out field encryption profiles on specific environments, or if I can change the key being used by the environment?

Ultimately, I'd just like keys to be available to their environment only. Lockr helps by never displaying the key, but I can still request the prod key from lockr when on local, etc.

I'm not sure I can do these while keeping my site secure so I'm hoping for some best practice solutions to this.

Thanks.

# Answer
> 0 votes
So, I reached out to one of the authors of key and the lockr service to get some help.

What I learned is, if using the key module without lockr, you can change the value of the key while keeping its machine name the same.

But, if using lockr (and you should be using lockr) it will create and swap keys for you based on your environment automatically. So, your encryption profile will automatically be kept up to date. Awesome stuff.

Hope this is helpful to others, the docs are here; https://docs.lockr.io/#separate-environments

---
Tags: 8
---


# Question
Title: why is hook_access_node running three times?
I'm working on a custom node access module. For this I'm working with hook\_node\_access hook (for the first time).

I want visitors to be able to view a node only when they are looking at them from the right domain. For this I have a content type `page`, in this content type I created a field `field_domain`.

Now I create a two nodes, `Node A` with field\_domain value `d9-a.lcl` and `Node B` with field\_domain value `d9-b.lcl`.

Now I wanted to create the module based on the this tutorial. But before this I created a simple check to see if I can get the value from the field and current domain. So I wrote this:

```
function hook_access_node_access(NodeInterface $node, $op, $account)
{
    $type = $node->bundle();
    if ($type == 'page') {
        $currentDomain = $_SERVER['SERVER_NAME'];
        $readerDomain = $node->field_domain->value;
        dpm($node->id());
        dpm('Current domain: ' . $currentDomain);
        dpm('Pages domain: ' . $readerDomain);
    }
}

```

Now going to `Node B` from domain `d9-b.lcl` made me expect to see three values. And the values I wanted to see are there but they get returned three times.

So for some reason the hook is called three times and I can't figure out why. Is it normal that this hook is called three times? And if it is is there a better way to do what I want?

# Answer
Yes it’s perfectly usual for a node access hook to be hit multiple times in one request, check the $op parameter to see what you’re dealing with each time.

Checks may be done for different $op values like view,update and delete.

(Answer from @Clive in comments, posted here as answer after his advice. Please see question's comments.)
> 2 votes

---
Tags: 8, hooks
---


# Question
Title: "[warning] Invalid argument supplied for foreach() Migration.php:641"
Why does this error appear when I use the `drush ms` command?

> \[warning\] Invalid argument supplied for `foreach()` Migration.php:641

# Answer
Usually this comes from having incorrectly coded a hard value in your migration yml script. As noted in the following example:

```
process:
  type:
    plugin: default_value
    default_value: 'profile'
  status: 1
  uid:
    -
      plugin: skip_on_value
      source: user_id
      method: row
      value: 1
    -
      plugin: migration_lookup
      no_stub: true
      migration: tabs_users
      source: user_id

  is_default: '1'
  created: created
  changed: user_lastvisit

```

Here I show a few different approaches, but one is wrong. Specifically, the `status:` line is trying to set a value of **1** but the migrate module is assuming it is a variable and since it is not set previously in the **source** section of the yml script, drupal is barfing. To fix this, do what is done in either the **type** line OR the **is\_default** line; explicitly set the value via the **default\_value** plugin OR **encapsulate your value in quotes**. This is identified in the documentation but can be easily overlooked when quickly coding up a solution.
> 0 votes

---
Tags: 8, migrations
---


title: How to override Drupal behaviors?

text:
# Question
Title: How to override Drupal behaviors?
I want to override the drupal core behavior `Drupal.behaviors.filePreviewLinks` which is located at `core\modules\file\file.js` from my custom module

I tried placing the following code in js file of my custom module

```
Drupal.behaviors.filePreviewLinks = {
    attach: function (context, settings) {
        console.log($(context).find('div.js-form-managed-file .file a'));
        //some custom code
    },
    detach: function (context, settings){
       //some custom code
    }
};

```

But it is not working. What I need to do? How to override Drupal core behavior in custom module?

**EDIT**

Let me explain my actual question. I am loading a form in page that is created using ECK entity type module. One of a field in form has 'file' as field type. So once I upload a file, it is showing filename with link in a table(I hope it is default drupal feature). I want to remove the file link and show only file name.

# Answer
> 1 votes
I do something similar in the Node Revision Delete module to override the drupal.content\_types library doing this:

In the \*.libraries.yml file define your library:

```
content_types:
  version: 1.0.0
  js:
    js/content_types.js: {}
  dependencies:
    - core/jquery
    - core/drupal
    - core/drupal.form

```

Attack your library where you need it:

```
  // Element to track the content type.
  $form['workflow']['section']['node_revision_delete_track'] = [
    '#type' => 'checkbox',
    '#title' => t('Limit the amount of revisions for this content type'),
    '#default_value' => $track,
    '#attached' => [
      'library' => [
        'node_revision_delete/content_types',
        'node_revision_delete/admin_settings',
      ],
    ],
  ];

```

And remove the core library:

```
/**
 * Implements hook_library_info_alter().
 */
function node_revision_delete_library_info_alter(&$libraries, $extension) {
    unset($libraries['drupal.content_types']);
}

```

# Answer
> 5 votes
## Use `libraries-override` in your theme's info.yml file

**Step 1: Find the library name in core that the JS or CSS file to override belongs to.**

For example, it is clear that `core\modules\file\file.js` belongs to the `file` module. Review at `core/modules/file/file.libraries.yml` to find the library name . In the yaml file, the library name is the top-level item in the yaml structure where `file.js` is defined. In this case `drupal.file`.

```
#core/modules/file/file.libraries.yml
drupal.file:
  version: VERSION
  js:
    file.js: {}  #### Drupal 8+ defines the js/css to override in libraries.yml
  dependencies:
    - core/jquery
    - core/jquery.once
    - core/drupal
    - core/drupalSettings

```

**Step 2: Find the fully-qualified library name.**

The fully-qualified library name is generally prefixed by the module name, in the format `<modulename>/<libraryname>`. However, some core system libraries don't follow this format, so if unsure of the fully qualified library name, search for instances of the `<libraryname>` in the core codebase, which may turn up a string with the fully-qualified library name like `drupal/<libraryname>`.

In this case the fully qualified name is `file/drupal.file`.

**Step 3: Override the file in your theme**

In your custom theme's info.yml file add the following lines:

```
libraries-override:
  file/drupal.file:
    js:
      file.js: js/file.js

```

If you want to override a core or contrib CSS file, the syntax is similar:

```
libraries-override:
  filter/caption:
    css:
      theme: # <-- this line must match the definition in libraries.yml
        css/filter.caption.css: css/components/captions.css
#        ^                       ^
#        |                       |
#      File path as defined     File path relative to your
#      in *.libraries.yml       theme's folder.

```

**Step 4: Copy the file into your theme, and modify it to your needs**

For the 2 examples given above, you'd place the files.js inside a folder `js` in your theme, and you'd rename filter.caption.css to captions.css and place it inside the `css/components` folder of your theme.

**Step 5: Clear caches and reload the page.**

Use your Web browser's resource inspector to verify the path to the overridden file is coming from your theme folder.

# Answer
> 4 votes
Since Drupal behaviors are really just javascript objects, all you need to do is to ensure that the behavior you're overwriting is loaded before your replacement. So:

**my\_module.libraries.yml**

```
some_new_lib:
  js:
    my-js-file.js: {}
  dependencies:
    - libary_with/behavior_you_want_to_override
    - core/jquery   # anything else you need

```

**my-js.file**

```
(function ($) {

  Drupal.behaviors.nameOfBehaviorYouWantToOverride = {
    // Your little dash of magic
  }

})(jQuery);

```

---
Tags: 8, javascript
---


# Question
Title: 'You must declare "ids" as a unique array of fields in your source settings'
I am trying to learn about importing images with migrations using this tutorial and this custom module (c11n\_module). When I install and try to run 'drush ms' I keep getting an error.

```
In CSV.php line 105: You must declare "ids" as a unique array of fields in your source settings.

```

The id looks like this:

```
keys:
  - ID

```

The helper thought I found shows this:

```
ids:
  id:
    type: integer

```

However, if I change to this:

```
ids:
  keys:
    - ID

```

I still get the error. I have spent a few hours trying to figure this out. I am assuming it is in the YML file that I have to correct this. Any ideas for solving this issue?

Or am I thinking about it all wrong?

Here is the whole YML:

```
# Migration file for creating "image" for academic programs.
#
# Detailed explanations for various elements of a migration
# YAML have been provided in migrate_plus.migration.program_data.yml

id: program_image
label: Image associated to academic programs.
migration_group: c11n
migration_tags:
  - academic program
  - file
  - image
# Source.
source:
  plugin: csv
  path: 'public://import/program/program.data.csv'
  header_row_count: 1
  ids:
    keys:
      - Image file
  # Source field definitions.
  fields:
    Image file: Name of the image file associated with the program.
  constants:
    file_source_uri: public://import/program
    file_dest_uri: 'public://program/image'
# Destination.
destination:
  # We will be creating entities of type "file" this time.
  plugin: 'entity:file'
# Mappings.
process:
  file_source:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/file_source_uri
        - Image file
    -
      plugin: urlencode
  file_dest:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/file_dest_uri
        - Image file
    -
      plugin: urlencode
  filename: Image file
  uri:
    plugin: file_copy
    source:
      - '@file_source'
      - '@file_dest'
# Dependencies.
dependencies:
  enforced:
    module:
      - c11n_migrate

```

# Answer
The way you're currently doing it doesn't look familiar, with `keys` and the way the `fields` are mapped; might just be it's a method I haven't come across though.

Either way I've always had success processing CSVs like this:

```
ids:
  - image_file
fields:
  0:
    name: image_file
    label: Image file

```

That assumes the first column in the CSV contains the unique image file name.
> 1 votes

---
Tags: 8, migrations
---


# Question
Title: How can I make Search API search field collections?
I have a content type called Basic Page with a few fields (title, description, page body), one of which (page body)is a field collection with a field called 'Section Body'. I created a view called Search Page that searches all my content (including other content types), then added my Field Collection Item datasource to my index and added the Section Body field (with type Fulltext) to the Fields section of my index.

After reindexing all of my content, I went to my view and added 'Field Collection Item \>\> Section Body' to the 'Search fields' section of my Fulltext search option in my view's Filter Options.

To test all this, I added in the unique term 'testterm123' to my content title, cleared the cache, and searched for the term. The test content returned successfully, so I know that the title is being searched for successfully. I repeated this process for description, and that worked as well. However, it did not work for my field collection field Section Body and nothing was returned.

So I'm confident that I indexed everything correctly, but the Field Collection field is not being searched. Has anyone run into this and if so, what did you do to fix it? Does anyone have any ideas on how to fix this or solutions to attempt?

# Answer
You shouldn't use the field collection module in D8 to begin with, as the project page says

>

and it also says

> ### Drupal 8
>
> Use Paragraphs and Entity Reference Revisions instead of field collection for Drupal 8 projects.

If you don't make the change now you will have to, in the future, whenever you migrate to D9 as there won't be any D9 version.
> 3 votes

---
Tags: 8, search
---


# Question
Title: LogicException: The database connection is not serializable - when I try to open any "gear" on checkout flow page?
So I'm on `Commerce -> Configuration -> Orders -> Checkout flows`. I'm editing a flow (it's the same with any of them), so i.e. I'm at page:

```
/admin/commerce/config/checkout-flows/manage/shipping

```

and for some items (i.e. "Login or continue as guest", "Contact information"...) with the option I also have gear icon on right for opening some settings block.

Until recently that worked well, but now, when I click gear icon spinner appears for short time and nothing happens.

In error log I see message:

> *LogicException: The database connection is not serializable. This probably means you are serializing an object that has an indirect reference to the database connection. Adjust your code so that is not necessary. Alternatively, look at DependencySerializationTrait as a temporary solution. in Drupal\Core\Database\Connection-\>\__sleep() (line 1573 of /var/www/html/drupal/web/core/lib/Drupal/Core/Database/Connection.php).*

From browser network tab I can see that url:

http://sitename.test/admin/commerce/config/checkout-flows/manage/shipping?destination=/admin/commerce/config/checkout-flows&ajax\_form=1&\_wrapper\_format=drupal\_ajax

is called and response was:

**500 Service unavailable (with message)**

Any idea what could cause this error and how to solve it?

# Answer
> 0 votes
Found what caused the problem. As I said, it was working until recently and just stopped "without any reason". Then I remember that I recently installed module "Mail login": https://www.drupal.org/project/mail\_login

And as soon as I uninstall that module everything is back to normal, everything works well.

So not sure where the problem is, probably inside that Mail login module, but they don't work well together.

Reported the issue here: https://www.drupal.org/project/mail\_login/issues/3181217

# Answer
> 9 votes
I experienced the same problem. It's not a commerce issue, and there is no general rule which module causes the problem.

The problem probably occurs, because one of your checkout panes depend on a service, which has an indirect dependency to Drupals database connection -- Drupals database connection is not serializable and this causes the error.

It's not that easy to debug, because the form is soooo big, and loads all the CheckoutPane Plugin Forms. The good news: I figured out a way to debug the issue:

First of all, we need to determine the problematic checkout pane. To do that, we loop over all panes and try to serialize them independently. Temporary add the following snippet to the Drupal\Core\Form\FormState::getCacheableArray()

```
if(!empty($this->getStorage()['panes'])) {
  // loop over all panes and try to serialize each independently,
  // catch possible serialization errors and dump the problematic pane.
  foreach($this->getStorage()['panes'] as $key => $pane) {
    try {
      serialize($pane);
    } catch(\Throwable $throwable) {
      // dump pane, which causes the error and die
      dd($pane);
    }
  }
}

```

*FYI: The dd() output does not look very pretty in chrome's network tab (all the properties are expanded). I copied the request as CURL Request (in chrome: right click on the XHR Request --\> copy as CURL) and pasted it into Insomnia (my Rest Client). When executing the Request there, the dd() is displayed as usual with the possibility to expand and collapse the properties. That makes it much easier to find the problematic service..*

There should be a dumped object, which is the non-serializable checkout pane. If thats not the case, you have a completely different problem than me and you can skip this answer. But if there is a dump of the pane, you can now have a detailed look at the properties of the pane. It is necessary, that the properties which are services have a \_serviceId property; if this property is missing, the Pane's DependencySerializationTrait isn't recognizing the Service as a Service.

Unfortunately, there can be Services, which haven't the \_serviceId property. In my case, a contrib module (mail\_login) provided a decoration service, which decorated the service user.auth. The service user.auth is injected as dependency to the Login-pane (and I think another one too). This decorated service, had no \_serviceId property, so Drupal tried to serialize the the user.auth Service. The problem is now, that the user.auth service has a dependency to Drupals database connection, but no DependencySerializationTrait --\> Drupal tries to serialize the Database connection and throws the error.

To solve the issue, I created my own decorator service class within a custom module, which extends the original decorator class from mail\_login (because i need the logic from the mail\_login decorator). I just added the DepenencySerializationTrait to my own decorator and replaced the service class for the decorator service in my modules service provider (in my case, the decorator service is called "mail\_login.auth").

I'll share my code too.. (I modified it for the post, so there may be errors. But you can use the snippets for better understanding)

My decorator only uses DependencySerializationTrait:

```
<?php

namespace Drupal\my_module;

use use Drupal\mail_login\AuthDecorator as MailLoginAuthDecorator;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;

class AuthDecoratorDependencyFix extends MailLoginAuthDecorator
{
  use DependencySerializationTrait;
}

```

My Serviceprovider just replaces the original service class:

```
<?php

namespace Drupal\my_module

use Drupal\Core\DependencyInjection\ContainerBuilder\ContainerBuilder;
use Drupal\my_module\AuthDecoratorDependencyFix;

class MyModuleServiceProvider
{

  public function alter(ContainerBuilder $container) {
    if($container->hasDefinition('mail_login.auth')) {
      $mailLoginAuth = $container->getDefinition('mail_login.auth');
      $mailLoginAuth->setClass(AuthDecoratorDependencyFix::class);
    }
  }
}

```

I'll create an issue for the mail\_login module (maybe on Monday ;)). Please let us know, if it's another service, or a completely different error on your side.

---
Tags: 8, commerce, database, ajax
---


title: How do I clear or delete a queue?

text:
# Question
Title: How do I clear or delete a queue?
I scheduled a big queue with VBO, but I changed my mind. How can I delete it? I don't seem to find any UI/interface to manage queues. Do I have to delete it in the database?

# Answer
> 14 votes
There's no built-in management UI for queues in Drupal but if you're looking for a one check out the Queue UI module.

To delete a queue in your code use `$queue->deleteQueue();`

# Answer
> 20 votes
`drush` has no option to clear queues, there is just `drush queue-list` and `drush queue-run`. However, you can use it to delete the corresponding queue records from the database:

1. Use `drush queue-list` to find out the name of the queue you want to clear. In my case, it is `message_subscribe`.
2. Use a command like this, replacing with your queue's name accordingly:

```
drush sqlq "DELETE FROM queue WHERE name='message_subscribe'"

```
3. Confirm with `drush queue-list` that the queue in question now has zero items in it.

This solution is quite similar to @batigolix's, just that it clears a specific queue instead of all queues.

**Careful.** Like @batigolix said, take care not to lose data! This solution might not be for a production environment …

# Answer
> 6 votes
Yes, you can delete or clear a queue in the database by emptying the queue table.

Drush allows you to do that easily with `drush sqlq "TRUNCATE queue"`.

**Careful**. I tried this in a local development environment. It may not be recommended in production.

Emptying the entire `queue` table is not always a good idea as it contains items from queues created by other modules as well. So, a cleaner way is to remove items from a particular queue.

* First, inspect the queues which exist in the `queue` table by browsing the table using `mysql` or `phpmyadmin`. To get all queue names with some items in the queue, you can do `SELECT DISTINCT name FROM queue`.
* Second, once you've decided upon the queue you want to empty, remove items only for that queue using `DELETE FROM queue WHERE name = :name`. Replace \`:name: with the name of the queue you found in the first step.

I've used this on production, but you should be careful and use your judgement. In short, best thing is to not delete stuff from other module's queue or queues you don't know the purpose of.

# Answer
> 5 votes
In Drupal 8, via drush you can do it this way:

```
$ drush queue:delete your_queue_name

```

Or:

```
$ drush php
>>> \Drupal::service('queue')->get('your_queue_name')->deleteQueue()
=> null

```

---
Tags: 7, queue
---


# Question
Title: Can you render a custom block in a view without adding it to the admin blocks page?
I made a custom block in my custom module. I now want to show that block in the "No results" area of a view, but I can't get it to render (I don't see any error message, and I don't see any output).

Here is the block definition:

```
/**
 * Provides an 'New User' Block.
 *
 * @Block(
 *   id = "newuser_block",
 *   admin_label = @Translation("New user block"),
 *   category = @Translation("MYMODULE"),
 * )
 *

```

In my view, in the "No results" section, I added **Rendered entity - Block**, and set the **Block ID** to **newuser\_block**.

However, the block does not get rendered.

This is because I did not add the block on the block admin page at `/admin/structure/block`. When I add the block on the admin page and use the admin page block ID (not the block machine name), the block is rendered correctly.

However, I don't want to add the block to the admin page because I only need this block in a few places on my site, so I was using Layout Builder to inject the block where necessary.

So, is there a way to inject a block by machine name (instead of by the ID used on the block admin page) in Views?

# Answer
> 1 votes
There is an core issue about this, Problems using 'Rendered entity - Block' in header/footer

> the block ID only exists as long a the the block is configured to be visible in a region

Until fixed, yes, it is possible without having to add it to a region as long as you solve it via template file. In this case using views-view--\[view-name\]--\[view-display-name\].html.twig and using **Twig Tweak** you can print it with

```
{{ drupal_form('namespace\\ClassName') }} # except you add an extra `\`

```

Ex:

```
{{ drupal_form('Drupal\\search\\Form\\SearchBlockForm') }}

```

# Answer
> 4 votes
The only purpose of a block plugin is to be placed as a block. It's not an entity. The placed block instance can become an entity of its own but also be part of a layout section.

Since the block is your own custom code you don't need any of the workarounds discussed and linked. It would make more sense to refactor the code and expose it as block plugin to be placed on the page and at the same time as area plugin to be placed in a View.

For sharing the custom code between both plugins you can use classic OOP, or the in Drupal very common traits and services. The service has the advantage that it is more flexible and you can not only share code but also data, for example to cache the result if it is expensive to calculate and used in multiple places.

---
Tags: 8, views, blocks
---


# Question
Title: How do I show an exposed view filter in a block only on relevant taxonomy term pages?
I have two different taxonomy term views for different taxonomy vocabularies: the Blog categories the and Product types. I have an exposed filter in a block that is relevant only for the Product taxonomy term.

How do I show the filter block only on /taxonomy/term/\* pages for the Product term, without the need to list them explicitly in the block settings?

# Answer
> 2 votes
**How to make a block vocabulary-specific**

You can use the Block Visibility Groups module in conjunction with the **Vocabulary Condition** module (linked on that page). Using those two modules together will give you a checkbox on the block to pick the vocabulary it should be shown for.

If you want to do it programmatically, the Vocabulary Condition module should be a good code reference. There's also another Vocabulary Condition module (same name, ugh!) which could also be a good reference.

**Alternative idea: Use different view pages for each vocabulary**

If you're using the default taxonomy term view provided by core, I'm pretty sure you can customize it so that you have one page for terms with the Product vocabulary and another for the Blog category. Then you can simply expose the filter on the view page for the relevant vocabulary.

---
Tags: 8, views, blocks
---


# Question
Title: Permission name to view manage display page
I want to programatically use a permission to give user access to the manage display page. Does anybody know the name of that permission? 'administer content types' only gets me far as to edit the content type.

# Answer
> 0 votes
The route definitions for the *Manage display* pages are added from `RouteSubscriber::alterRoutes()`, a class implemented from the *Field UI* module. The relevant code is the following one.

```
$route = new Route("{$path}/display", [
  '_entity_form' => 'entity_view_display.edit',
  '_title' => 'Manage display',
  'view_mode_name' => 'default',
] + $defaults, [
  '_field_ui_view_mode_access' => 'administer ' . $entity_type_id . ' display',
], $options);

```

The permission the users need to have to access those pages is *administer $entity\_type\_id display*. Since there is a page for every fieldable entity defined, the permission changes basing on the entity for which that page is shown. For nodes, that permission is *administer node display*.

Those permissions are defined from the *Field UI* module in `FieldUiPermissions::fieldPermissions()`. A module using them should add the *Field UI* module to its dependencies.

---
Tags: 8
---


# Question
Title: How do I redirect on flag save programmatically?
I want to redirect users to a view when they flag a taxonomy term.

This question is about how to use Rules to redirect on flag save. I want to do this programmatically.

I tried to use `hook_form_alter()` to add a submit handler with the redirect. Unfortunately, while flaggings have an edit form that can be targeted by `hook_form_alter()` (`MYMODULE_form_flagging_FLAGTYPE_edit_form_alter()`), they do not seem to have a "create" form.

So how can I add a redirect programmatically upon flagging?

**EDIT**

Based on 4k4's comment I looked at `/flag/srs/Entity/Flagging.php`:

```
 *    "form" = {
 *      "add" = "Drupal\flag\Form\FlaggingForm",
 *      "edit" = "Drupal\flag\Form\FlaggingForm",
 *      "delete" = "Drupal\flag\Form\UnflagConfirmForm"

```

However, when I tried to do a `hook_form_alter()` with:

* `function MYMODULE_form_flagging_FLAGGINGTYPE_add_form_alter(&$form, FormStateInterface $form_state, $form_id)`
* `function MYMODULE_form_flagging_add_form_alter(&$form, FormStateInterface $form_state, $form_id)`

I could not get either to pick up my code (I rebuilt the cache).

# Answer
> 1 votes
You can take a different approach to target entity forms:

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

/**
 * Implements hook_form_alter().
 */
function mymodule_form_alter(array &$form, FormStateInterface $form_state) {

  $form_object = $form_state->getFormObject();
  if (!($form_object instanceof ContentEntityFormInterface)) {
    return;
  }

  $entity = $form_object->getEntity();
  if (!(entity instanceof FooEntityInterface)) {
    return;
  }

  if (!$entity->isNew()) {
    return;
  }

  if ($entity->bundle() !== 'bar') {
    return;
  }

  // alter form
}

```

# Answer
> 1 votes
This can be done in `hook_entity_presave()`.

```
function MYMODULE_flagging_presave(FlaggingInterface $flagging) {
  switch ($flagging->getFlagId()) {
    case 'FLAGTYPE':
      $redirect_url = Url::fromRoute('view.VIEW_MACHINE_NAME.VIEW_DISPLAY_ID')->toString();
      $response = new RedirectResponse($redirect_url);
      $response->send();
     break;
   }
 }

```

---
Tags: 8, flags
---


# Question
Title: How do I add a description to the node title form field?
This might sound stupid, but I can't find a way to do it. I need to add a description to the node title, just like I add a description to other fields. How can I do it?

# Answer
> 10 votes
In a `hook_form_alter()` or `hook_form_FORM_ID_alter()`, add a description attribute to the node form element array:

```
 //Add a title field description
  $form['title']['#description'] = t('Enter your awesome title field details.');

```

# Answer
> 3 votes
In Drupal 8 is pretty similar inside the same `hook_form_alter()`:

```
$form['title']['widget'][0]['value']['#description'] = t('Enter your awesome title field details.');

```

# Answer
> 1 votes
Node title help text module can be used to add help text to node title. Configuration is available to add description per content type

https://www.drupal.org/project/node\_title\_help\_text

---
Tags: 7, nodes
---


# Question
Title: How can I limit the password reset attempts?
I have Google Recaptcha, but some users try to recovery password too often. I didn't find any solution for this problem. I want to make 5 attempts limit for this.

# Answer
You can use the Flood Control module for it.

> Flood Control provides an administration interface for hidden flood control variables, like the login attempt limiters and any future hidden variables.
> 1 votes

# Answer
Yes, Drupal 7 does not have such option at the moment but there is a patch and also you can create your own module to fix this.

1. Patch https://www.drupal.org/project/drupal/issues/3074666 1.1) After applying of the patch add to the end of the file /sites/default/settings.php line that defines number of attempts:

```
$conf['user_pass_reset_user_limit'] = 3;

```
2. Create your own module 2.1) Prepare files for your module xandeadx.ru/blog/drupal/256 2.2) Modify password reset form, code can be taken from here: https://www.drupal.org/project/drupal/issues/1681832

```
// xyz - your module name
function xyz_user_pass_form_validate($form, $form_state){
  // 3 - stands for number of password reset limit made during 86400 seconds
  if(!flood_is_allowed('request new password', 3, 86400, $form_state['values']['name'])){
    form_set_error('name', 'Reset password limit exceeded.  Please contact technical support for further assistance.');
  flood_register_event('request new password', 86400, $form_state['values']['name']);
  } else {
    flood_register_event('request new password', 86400, $form_state['values']['name']);
  }
}

hook_form_user_pass_alter($form){
  array_unshift($form['#validate'], 'xyz_user_pass_form_validate');
}

```
> 1 votes

---
Tags: users
---


# Question
Title: With a view of flaggings, how do I get the flagged entity?
I want to create a view of flaggings and show content from the flagged entity.

However, on a flaggings view (Flag 4.x, Drupal 8/9), when I try to add a relationship, I can only add a relationship to the **User**, not the flagged entity.

Is this functionality not available in Flag?

When I create a view of nodes and want to pull in the flags, all I have to do is add a relationship to the **Flag** and it pulls in the flaggings automatically. So the Flag module supports going from nodes to flaggings, but how do I go from a view of flaggings to the flagged nodes?

**Why I am trying to do this**

Normally, I would just go from nodes to flaggings. However, this time, I have three different flags, and the same node may be flagged by multiple flags, and I want to show an entry for the node for each flagging, not one entry for the node for all flaggings.

# Answer
Whoops, this is a work in progress to be added to Flag at some point.

In the meantime, this can be worked around using an entity reference field.

First, add an entity reference field to the flag.

Next, set the entity reference using hook\_flagging\_presave().

```
function MYMODULE_flagging_presave(FlaggingInterface $flagging) {
  switch ($flagging->getFlagId()) {
    case 'MYFLAGTYPE':
      if ($flagging->isNew()) {
        // Set entity reference for new flaggings.
        $flagged_entity_id = $flagging->get('entity_id')->value;
        $flagging->set('field_myflag_entityreference', $flagged_entity_id);
      }
    break;
  }
}

```

Finally, you can use the entity reference to the flagged node in your view in the same way as any other entity reference.

Because the flag module patch to solve this issue is in flux, it seems to me a bit dangerous to apply the patch to a production site, because the ultimate direction of the flag module may differ from any given patch. So, using an entity reference has the advantage of achieving the desired solution now (get access to the flagged entity in the flaggings view) while still allowing the future flag solution to be used (when flag becomes able to support this, you can simply delete the entity reference field, as it will no longer be necessary).
> 2 votes

---
Tags: 8, views, flags
---


# Question
Title: Autocomplete field where title is replaced with NID
I'm using Drupal 7 and I have made autocomplete function to be called on a field.

File my\_module.module:

```
<?php

function my_module_menu() {

    $items = array();

    $items['/autocomplete'] = array(
        'title' => 'Autocomplete',
        'page callback' => 'companyAutocomplete',
        'access arguments' => array('autocomplete'),
        'type' => MENU_LOCAL_TASK,
        'weight' => 1,
        'file' => 'my_module.autocomplete.inc'
    );

    return $items;
}

```

File my\_module.autocomplete.inc:

```
<?php

function companyAutocomplete($fieldInput) {

    $returnArray = array();

    $query = db_select('node', 'n')
        ->fields('n', array('nid', 'title'))
        ->condition('n.title', '%'.db_like($fieldInput).'%', 'LIKE')
        ->condition('n.type', 'company', '=')
        ->orderBy('n.title', 'ASC')
        ->range(0, 10);

    // print strtr((string) $query, $query->arguments());

    $results = $query->execute();

    foreach ($results as $result) {
        $returnArray[$result->title] = check_plain($result->title);
    }

    drupal_json_output($returnArray);
}

```

File template.php:

```
<?php

function my_theme_preprocess_field(&$vars) {

    if ($node = menu_get_object()) {

        if ($node->type == 'company') {

            if ($vars['element']['#field_name'] == 'field_company') {
                $company = entity_metadata_wrapper('node', $vars['items']['0']['#markup']);
                $vars['items']['0']['#markup'] = $company->label();
            }
        }
    }
}

```

and I have a field company (I use this field to enter NID):

```
$form['field_company'] = array(
    '#type' => 'textfield',
    '#default_value' => $defaultCompany,
    '#title' => 'Company',
    '#autocomplete_path' => '/autocomplete',
);

```

When I type something in field, autocomplete returns correct text value of the searched term and that is ok.

How can I modify `companyAutocomplete()` function or the field itself for autocomplete to works as it is, but to write NID instead title in $form\['field\_company'\]\['und'\]\[0\]\['value'\]?

# Answer
> 0 votes
You need the array keys to be nids, so change it to

```
$returnArray[$result->nid] = check_plain($result->title);

```

---
Tags: 7, theming, entities, forms, ajax
---


title: How to update the TWIG flag conditions?

text:
# Question
Title: How to update the TWIG flag conditions?
I have this code in my sub theme :

**bootstrap\_subtheme\_front\_office\_old.theme**

```
<?php

/**
 * Implements hook_preprocess_HOOK() for user.html.twig.
 */
function bootstrap_subtheme_front_office_old_preprocess_user(&$variables) {
  $flag_service = \Drupal::service('flag');
  $user_to_flag = $variables['user'];

  $flag_ids = [
    'role_association' => 'is_flagged_role_association',
    'role_pop_up_store' => 'is_flagged_role_pop_up_store',
    'role_artisan' => 'is_flagged_role_artisan',
  ];

  foreach ($flag_ids as $flag_id => $var_flag) {
    if ($flag = $flag_service->getFlagById($flag_id)) {
      if ($flag_status = $flag_service->getFlagging($flag, $user_to_flag)) {
        $variables[$var_flag] = $flag_status;
      }
    }
  }
}

```

And this templates :

**user--account-roles.html.twig**

```
<div class="card p-4 overflow-hidden shadow rounded bg-white">

  <div class="alert alert-light" role="alert">
    <p class="text-center">Vous trouverez sur cette page les différents types de compte disponible.</p>
    <p class="text-center">Chaque type de compte vous donne droit à des autorisations au sein de la plateforme.</p>
    <p class="text-center font-weight-bold">Vous devez avoir un numéro de SIRET.</p>
    <p class="text-center">Les modifications peuvent prendre 24 heures pour ếtre appliquées.</p>
  </div>

  <p>Les associations sont destinées aux comités des fêtes, offices de tourisme, ... qui organisent des événements. Vous pourrez y publier divers types de contenu.</p>
  {% if 'association' in user.getroles %}
    <div><i class="fas fa-circle text-success"></i> Votre compte association est actif.</div>
  {% elseif 'association' not in user.getroles and is_flagged_role_association %}
    <div><i class="fas fa-circle text-warning"></i> Votre compte association est en attente.</div>
  {% elseif 'association' not in user.getroles and not is_flagged_role_association %}
    <div><i class="fas fa-circle text-danger"></i> Votre compte association est inactif.</div>
    {{ content.flag_role_association }}
  {% endif %}

  <span class="border-top mt-4 mb-4"></span>

  <p>Les boutiques éphémères vous permettent d'exposer les créations des artisans présents sur la plateforme (pas de vente en ligne).</p>
  {% if 'pop_up_store' in user.getroles %}
    <div><i class="fas fa-circle text-success"></i> Votre compte boutique éphémère est actif.</div>
  {% elseif 'pop_up_store' not in user.getroles and is_flagged_role_pop_up_store %}
    <div><i class="fas fa-circle text-warning"></i> Votre compte boutique éphémère est en attente.</div>
  {% elseif 'pop_up_store' not in user.getroles and not is_flagged_role_pop_up_store %}
    <div><i class="fas fa-circle text-danger"></i> Votre compte boutique éphémère est inactif.</div>
    {{ content.flag_role_pop_up_store }}
  {% endif %}

  <span class="border-top mt-4 mb-4"></span>

  <p>Si vous êtes artisans, nous serions ravis de vous accueillir sur notre marketplace. Nous facturons une commission de 10% sur chaque vente. Vous recevrez une facture à chaque début de mois, si vous réalisez des ventes le mois précédent. Plus d'infos sur <a href="/node/271">cette page</a>.</p>
  <p>Pas de vente = Rien à payer</p>
  {% if 'marchand' in user.getroles %}
    <div><i class="fas fa-circle text-success"></i> Votre compte artisan est actif.</div>
  {% elseif 'marchand' not in user.getroles and is_flagged_role_artisan %}
    <div><i class="fas fa-circle text-warning"></i> Votre compte artisan est en attente.</div>
  {% elseif 'marchand' not in user.getroles and not is_flagged_role_artisan %}
    <div><i class="fas fa-circle text-danger"></i> Votre compte artisan est inactif.</div>
    {{ content.flag_role_artisan }}
  {% endif %}

</div>

```

The above code works but the problem is that it is cached. I have to face `drush cr` for the conditions in TWIG to be visible in my page.

How can I correct this ?

# Answer
> 0 votes
Based on what I see here, something like the following might do the trick:

```
use Drupal\Core\Cache\Cache;

/**
 * Implements hook_preprocess_HOOK() for user.html.twig.
 */
function bootstrap_subtheme_front_office_old_preprocess_user(&$variables) {
  $flag_service = \Drupal::service('flag');
  $user_to_flag = $variables['user'];

  $flag_ids = [
    'role_association' => 'is_flagged_role_association',
    'role_pop_up_store' => 'is_flagged_role_pop_up_store',
    'role_artisan' => 'is_flagged_role_artisan',
  ];

  $invalidate_cache = FALSE;
  foreach ($flag_ids as $flag_id => $var_flag) {
    if ($flag = $flag_service->getFlagById($flag_id)) {
      if ($flag_status = $flag_service->getFlagging($flag, $user_to_flag)) {
        $variables[$var_flag] = $flag_status;
        $invalidate_cache = TRUE;
      }
    }
  }

  if ($invalidate_cache) {
    $cachetag = "user:{$user_to_flag->id()}";
    Cache::invalidateTags([$cachetag]);
  }
}

```

Maybe there's a better hook to call that cache invalidation like when the flag action is made.

---
Tags: 8, theming, users, caching, flags
---


title: Changing the output of a views field

text:
# Question
Title: Changing the output of a views field
I'm using Drupal 8, with a view of type Log entries. I'm trying to rewrite the output so it adds additional text but the field is already formatted by the time it gets to the twig file. Where is the field being rendered? I'd like to override the rendering for just this field in just one view. Thanks.

# Answer
> 2 votes
**Use replacements** ..

You can simply edit the field and tick the box Next to "Exclude from display" this will hide the field, then you can Add a new field of type "Custom text"

In the "Text" section scroll until you see "REPLACEMENT PATTERNS" expand that and grab the `{{ field_name }}` \< the field you want to use.

then in the text section put

```
{{ field_name }} your additional text.

```

---
Tags: views
---


# Question
Title: Is there any way to capture only the updates from "drush cex"?
I did a cex to "reset" my config being exported. I then made a bunch of changes to a bundle. Now when I do a new cex I see only the yml files containing my most recent changes. Is there any way to capture JUST these files (into a new folder)?

If I specify a --destination; it dumps my entire config there. Not what I want.

# Answer
Take a look at Config partial export module

> It is able to export to a tarball only modified configuration files.

For available commands in drush:

```
drush cpex --help

```
> 2 votes

---
Tags: drush
---


# Question
Title: Translate dynamic variable that is an array in twig or using t()
How do I translate this in twig? I have this variable in twig that is an array:

```
$array = [
  ['number' => 7, 'name' => 'foo'],
  ['number' => 8, 'name' => 'bar'],
  ['number' => 10, 'name' => 'baz'],
  // ... and so on and so forth
]

```

Would like it to be something like this:

> The variables are 7 times for foo, 8 times for bar, and 10 times for baz.

Or

> The variables are 7 times for foo and 10 times for baz.

Or

> The variable is 7 times for foo.

Tried with something like this:

```
    {% set last = array|last %}
    {% set array = array|slice(0, array.length - 1) %}

    {% trans %}
      <p>The variables are
        {% for i in array %}
          {{ i.number }} times {{ i.name }},
        {% endfor %}
        , and {{ last.number }} number of {{ last.name }}
      .</p>
    {% endtrans %}

```

The error I am getting is:

> The text to be translated with "trans" can only contain references to simple variables

Could also use `t()` although I'm not sure how as well. Also tried with something like this:

```
{% for i in array %}
    {% trans %}{{ i.number }} times {{ i.name }},{% endtrans %}
{% endfor %}
{% trans %}, and {{ last.number }} number of {{ last.name }}{% endtrans %}

```

Although it doesn't look good from the "User interface translation" page as you would have to translate them separately.

Thanks!

# Answer
> 0 votes
I think it's better to split the content in translatable parts:

```
  <p>{% trans %}The variables are{% endtrans %}
    {% for i in array %}
      {% trans %}{{ i.number }} times {{ i.name }}{% endtrans %},
    {% endfor %}
    , {% trans %}and {{ last.number }} number of {{ last.name }}{% endtrans %}
  .</p>

```

Haven't tested this so I'm not sure if it works. Also, you could use trans as a filter, check this question.

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


# Question
Title: How to have users set a value for a flag field upon flagging?
I added a field (**Text list** of options) to my flag. But, when a user flags the content, they don't get a chance to set the value for the field (the flagging form does not show the field to edit). Instead, the user has to flag the node, then go to the flag edit page, then set the value, and then re-save the node. Instead, I want the user to set the value of the field upon flag creation.

In other words, I want to use flags like I use nodes. With nodes, when you add a field to a node, that field is shown on the node creation form, and users with permission to add the node can also set the value for the fields on the node.

How do I do this in Flag?

# Answer
You need to read the flag admin options more carefully.

On `/admin/structure/flags/manage/MYFLAG`, under **Display options**, choose "Field Entry Form". This will give users the options to enter flag fields before the flag is saved.
> 0 votes

---
Tags: flags
---


title: Submissions using JSON:API POST method

text:
# Question
Title: Submissions using JSON:API POST method
I would like post submissions in webform using core's JSON:API. I've created a webform, then added the fields I need. I've installed JSON:API Extras to be able customize some API properties per resource. I'm able to create submissions, override the remote address, post the referenced entity except to the field values.

I've also tried a couple of data formats, but still no luck.

Here's what I've done so far.

**Headers**

* api-key: 4bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* Content-Type: application/vnd.api+json
* Accept: application/vnd.api+json

**POST URL**

```
http://example.com.com/api/webform_submission/contact

```

**POST data**

```
{
    "data": {
        "type": "webform_submission--contact",
        "attributes": {
            "entity_type": "node",
            "entity_id": "5",
            "remote_addr": "",

            // Format 1
            "email": "example@example.com",
            "name": [{"value": "Loremipsum"}],

            // Format 2
            "data": [{
                "email": "example@example.com",
                "message": ["Please ignore this email."],
                "name": [{"value": "Loremipsum"}],
                "subject": "Testing contact webform"
            }],

            // Format 3
            "data": [{
                "email": "example@example.com",
                "message": "Please ignore this email.",
                "name": "Loremipsum",
                "subject": "Testing contact webform"
            }]
        }
    }
}

```

**Results**

```
{
    "jsonapi": {
        "version": "1.0",
        "meta": {
            "links": {
                "self": {
                    "href": "http://jsonapi.org/format/1.0/"
                }
            }
        }
    },
    "data": {
        "type": "webform_submission--contact",
        "id": "035de1b3-01ef-49a9-89ab-3bf8b2b641ea",
        "links": {
            "self": {
                "href": "http://example.com.com/api/webform_submission/contact/035de1b3-01ef-49a9-89ab-3bf8b2b641ea"
            }
        },
        "attributes": {
            "serial": 211,
            "drupal_internal__sid": 62,
            "token": "xjIywCTtW9gqpgnYIAtVIIO_LpUB7pKIKnYfjIf1Z8U",
            "uri": "/api/webform_submission/contact",
            "created": "2020-11-05T01:26:51+00:00",
            "completed": "2020-11-05T01:26:51+00:00",
            "changed": "2020-11-05T01:26:51+00:00",
            "in_draft": false,
            "current_page": null,
            "remote_addr": null,
            "langcode": "en",
            "entity_type": "node",
            "entity_id": "5",
            "locked": false,
            "sticky": false,
            "notes": null
        },
        "relationships": {
            "uid": {
                "data": null,
                "links": {
                    "self": {
                        "href": "http://example.com.com/api/webform_submission/contact/035de1b3-01ef-49a9-89ab-3bf8b2b641ea/relationships/uid"
                    }
                }
            },
            "webform_id": {
                "data": null,
                "links": {
                    "self": {
                        "href": "http://example.com.com/api/webform_submission/contact/035de1b3-01ef-49a9-89ab-3bf8b2b641ea/relationships/webform_id"
                    }
                }
            }
        }
    },
    "links": {
        "self": {
            "href": "http://example.com.com/api/webform_submission/contact"
        }
    }
}

```

Drupal version: 9.x

Webform version: 6.0.0-alpha20

JSON:API Extras version: 8.x-3.16

Am I missing something?

# Answer
> 1 votes
According to the issue, Support submitting webforms through JSON API Closed (won't fix)

> POSTing a WebformSubmission entity requires an administrative permission (or requires crafting custom access hooks)

The expectation is to use the contrib module Webform REST instead.

---
Tags: webforms, 9
---


title: Sort entityQuery by date published

text:
# Question
Title: Sort entityQuery by date published
I'm attempting to perform a query to retrieve only the three most recent nodes of a certain content type.

```
$query = \Drupal::entityQuery('node')
    ->condition('type', 'blog_post')
    ->sort('field');
$nids = $query->execute();

```

I understand that I can use sort to specify the field I want the results to be sorted by. But how would I sort by the dates the nodes were published?

# Answer
> 9 votes
'created' was the field. I was able to find this by looking at the fields being used in Core\Modules\node\src\Entity\Node.php

# Answer
> 23 votes
```
$query = \Drupal::entityQuery('node')
                ->condition('status', 1)
                ->sort('created' , 'DESC');

```

# Answer
> 1 votes
```
\Drupal::entityQuery('node')
    ->condition('status', 1)
    ->sort('changed' , 'DESC');

//Available fields
public function fields() {
  $fields = array(
    'nid' => $this
      ->t('Node ID'),
    'type' => $this
      ->t('Type'),
    'title' => $this
      ->t('Title'),
    'body' => $this
      ->t('Body'),
    'format' => $this
      ->t('Format'),
    'teaser' => $this
      ->t('Teaser'),
    'node_uid' => $this
      ->t('Node authored by (uid)'),
    'revision_uid' => $this
      ->t('Revision authored by (uid)'),
    'created' => $this
      ->t('Created timestamp'),
    'changed' => $this
      ->t('Modified timestamp'),
    'status' => $this
      ->t('Published'),
    'promote' => $this
      ->t('Promoted to front page'),
    'sticky' => $this
      ->t('Sticky at top of lists'),
    'revision' => $this
      ->t('Create new revision'),
    'language' => $this
      ->t('Language (fr, en, ...)'),
    'tnid' => $this
      ->t('The translation set id for this node'),
    'timestamp' => $this
      ->t('The timestamp the latest revision of this node was created.'),
  );
  return $fields;
}

```

> Source

---
Tags: 8, entities
---


# Question
Title: How to do views random sort for all the items in a pager?
I created five nodes:

* Apple
* Pear
* Kiwi
* Orange
* Cheese

Then I created a view with the following settings:

* Show content of type **Fruit**
* Display 1 item per page, use mini pager
* Sort: **Global: Random**

Now I flip through the nodes one at a time as an authenticated user.

There should be five nodes, but I don't see all 5 nodes in a random order; instead, I see some nodes twice, and other nodes not at all.

**Things I tried**

* In the query settings for the view, I have tried toggling DISTINCT on/off and rebuilding the cache; it appears to have no effect.
* I tried setting the views caching to time-based (1 hour), thinking that this would give me all the nodes arranged in a random order that changes each hour, but I still get some nodes twice and others not at all

Is there a way to sort the nodes in a random order and yet still go through the entire set?

**Potential problems with random sorting that don't affect this use case**

# Answer
> 0 votes
After struggling with this, it seems that **when you use a pager, random sort can return the same item on multiple pages**. In other words, Views random sort will randomly generate a list of results on each page, and you can get repeat results among different pages.

So what do you do if you want a random sort of all view results (on all pages of the pager) with no repeats?

You have to do it yourself.

Here's what I did.

First, add an integer field, **Random Int**.

Then, in `hook_node_presave()`, set the field to a random value.

```
function MYMODULE_node_presave(NodeInterface $node) {
  // Randomize the order in which missed cards appear.
  $node->set('field_int_random', MYMODULE_randomize_repeat_sort());
}

/**
 * Returns a number between 1 and 1000 for randomizing sort.
 *
 * @return int
 *   A random number from 1 to 1000.
 */
function MYMODULE_randomize_repeat_sort() {
  return mt_rand(1, 1000);
}

```

Finally, in your view, sort by the **Random Int** field instead of Views random sort.

Of course, the method here only randomizes the nodes on node save. For my use case, that is sufficient, but if you want a random sort per user, etc., you will need to do it a different way.

# Answer
> 0 votes
In your view under filter criteria, use Aggregation settings -\> group results together.

This should remove your duplicate results

---
Tags: 8, views
---


# Question
Title: In hook_form_alter(), how can I access the entity that is being flagged?
In `hook_form_alter()`, I want to load the entity being flagged so that I can do some processing based on the field values of that entity.

However, I can't find an entity object using `kint($form)`. I know it must be there somewhere because the flag is correctly attached to the entity.

```
function MYMODULE_form_flagging_MYFLAG_add_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  kint($form);
  kint($form_state);
  // Where is the flagged entity object id?
}

```

On the flagging object, after the flagged has been saved, the entity id can be accessed like this:

```
    $flagged_entity_id = $flagging->get('entity_id')->value;

```

However, in `hook_form_alter()`, when the flag has not yet been saved for the first time, I can't find the `entity_id` in `$form`.

I thought it might be in `$form_state`, but I got a NULL result for `$form_state->get('entity_id')`.

# Answer
> 2 votes
Ok, thanks to leymannx and No Sssweat, I think I finally understand how to get the entity from a form.

To get the entity being flagged inside a flag, this is what I had to do:

```
function MYMODULE_form_flagging_MYFLAG_add_form_alter(&$form, FormStateInterface $form_state, $form_id) {
      $flagging_entity = $form_state->getFormObject()->getEntity();
      $flagged_entity_id = $flagging_entity->get('entity_id')->value;
}

```

---
Tags: 8, forms, flags
---


title: Token path to file URL, filename, etc.?

text:
# Question
Title: Token path to file URL, filename, etc.?
I'm writing a Rule that sends an email when a user uploads a file to a node. How would I output the file's URL and filename in the body of the email?

First, some things to note:

1. This is an Entityform node
2. The File Upload field is a mulit-value field
3. Drupal 7 site

In rules, when I use the replacemement token for the File Upload field...

`[entityform:field-file-upload]`

...it returns...

`property 0, property 1, property 2`

There are three files uploaded to this Entityform node, so it appears that Drupal is accurately reporting the correct number of files. But this is all the info I've been able to can extract.

I've tried to change the token in few different way, like these:

```

[entityform:field-file-upload:file:url]

[entityform:field-file-upload:0:file:url]

[entityform:field-file-upload:url]

[entityform:field-file-upload:0:url]

```

These all return nothing. What is the corrent token string to return URL, filename, etc.?

# Answer
> 0 votes
Through some trial and error and some further digging, I figured it out. Here's what works:

URL: `[entityform:field-file-upload:0:file:url]`

Filename: `[entityform:field-file-upload:0:file:name]`

Upload date: `[entityform:field-file-upload:0:file:timestamp:short]`

Increment the `0` to return more files from the multi-value array of uploaded files.

Once I had the basic syntax, the Drupal List of Tokens page was particularly useful.

---
Tags: nodes, files, rules, tokens
---


# Question
Title: Why can html.twig files be placed outside the templates folder?
In Drupal theme folder structure, there is written:

> Templates provide HTML markup and some presentation logic. Contrary to Drupal 7, in Drupal 8 template files (\*.html.twig files) must be stored in the 'templates' subfolder.

In my theme, I have a *styleguide* folder at the root. Drupal 9 finds template files, such as *mytheme/styleguide/components/10-atoms/form/input.html.twig*, in this folder.

Drupal 9 will use this input.html.twig file despite it's not in the mytheme/templates folder.

# Answer
Ok, I have found a solution, I just need to add in my settings.php the "styleguide" folder in the ignore directories

```
$settings['file_scan_ignore_directories'] = [
  'node_modules',
  'bower_components',
  'styleguide'
];

```
> 1 votes

---
Tags: theming, 9
---


# Question
Title: How to create a new entity with default values if not passed?
Hello everyone how are you?

I created a new configEntity called Modal with 3 fields:

1. Label
2. Body
3. Auto Open

To create a new Modal I'm using this code:

```
$modal = \Drupal::entityTypeManager()->getStorage('modal')->create();

$modal->setLabel('Modal Title');
$modal->setBody('Modal Content');
$modal->setAutoOpen(TRUE);
$modal->save();

```

OK! It works!

But now I don't want to pass "auto-open" and I this value with TRUE as default. Like this:

```
$modal = \Drupal::entityTypeManager()->getStorage('modal')->create();

$modal->setLabel('Modal Title');
$modal->setBody('Modal Content');
$modal->save();

```

Note that there is no "Auto-Open" and it inserts a new Modal with "auto-open" = FALSE

My goal is; if you don't pass "auto-open" this field is filled with TRUE by default.

Do you know how can we do this?

Thank you so much, everyone

# Answer
For entities in general, set default values by adding preCreate() to your entity class:

```
  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
    parent::preCreate($storage_controller, $values);
    $values += [
      'auto_open' => TRUE,
    ];
  }

```

---

In this specific case, define a class property with the same name as the field, which defaults to TRUE:

```
  /**
   * Auto Open.
   *
   * @var bool
   */
  protected $auto_open = TRUE;

```
> 3 votes

---
Tags: entities
---


# Question
Title: What does the checkbox "link to content" do?
I am creating some custom content but have not got round to creating the views yet. When looking at the layout tab I see this

What content does this refers to? All my Plain text fields have this checkbox, but none of the others.

# Answer
It seems you are in display settings of a content type and these are the fields it has. *Link to content* in this context means that when this field is displayed it will link back to the parent node. It will be displayed as link similar to this

```
<label>Surname</label><a href="/node/2">This surname</a>

```

where the `/node/2` would be the url of the node you are actually viewing

NOTE: if you enable this on the default content type view mode it will not make much sense as it will link on the page you are currently on (`node/2`). This makes sense for example when the node is displayed as part of a view and in that case if clicking on the link will take you to the full node.
> 0 votes

---
Tags: theming
---


# Question
Title: How to add filters to a custom entity type listing page
I have a custom entity type and a list of entities of that types shown on a standard listing page.

But I need to have some filters similar to what we have on a node list page

How could I do that ?

# Answer
Yes, everybody keeps mentioning Views. But it can be done easily without Views.

Basically, you need, in addition to your `EntityListBuilder`, a form that will expose the filter. Just create a usual form extending `FormBase`, building whatever UI you need (eg. a dropdown with items to select from, and a **Filter** submit button).

Your list builder will first create that form and then use it together with the rendered entity list:

```
public function render() {
  $build['form'] = \Drupal::formBuilder()->getForm('Drupal\your_module\Form\YourFilterForm');
  $build += parent::render();
  return $build;
}

```

In the submit handler of the form, you redirect to the same URL but with the filter query variables added:

```
public function submitForm(array &$form, FormStateInterface $form_state) {
  $value = $form_state->getValue('your_var_name');
  $query = ['your_var_name' => $value];
  $form_state->setRedirect('route_name_of_your_entity_list', $query);
}

```

Also, if you want a **Reset** button, just do the same redirect without the query, thus clearing it.

In your entity list builder, you have a `getEntityIds()` that's responsible for loading the entities. You probably didn't override it at all to get the full list. But you can override, get the current filter and only load those matching the filter:

```
protected function getEntityIds() {
  $value = \Drupal::request()->get('your_var_name');
  $query = \Drupal::entityQuery($this->entityTypeId);
  $query->condition('your_var_name', $value);
  return $query->execute();
}

```

Or, if there is no actual filter, just call the original `parent::getEntityIds();`.
> 2 votes

---
Tags: 8, entities
---


title: Ajax form add library on callback

text:
# Question
Title: Ajax form add library on callback
I'm having an AJAX form, which on submit fires a callback function where I want to attach my library.

Here's the submit button:

```
$form['actions']['submit'] = [
    '#type' => 'submit',
    '#value' => 'Submit',
    '#button_type' => 'primary',
    '#name' => 'calculate',
    '#submit' => ['::submitForm'],
    '#ajax' => [
      'callback' => [$this, 'submitFormCallback'],
      'wrapper' => 'my-form-id',
    ],
];

```

When the **submitFormCallback** is called I attach my library using **AjaxResponse** and its **addAttachments** like this:

```
$ajax_response->addAttachments([
  'library' => ['my_module/library_name']
]);

```

The problem is when the AJAX is completed the whole page's layout is destroyed. When I do NOT attach the library to AJAX response everything seems to work fine. (I've already tried to empty my JS files in **my\_module/library\_name** so the javascript won't affect any DOM elements, but the result is the same.

Is there any problem with the way I attach the library to **AjaxResponse** that may cause the broken layout?

# Answer
> Is there any problem with the way I attach the library to AjaxResponse that may cause the broken layout?

I guess so. This is how core does it when its an AJAX response, it attaches it to the form like this:

```
$form['#attached']['library'][] = 'my_module/library_name';
$ajax_response->setAttachments($form['#attached']);

```
> 1 votes

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


# Question
Title: How to use the node title in the "Override title" field of contextual filter
Situation:

* A view has a contextual filter on a field named `type`.
* The view sorts by date and has the pager set to display 1 item (I want only the newest node).
* I want to show `type` \+ the node title as the view title.
* So, what I want to put in the **Override title** field is

{{ arguments.field\_type\_value }} {{ title }}

But `{{ title }}` doesn't work. It outputs nothing. This isn't a surprise because (a) `{{ title }}` isn't in the Replacement Patterns list and (b) I assume the view expects to display multiple nodes, so there isn't just one `{{ title }}` to display.

Is there a straightforward way to do what I want to do using a view as I'm doing? There are reasons why I want to use a view.

# Answer
Simply add title as a field and checkmark hide from display, now `{{ title }}` should work despite not being listed as replacement pattern.

Also make sure your view's title is set to none

---

Alternatively, you could also solve it by not overriding it in the contextual filter settings and instead overwrite it directly in the view's title.

Add title and type as fields, hide them if you want/need to.

---

But, if you're using teaser

The above two solutions won't work, so you can solve it programmatically:

```
/**
 * Implements hook_views_post_render()
 */
function mymodule_views_post_render($view) {
  if ($view->id() == "view_name" && $view->current_display == 'page_1') {
    $node = $view->result[0]->_entity;
    $new_title = $node->type->entity->label() . ' ' . $node->getTitle();
    $view->setTitle($new_title);
  }
}

```
> 3 votes

---
Tags: 8, views
---


# Question
Title: How to get the destination nid from an URL object
In a preprocess function I want to access the destination node id via the URL object

I cannot find any method that will return the node id for me but I can clearly see that it holds the node id. (see attached)

Any idea how I can get the node id without going the long way of generating it from the URL path?

# Answer
> 3 votes
Looks like you're using the latest Devel, 4.0.1, which sadly currently doesn't show the available methods tab unless you patch it.

If you had the available methods tab, you would've seen that you can retrieve using the public method getRouteParameters

```
$nid = $url_object->getRouteParameters()['node'];

```

---
Tags: 8, uri
---


# Question
Title: Delete a record from a specific table when a submission is deleted
Is it possible to delete a record from a specific table when a webform submission is deleted?

I know it's possible in Drupal 7, with `hook_webform_submission_delete()`. The code I would use in Drupal 7 is similar to the following one.

```
function app_webform_submission_delete($node, $submission) {
  $id = $submission->data[7][0];
  // Delete a record from x table when a submission is deleted.
  db_delete('x_table')
    ->condition('type', "submission_type")
    ->condition('nid', $id)
    ->condition('sid', $submission->sid)
    ->execute();
}

```

What would the code for Drupal 8 be?

My question, in fact, is: How to respond to a specific webform submission deletion in drupal 8? In my code when a webform is submitted i insert sid with information in a custom table. When a specific submission is deleted i want to delete as well the record inserted in the custom table that have the deleted submission sid.

# Answer
> 0 votes
Please be very careful when executing direct delete queries on a table. I am not sure if your `x_table` is a "Drupal" table or a custom table that you had created. Preferably you should use the Drupal API to ensure records for entities or such are deleted gracefully.

If the record that you are trying to delete is an entity ie. a node, then you would do something like:

```
$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
$node->delete();

```

Alternatively use the `database` service for non-entities:

```
\Drupal::database()->delete('x_table')
  ->condition('foo', 'bar')
  ->execute();

```

You can put this code in your implementation of hook `hook_webform_submission_delete()`.

---
Tags: 8, webforms
---


# Question
Title: How can I send mail containing rendered entity from referenced field?
How do I code a function for sending mail containing a rendered entity that is referenced from a field?

I have content type A that contains static information, and content type B that users create and reference to the corresponding content type A node instead of writing everything manually. In a custom module I have some code for sending mail notifications containing info in a content type B node, but now the client wants some info from the referenced content type A node.

The line of code that I have a problem is this:

```
$avtal_id = $node->field_avtalsnummer['und'][0]['value'];

```

`field_avtalsnummer` is the reference field in content type B that points to a node of type A and `$avtal_id` is used in the mail (plain-text). All other fields in the custom module works fine, but for some reason that I don't fully understand I can't get this to work. If I change `value` to `target_id` i get the node ID but I can't get the value. Title does not work either. Do I need some code to load the entity first? The optimal solution for me would be to get the info from the referenced field and to display a custom view mode so that I can customise the mail notification accordingly to my clients demands, but I can't even get the value of of the referenced field to work so I'm running out of ideas. Help is very appreciated!

# Answer
You need to use `target_id` to get the node id, then load the node and get the fields values you want.

```
$avtal_id = $node->field_avtalsnummer[LANGUAGE_NONE][0]['target_id'];
$avtal_node = node_load($avtal_id);

```
> 1 votes

---
Tags: 7, entities, emails
---


# Question
Title: "The service 'serializer' has a dependency on a non-existent service 'entity.manager'"
I have a multidomain site and recently I update from D8 to D9.

In my multidomain site I have 2 websites, sharing core and modules, but with different DB.

One of them after update works correctly but the other one not.

I got this error:

> The service "serializer" has a dependency on a non-existent service "entity.manager"

In this last 2 days I search and tried some fixes but no luck.

What I tried:

* uninstall contrib modules
* disable views
* uninstall/delete paragraphs
* tried a couple of patches

If I return to D8 everything works good.

My modules list:

Dind't find anything related with theses modules and current error.

Any thouths about this migration error?

Thanks in advance :)

# Answer
After @leymannx and @Kevin tips I could fix my problem, I will leave step by step what I have done, hope help anyone else :)

1. Set my sites do Drupal 8 again
2. Search inside my modules folder if any module use "entity.manager"
3. Update those modules according module page
4. Update D8 to D9 with composer
5. Run update.php (this give couple more errors about compatibility in some modules)
6. Update those modules

I have a couple of custom modules and custom theme, in those I replace

> core: ^8.8

with

> core\_version\_requirement: ^8.8 || ^9

Also have couple more contrib modules with the same problem, so I created a patch for those modules.

After all that could run update.php and everything works as expected.
> 2 votes

---
Tags: upgrading, 9
---


# Question
Title: How to check the Webform submission values in a twig template
I have an Webform with an option element, (option\_one), with 6 options.

Below this are 2 option elements with 5 and 2 options.

These 2 option elements have a conditional statement to display if the correct option is selected on the, (option\_one), option element.

Added email handlers to the form for the site admin and the submitter.

Using the default email format, all display as per the Webforms default email output, with the correct option element hidden as per the coditional statements.

**Goal**

Build my own twig template to enable me to theme the email using inline styles.

Below is the code used to check for the selected options.

**UPDATE**

Question simplified:

How to compare a Webform token with a given value in a twig 'if' statement?

{% if webform\_token('\[webform\_submission:values:airports\_to\_radio\]', webform\_submission, \[\], options) == Heathrow %}

**Don't want or need to go and build a submit handler via hook\_form\_alter()**

```
{% if webform_token('[webform_submission:values:airports_to_radio]') == 'Heathrow' %}
<div style="display: flex;width: 50%; background-color:cadetblue;color: #000;">
  <p style="padding-left: 10px;">{{ webform_token('[webform_submission:values:heathrow_terminals_to]', webform_submission) }}</p>
</div>
{% endif %}

{% if webform_token('[webform_submission:values:airports_to_radio]') == 'Gatwick' %}
<div style="display: flex;width: 50%; background-color:cadetblue;color: #000;">
  <p style="padding-left: 10px;">{{ webform_token('[webform_submission:values:gatwick_terminals_to]', webform_submission) }}</p>
</div>
{% endif %}

```

This works to a point. Both sections of the twig template do not display, so i assume that the syntax is correct, but not using the correct comparison.

Any help to get the correct syntax for the {{ if }} statement would be great, or any links to information on the web would also be great.

Webform source code below.

```
airports:
  '#type': fieldset
  '#title': Airports
  airports_to_radios:
    '#type': radios_other
    '#title': Airports
    '#options':
      Heathrow: Heathrow
      Gatwick: Gatwick
      Stansted: Stansted
      Southend: Southend
      'London City': 'London City'
      Luton: Luton
    '#options_display': buttons
    '#other__option_label': Hotel
    '#other__title': Hotel
    '#other__placeholder': Hotel
  heathrow_terminals_to:
    '#type': radios
    '#title': 'Heathrow Terminals'
    '#options':
      'Terminal One': 'Terminal One'
      'Terminal Two': 'Terminal Two'
      'Terminal Three': 'Terminal Three'
      'Terminal Four': 'Terminal Four'
      'Terminal Five': 'Terminal Five'
    '#options_display': buttons
    '#states':
      visible:
        ':input[name="airports_to_radios[radios]"]':
          value: Heathrow
  gatwick_terminals_to:
    '#type': radios
    '#title': 'Gatwick Terminals'
    '#options':
      'South Terminal': 'South Terminal'
      'North Terminal': 'North Terminal'
    '#options_display': buttons
    '#states':
      visible:
        ':input[name="airports_to_radios[radios]"]':
          value: Gatwick
  customer_email:
    '#type': email
    '#title': 'Customer Email'
    '#default_value': test@localhost

```

# Answer
> 0 votes
Adding `:raw` to your webform submissions value has worked for me.

```
{% if webform_token('[webform_submission:values:airports_to_radio:raw]') == 'Heathrow' %}

```

---
Tags: theming, webforms
---


# Question
Title: Mocking Settings (settings.php) within Unit tests
Drupal's `Settings` class is marked final and has no interface, meaning traditional PHPUnit mocking techniques will not work out of the box. Is it necessary to install third-party tools to be able to mock this or is there another way?

# Answer
> 7 votes
At first glance `Settings` appears to be read-only, however the constructor is quite forgiving in its parameters. We can construct a fake settings structure like so:

```
$site_settings = [
  'http_services_api' => [
    'auth_services' => [
      'title' => 'Auth Services',
      'config' => [
        'base_uri' => 'https://demo.api-platform.com/auth'
      ],
    ],
    'resource_services' => [
      'title' => 'Resource Services',
      'config' => [
        'base_uri' => 'https://demo.api-platform.com/books'
      ],
    ],
  ],
];

new Settings($site_settings);

```

This is alluded too here but never fully described.

Edit: I have added an example to the docs linked.

---
Tags: testing, 9
---


# Question
Title: Is there a browser-side validation passed event I can listen for?
Is there a JS event that my own custom code can listen for to determine that client-side / browser validation of a form has passed?

i.e. That no messages like this have occurred: "Please fill in this field" because a field was empty.

If there such an event that can be listened to then my own JS could handle the POST submission and then replace the form with a thank you message, in-situ / in place on the same page.

What I don't want to do is have my code run whether the form submission input by the user is valid or not. In other words I don't want to display a thank you message if they've not given valid data. That's why I need an event to say validation passed.

This to me is a better solution to say "thank you" rather than redirecting to content that can itself be indexed and accessed "outside" of the form submit situation, even if a module like rabbit\_hole is used.

Looking for a Drupal 8 or 9 solution for myself but tagged with 7 to encourage answers for those who also might want an answer but for Drupal 7.

# Answer
Drupal doesn't have a browser-side validation framework as it does with the back-end form validation handlers. The "Please fill..." message is the browser enforcing the `required` property.

If you'd like to hook into those validation events, you can bind event listeners on specific form elements for `invalid` events. If you want to take action on a submit click, the `checkValidity()` method can be executed on form field DOM objects.

See the MDN docs on the constraint validation API for more info.
> 3 votes

---
Tags: forms, javascript
---


# Question
Title: Error: Call to a member function addWhere() on array in hook_views_query_alter()
I'm getting the error 'Call to a member function addWhere() on array' in my hook. Any thoughts? I just need to add WHERE clause to my query.

```
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implementation of hook_views_query_alter
 *
 * @param $view
 * @param $query
 */
function MYMODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'search_filter' && $view->getDisplay()->display['id'] == 'block_1') {
    $field = 'node__field_country.field_country_target_id';
    $value = 'somevalue';
    $operator = '=';
    $query->addWhere(0, $field, $value, $operator);

```

# Answer
> 2 votes
Try to add your condition to conditions array in the where `$query->where` like the following:

```
/**
 * Implements hook_views_query_alter().
 */
function myModule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() === 'search_filter' && $view->current_display === 'block_1') {
    $field = 'node__field_country.field_country_target_id';
    $value = 'someValue';
    $operator = '=';
    if (isset($query->where[1]['conditions'])) {
      $query->where[1]['conditions'][] = [
        "field"    => $field,
        "value"    => $value,
        "operator" => $operator,
      ];
    }
  }
}

```

Read this Article it's very useful.

# Answer
> 0 votes
Try This code, In drupal 8 we cannot use 'function myModule\_views\_query\_alter(ViewExecutable $view, QueryPluginBase $query) { '. Refer Below code, This works for me, Above code not worked for me. Hope this will helpfull.

```
function Hook_views_query_alter($view, $query) {
   if ($view->id() == 'content') {
      $field = 'node_field_data.langcode';
      $value = array('en');
      $operator = 'IN';
      $query->where[1]['conditions'][] = [
        "field"    => $field,
        "value"    => $value,
        "operator" => $operator,
      ];
  }
}

```

---
Tags: views, 8, hooks
---


# Question
Title: how to add exposed drop-down filter with options in a view of custom table
In a drupal 7 website, I have a view that is based on a custom table. I have a **status** column in that custom table, which is type of integer and has 0 or 1 value, and in a view I want to add exposed filter with dropdown, with values somehow like below

```
$options[0] = 'No';
$options[1] = 'Yes';

```

So that a user can choose a value from dropdown and filter out data.

So in my views.inc file I have implemented hook\_views\_data(), then I have added the following code to make that field accessible in a view

```
$data['custom_users']['status'] = array(
      'title' => t('User Status'),
      'help' => t('User Status'),
      'field' => array(
        'click sortable' => TRUE,
      ),
      'filter' => array(
        'handler' => 'views_handler_filter_numeric',
      ),
      'sort' => array(
        'handler' => 'views_handler_sort',
      ),
  );

```

Now when I am trying to add exposed filter using this field I am not able to make it available as dropdown. I am only getting a textfield as exposed filter for this field.

Any help will be appreciated.

# Answer
> 0 votes
You can use `hook_form_alter()` for this. simply change the field type to select and add your options. here is my working code

```
// implements hook_form_alter
function project_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id === 'views_exposed_form') {
    $view = $form_state['view'];
    // add your view name in 'view_name'.
    if ($view->name === 'view_name') {
      // Checking status field is exists or not.
      if (isset($form['status'])) {
        $form['status']['#type'] = 'select';
        $form['status']['#empty_value'] = '';
        $form['status']['#empty_option'] = 'All';
        $form['status']['#options'] = array('0' => 'No', '1' => 'Yes');
        $form['status']['#size'] = 1;
        $form['status']['#attributes'] = array('id' => 'status-list');
      }
    }
  }
}

```

hope this will work :).

---
Tags: 7, views
---


# Question
Title: Different responsive image per breakpoint
I have the following scenario - the main page banner should have at any time 1 of 3 images displayed at a given viewport size. These images are art-directed, that is to say, that will differ in content and layout and are created with desktop, tablet and mobile in mind. (All of this is despite my protests).

I'm wondering what are the options for requesting the correct image at the appropriate viewport size? (Optimisation is very much a concern here! I don't want to serve 3 images only to use 1.) My understanding when it comes to D8 and responsive images is that D8 will create versions of the same image for the srcset rather than giving the option to serve different images at different viewport sizes.

So what are my options here? Perhaps the best option is to have 3 image fields that are outputting directly into a srcset in a banner template.

# Answer
Are they completely different images?

Then I'd use Paragraphs module and create a heavily customized template outputting your different images as `<source srcset="..." media="">` inside a single `<picture>` tag. Modern browsers will only download the correct version for the visitors viewport. (Manually add a polyfill library if required.)

Is there one large source image rendered with different focal points or different crop areas (Modules "Focal point" or "Image widget crop")?

Then I'd create a specific breakpoint group only for your banner. Create a responsive image style for this group and use `Select a single image style` for each individual breakpoint width. Drupal will then automatically render a similar markup as above and also add polyfills for older browsers.

In any case, definitely use a `<picture>` tag with multiple `<source srcset="...filename..." media="(...mediaquery...)">`s for art directed responsive images.
> 4 votes

# Answer
I came across the same problem, solved it, and wrote a tutorial about it.

The key is to use 2 different images (rendered as picture elements), positioned on the same place. An image uses the *Mobile only* responsive image style; the other images uses the *Desktop only* style. In this way, for any given viewport, there is only an image loaded and visible.

Implementing a hook, it's possible to add a *max-width* property to the *Mobile only* image style to make it not visible in desktop mode. Another can prevent the `<img>` tag from rendering.

```
function od_helper_preprocess_responsive_image(&$variables) {
  $responsive_image_style = $variables['responsive_image_style_id'];

  // Prevent mobile images to be shown for viewport-width > 767px.
  if ($responsive_image_style == "mobile") {
    if (isset($variables['sources'])) {
      foreach ($variables['sources'] as $source) {
        $value = $source["media"]->value();
        $value = $value . " and (max-width:767px)";
        $source["media"] = new AttributeString("media", $value);
      }
    }

  // Prevent fallback-image from rendering by removing src and alt and store it in data attributes. This fallback-images are later repaired depending on viewport size by js behaviour px1_ResponsiveImageContainerActivateFallbacks

  if ($responsive_image_style == "mobile" ||
      $responsive_image_style == "desktop") {

    $img = $variables["img_element"];
    $img["#attributes"]["data-src"] = $img["#uri"];
    $img["#attributes"]["data-alt"] = $img["#alt"];
    $img["#uri"] = "";
    $img["#alt"] = "";
    $variables["img_element"] = $img;
  }
}

```

We can later activate the appropriate image via JavaScript, depending on the viewport size. This is relevant for Internet Explorer which doesn't support the picture element.
> -2 votes

---
Tags: 8, media
---


title: Reverse entity reference lookup

text:
# Question
Title: Reverse entity reference lookup
I have a data structure where content type `research` has an entity reference field `scientists`.

The content type `scientists` does not have any `research` reference entity field though.

I can get all `scientists` that a particular `research` has through `research`.

But is there a way to get all `research`es one particular `scientist` has? When content types were created I wasn't involved, so I'm trying to see my options whether I can somehow click a checkbox to make this applicable.

When I tried to set up a field with type of `entity reference` and pointed it to research for scientists, they were empty.

Any help is highly appreciated.

# Answer
> 6 votes
> Is there a way to get all researches one particular scientist has?

Yes, search for the scientist target id:

```
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties([
  'type' => 'research',
  'field_scientists' => $scientist_id,
]);

```

---
Tags: entities, 9
---


title: hiding field -reference option limit

text:
# Question
Title: hiding field -reference option limit
Helloo ! I am using the D7 reference option limit module. I have two fields "primary" and "secondary" and I managed to reduce the choices of secondary based on the value of primary using this module. Both of them are required field in the user registration form.

I have a small question, when I set no value for primary, I get for the secondary field: No options are available for the current form values. Try selecting different values for the following fields: Primary. This is the good behaviour that I want but I want to hide secondary when no value is set for primary instead of displaying this message..

Is that possible? In other words I want to keep secondary hidden until primary has a value.

# Answer
> 0 votes
have you try any alter functions to implement ?

if you can try with alter then try `#states` in `hook_form_alter()` to hide field, if primary field default value is empty/null.

here is e.g

```
/**
 * @param type $form
 * @param type $form_state
 * @param type $form_id
 * Implements hook_form_alter()
 */
function hook_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'form_id') {
    // Hide secondary field.
    if (isset($form['secondary_field'])) {
      $form['secondary_field']['#states'] = [
        'visible' => array(
          'input[name="primary_field"]' => array('!value' => ''),
        ),
      ];
    }
  }
}

```

`'input[name="primary_field"]' => array('!value' => ''),` change this as per need i.e if its select list then `'select[name="primary_field"]' => array('!value' => ''),` etc.

hope this will solve your issue.

---
Tags: entities
---


# Question
Title: How to hide all nodes of a particular content type?
I have a site that used to run polls, but has stopped doing so. I'd like to keep the poll nodes in the database, just in case things change in the future, but otherwise hide the nodes. I guess this means returning a 403 or 404 if someone or a search bot requests the page, so that local users will be unable to see them and bots will eventually remove them from their indices.

I've disabled the poll module and disabled all the user permissions having to do with polls, so no new polls will get created. However, if someone requests the page via its URL, they get a normally-themed page with the poll's title (but no other content). I tried marking one of the polls as "not published", which comes pretty close to what I want: a normally-themed 403/access denied page. This would require my hacking the "published" state of all the poll nodes to "false", which I guess is better than nothing, but I was hoping for a hook function that would produce the same result, but without messing around in the database. Any advice out there? Thanks!

# Answer
Try the Rabbit Hole module:

> Rabbit Hole is a module that adds the ability to control what should happen when an entity is being viewed at its own page.
>
> Perhaps you have a content type that never should be displayed on its own page, like an image content type that's displayed in a carousel. Rabbit Hole can prevent this node from being accessible on its own page, through node/xxx.
> 1 votes

# Answer
The quickest way to achieve this would be to add Views Bulk Operations module to augment Views with new actions (including a 'select all results'), then creating an administrative View that shows all Polls, with a bulk action to change its published status.

With the nodes unpublished, they are retained in the system. Without "view unpublished nodes" permission, non-admin users will just see a Page Not Found 404 message.

From here, you may want to consider creating a redirect either with .htaccess if you are on Apache or add Rabbit Hole module to edit the Poll content type and changes its behavior when loaded (if they are already unpublished, this may not fire anyway).
> 1 votes

---
Tags: 7, nodes, polls
---


# Question
Title: Migrate plugin migration_lookup : dynamic migration id
"node\_a\_migration" is the migration ID of nodes of type "node\_a"
"node\_b\_migration" is the migration ID of nodes of type "node\_b"

I'd like to use either "node\_a\_migration" or "node\_b\_migration" as a migration\_lookup depending on other field value.

The source (not a drupal site, entities of content A and content B can have the same id, because stored in different tables) :

```
[
  ['entity_type' => 'content_a', 'entity_id' => 123],
  ['entity_type' => 'content_b', 'entity_id' => 123],
]

```

The migration config :

```
process:
  pseudo_field_migration_id:
    plugin: static_map
    map:
      content_a: node_a_migration
      content_b: node_b_migration
    source: entity_type
  field_entity_reference:
    plugin: migration_lookup
    migration: '@pseudo_field_migration_id'
    source: entity_id

```

There is no error when running the migration, but the field\_entity\_reference is not populated.
It works if I manually replace '@pseudo\_field\_type\_id' by node\_a\_migration

Any idea how to make it work ?

Thank you!

# Answer
As @Hudri suggested, I've created my own process plugin (extending MigrationLookup plugin):

my\_module/src/Plugin/migrate/process/CustomMigrationLookup.php

```

namespace Drupal\my_module\Plugin\migrate\process;

use Drupal\migrate\Plugin\migrate\process\MigrationLookup;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * @MigrateProcessPlugin(
 *   id = "custom_migration_lookup"
 * )
 */
class CustomMigrationLookup extends MigrationLookup {

  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    // We set the migration id based on the field configured in "migration_id_source"
    $this->configuration['migration'] = $row->getDestinationProperty($this->configuration['migration_id_source']);
    // We continue with the standard migration_lookup process
    return parent::transform($value, $migrate_executable, $row, $destination_property);
  }

}

```

The migration config :

```
process:
  pseudo_field_migration_id:
    plugin: static_map
    map:
      content_a: node_a_migration
      content_b: node_b_migration
    source: entity_type
  field_entity_reference:
    plugin: custom_migration_lookup
    migration_id_source: 'pseudo_field_migration_id'
    source: entity_id

```
> 1 votes

---
Tags: 8, migrations
---


# Question
Title: How can we make the summary field auto expand on load?
We have an admin page with a summary and body. The summary is auto collapsed but we want it to be automatically expanded on the page load like below in the image.

# Answer
You could do it with the Summary Options module.

> This module provides site builders with additional options for the 'summary' field when using "Text Area with a Summary" widget.
>
> Often, a summary or teaser field is used when displaying content in views. Drupal already has built in support for a summary field, however there is not much control of whether or not it is display, or required.
> 1 votes

---
Tags: forms
---


# Question
Title: How to run custom sql commands to database programatically
I'm using MariaDB as database backend and I would like to use built in "Sequences" to get an integer number generator. I need to dinamically create sequences and get their values. Following this documentation I know the right sql commands to do it and I have tested it on MariaDB, but I haven't found a way to run this commands from Drupal 8 database connection object. I can only do selects, updates, inserts or deletes. How could I run this custom sql? I need it because I have to create custom sequences on submit some form.

# Answer
> I haven't found a way to run this commands from Drupal 8 database connection object. I can only do selects, updates, inserts or deletes

That's not true, you can also run arbitrary queries, e.g.:

```
\Drupal::database()->query('TRUNCATE TABLE foo');

```
> 5 votes

# Answer
You can run your SQL query in your Drupal Project. Read this Static Queries Article. you will get detailed explaination of syntax and examples.
> -1 votes

---
Tags: 8, database
---


# Question
Title: How to load a form/page into a div via AJAX?
I want to open the create user form (`/admin/people/create`) into a specific `div` via AJAX. I can currently open such forms into a modal window using the following link format:

```
<a href="/admin/people/create" class="use-ajax" data-dialog-type="modal">
    Add user
</a>

```

Is there any way to load this form/page into a `div` instead of into a modal window?

# Answer
> 2 votes
Core does not provide an HTML format for non-dialogs, but you can create your own custom format.

mymodule/js/**custom-ajax-loader.js**:

```
(function ($, Drupal) {
  Drupal.behaviors.myCustomAJAXStuff = {
    attach: function (context, settings) {
      $("a.use-custom-ajax", context).once('mymodule-ajax').each(function(i, ajaxLink) {
        const $linkElement = $(ajaxLink);

        const elementSettings = {
          url: $linkElement.attr("href"),
          event: 'click',
          progress: {type: 'throbber'},
          element: ajaxLink,
        };

        const myAjaxObject = Drupal.ajax(elementSettings);

        // Declare a new Ajax command specifically for this Ajax object.
        myAjaxObject.commands.insert = function (ajax, response) {
          let target = $linkElement.attr("target");
          $(target).html(response.data);
        };
      });
    },
  };
})(jQuery, Drupal);

```

mymodule.libraries.yml:

```
mymodule.ajax:
  js:
    js/custom-ajax-loader.js: { }
  dependencies:
    - core/drupal.ajax

```

Add the library wherever needed: Adding stylesheets (CSS) and JavaScript (JS) to a Drupal module

Then when you create your link

```
<a href="/admin/people/create" class="use-custom-ajax" target="#some-div-id">
    Add user
</a>

```

---
Tags: 8, ajax
---