# Question
Title: Loading taxonomy terms in a tree in Drupal 8
I have multiple level of vocabulary, I want to display all level in the hierarchy same as taxonomy display. My taxonomy is like.

```
All
   Drinks
      Alcohol Drinks
         Beer
         Vodka
      Alcohol Free Drinks
         Coca Cola
         Pepsi
   Fruits
      Fruits For Losing Weight
         Watermelon
         Blackberrie
      Fruits For Dogs
         Strawberry
         Orange

```

now I am trying to load this using code.

```
$vid = 'food';
    $terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, 0, 1, FALSE);
    foreach ($terms as $term) {
        $term_data_1[$term->tid] = $term->name;
            $terms_2 =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $term->tid, 1, FALSE);
            foreach ($terms_2 as $term_2) {
                $term_data_2[$term_2->tid] = $term_2->name;
                    $terms_3 =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $term_2->tid, 1, FALSE);
                    foreach ($terms_3 as $term_3) {
                        $term_data_3[$term_3->tid] = $term_3->name;
                    }

            }
            $term_data_1[$term_2->tid] = $term_data_2;
            $term_data_1[$term_3->tid] = $term_data_3;
    }

    kint($term_data_1);

```

and this code giving result like

Need help to get term in hierarchy.

# Answer
TermForm.php has an example of how to do this.

Basically you loop through the tree and add dashes according to the depth of the term.

Here's an example you can use:

```
$options = [];
foreach (\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid) as $item) {
  $options[$item->tid] = str_repeat('-', $item->depth) . $item->name;
}

```

**UPDATE:** If you want a nested array of terms, you can do like this:

```
$result = [];
foreach (\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid) as $item) {
  $parents = array_reverse(\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadAllParents($item->tid), TRUE);
  $r = &$result;
  foreach ($parents as $k => $v) {
    if (isset($r[$k])) {
      $r[$k] = array_replace($r[$k], [$k => $v->label()]);
    }
    else {
      $r[$k] = [$k => $v->label()];
    }
    $r = &$r[$k];
  }
}

```

That will work regardless of how many levels your terms are nested.
> 8 votes

# Answer
I created a simple service to get a nested tree of taxonomy terms. It returns an array of taxonomy terms, with each term having an extra `children` property, which is an array of terms again having a `children` property.

```
/**
 * Class TaxonomyUtils
 */
class TaxonomyUtils {

  /**
   * @var \Drupal\taxonomy\TermStorage
   */
  protected $taxonomyStorage;

  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
    $this->taxonomyStorage = $entityTypeManager->getStorage('taxonomy_term');
  }

  /**
   * @param string $vocabulary
   * @param int $parent
   *
   * @return array
   */
  public function getTree(string $vocabulary, int $parent = 0) {
    $terms = $this->taxonomyStorage->loadTree($vocabulary, $parent, 1, TRUE);
    $tree = [];

    foreach ($terms as $term) {
      $term->children = $this->getTree($vocabulary, $term->id());
      $tree[$term->id()] = $term;
    }

    return $tree;
  }

}

```

### my\_module.services.yml

```
services:
  my_module.taxonomy_utils:
    class: Drupal\my_module\Utils\TaxonomyUtils
    arguments: [ '@entity_type.manager' ]

```
> 3 votes

# Answer
You should use Multi Dimensional array for storing data.

```
  $vid = 'tags';
  $terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, 0, 1);
  $termDataAll = [];
  foreach ($terms as $term) {
    $termDataAll[$term->tid]["tid"] = $term->tid;
    $termDataAll[$term->tid]["name"] = $term->name;
     $terms_2 =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $term->tid, 1);
      foreach($terms_2 as $term_2){
        $termDataAll[$term->tid][$term_2->tid]["tid"] = $term_2->tid;
        $termDataAll[$term->tid][$term_2->tid]["name"] = $term_2->name;
        $terms_3 =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $term_2->tid, 1);
        foreach($terms_3 as $term_3){
          $termDataAll[$term->tid][$term_2->tid][$term_3->tid]["tid"] = $term_3->tid;
          $termDataAll[$term->tid][$term_2->tid][$term_3->tid]["name"] = $term_3->name;
        }
      }
  }
  dpm($termDataAll);

```
> 0 votes

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


# Question
Title: I cannot call a function in another JavaScript file
I have two JavaScript files on my custom theme. One file has functions that need to be used on the other file. What I have below doesn't work. This is the error I get.

> Uncaught ReferenceError: test is not defined.

jQuery will be used on both files.

### file1.js

```
/**
 * @file
 * UI behaviors
 */

(function ($, Drupal) {

 'use strict';

  $(document).ready(function () {
    function test(){
     console.log('hello'):
    }
  });

})(jQuery, Drupal);

```

### file2.js

```
/**
 * @file
 * UI behaviors
 */

(function ($, Drupal) {

  'use strict';

  $(document).ready(function () {
     test();
  });

})(jQuery, Drupal);

```

### customtheme.libraries.yml

```
scripts:
  js:
    js/file1.js: {}
    js/file2.js: {}

```

### customtheme.info.yml

```
libraries:
 - 'customtheme/scripts'

```

# Answer
This is because `test()` is wrapped in an anonymous function, making it not available outside of that function.

I would add it to the Drupal object:

File 1:

```
(function($, Drupal) {
  Drupal.myFunction = function() {
    // Do something.
  }
}(jQuery, Drupal));

```

File 2:

```
(function($, Drupal) {
  Drupal.myFunction();
});

```

Also, as a side note, `$(document).ready()` is not used in Drupal. In Drupal `Drupal.behaviors` is used instead: https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview
> 1 votes

---
Tags: 8, javascript
---


# Question
Title: How to render a media field as responsive image?
I'm trying to render a media field as a responsive image in a custom twig template.

My naive approach looks like this:

```
{% include 'responsive-image.html.twig' with {
  "sources": content.field_media,
} %}

```

which simply yields a series of errors like this:

```
"0" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).

```

Presumably one of the reasons this fails is that I'm not providing a view mode, but I'm also not sure how to do so.

# Answer
> 0 votes
This is how I would do it. Note that I defer as much as possible to configuration through the UI, to limit custom code that needs to be maintained.

1. Use the Responsive Image module, set up your responsive image style (breakpoints etc).
2. Create a new view mode for the media type, named `Image Only`.
3. Navigate to the media type, 'Manage View' tab, and enable the new view mode.
4. Edit the new view mode. Set all fields except the image to be hidden. Set the formatter for the view mode to use the responsive image style created in step 1.
5. Render your media item using that view mode in the twig template. Note that the following link shows how to render the `teaser` view mode, you want to render the `image_only` view mode you created in step 2: https://drupal.stackexchange.com/a/207719/66659

# Answer
> 0 votes
Since you are posting Twig code here a solution in Twig:

First get the image URIs. In this example starting with the node if this is a node template:

```
{% for media in node.field_slider_image  %}

  <img src="{{ file_url(media.entity.field_image.entity.uri.value) }}">

{% endfor %}

```

See Display image/media entities view from node to twig template.

If you want to display an image style don't call the image template directly. Build a render element for the image template. See Rendering an image field in page.html.twig with a custom image style

---
Tags: media
---


title: Get the list of all content types

text:
# Question
Title: Get the list of all content types
How do I get a list of all the content types defined in a Drupal 8 site?

In Drupal 7 it used to be `node_type_get_types()`, but it has been deprecated.

I tried `Entity::loadMultiple()` but it doesn't seem to work. I was thinking about making a custom query, but I don't know how it's stored in the database.

# Answer
> 35 votes
`loadMultiple()` should be fine for this:

```
$types = \Drupal::entityTypeManager()
  ->getStorage('node_type')
  ->loadMultiple();

```

# Answer
> 20 votes
You can load all of the NodeType entities (config entities) using the NodeType class:

```
$node_types = \Drupal\node\Entity\NodeType::loadMultiple();
// If you need to display them in a drop down:
$options = [];
foreach ($node_types as $node_type) {
  $options[$node_type->id()] = $node_type->label();
}

```

# Answer
> 3 votes
There is another Drupal helper function that is not deprecated as of 8.7. `node_type_get_names()` returns:

> string\[\] An array of node type labels, keyed by the node type name.

API docs

# Answer
> 1 votes
Provided in case `node_type_get_names()` gets deprecated in the future (also a nice example of `array_map` usage):

```
function node_type_get_names() {
  return array_map(function ($bundle_info) {
    return $bundle_info['label'];
  }, \Drupal::service('entity_type.bundle.info')
    ->getBundleInfo('node'));
}

```

# Answer
> 1 votes
There's a service for that called "entity\_type.bundle.info":

```
>>> $bi = \Drupal::service('entity_type.bundle.info');
=> Drupal\Core\Entity\EntityTypeBundleInfo {#1433
     +"_serviceId": "entity_type.bundle.info",
   }
>>> $bi->getBundleInfo('node');
=> [
     "article" => [
       "label" => "Article",
       "translatable" => false,
     ],
.

```

---
Tags: nodes, 8
---


title: One time … landing page?

text:
# Question
Title: One time … landing page?
I’m building a Drupal 9 site and would like to have a one-time landing page that any visitor sees with various images when they first visit, then if they click on any image, or anywhere on the page for that matter, they go to the site’s home page, which stays as the home page for the remainder of that session. It’s sort of a like getting a splash when you first visit home, only I don’t want a modal, I’d like an empty page save for the images. I’m having a heck of a time figuring out how to do this. Does anyone smarter than me have any ideas? I don’t even know what to call this one-time landing page.

# Answer
Splash Redirect claims to do this with a cookie:

> The main difference between this module and ones like Splashify is that Splash Redirect sets a cookie to "remember" whether or not a user has seen your splash page.

This module is only available for Drupal 8 but you can either port it to Drupal 9 yourself or use the code as a reference.

P.S. If you're having trouble googling for this, it's probably because you want a *splash page*, not a *landing page*.

A landing page usually refers to:

> a standalone web page, created specifically for a marketing or advertising campaign. It’s where a visitor “lands” after they click on a link in an email, or ads from Google, Bing, YouTube, Facebook, Instagram, Twitter, or similar places on the web.

You would want a landing page if you were creating several different landing pages for various ad campaigns and sending different groups of users to each one.

In your case, though, it sounds like you want all visitors who come to the site from anywhere to go a single page, and then get sent to the home page, which is probably more commonly called a splash page.
> 1 votes

---
Tags: 9
---


# Question
Title: Can I pass a view's exposed filter values to the next page?
I have a D8 site view with exposed filters. I want the selected filters from that view to carry over to the next page's URL.

For example: The page lists software titles. If someone filters on OS, and picks MacOS, the URL of the view page changes from "viewpage" to "viewpage?os=MacOS". I want to make the links in the view change from "drupalpage" to "drupalpage?os=MacOS".

I can't figure out how to add the "?os=MacOS" query string to a link in the view. Is there a way to do that?

# Answer
I think what you needed to get in on your preprocess and pass it to your views.

In a `hook_preprocess_views_view()` implementation in your theme or module:

```
$values = $view->getExposedInput();
// for example $values["os"];

```

Or, you can access the values directly from the `views-view.html.twig` template:

```
// Assuming `os` is configured to be the Filter identifier in the

// view's Filter Criteria exposed filter.
{{ view.getExposedInput.os }}

```
> 0 votes

---
Tags: 8, views
---


# Question
Title: Unable to install modules: module 'login_security' is incompatible with this version of Drupal core
I'm trying to install the *Login Security* module. When I run `drush en login_security`, I get the following error.

> In ModuleInstaller.php line 91:
>
> Unable to install modules: module 'login\_security' is incompatible with this version of Drupal core.

What is the equivalent of the *Login Security* module for Drupal 9?

# Answer
> 2 votes
You are probably trying to install a `1.x` version of Login Security.

According to the module page, it supports Drupal 9 from version 2.0.

So check your `composer.json` and make sure you are trying to install the 2.0 version.

---
Tags: installation, 9
---


# Question
Title: How can I install a beta version of a module?
Now, a good amount of modules do not yet have a stable version, for example, webform. `composer require drupal/webform` says:

> Could not find package drupal/webform at any version for your minimum-stability (stable). Check the package spelling or your minimum-stability

If I try `composer require --minimum-stability=beta drupal/webform`, I get:

> The "--minimum-stability" option does not exist.

`drush dl` gives:

> This codebase is assembled with Composer instead of Drush. Use `composer update` and `composer require` instead of `drush pm-updatecode` and `drush pm-download`.

Note that due to the special versioning of Drupal this is *not* a generic composer question but a Drupal specific one. Ie. webform today is 8.x-5.0-beta12, how do I install the latest in the 8.x-5.0 series...? Now, composer *doesn't* understand or use 8.x-5.0 but uses somethting else, but what and how does that work for betas? This needs documentation *somewhere* because it currently does not exist. I would be the happiest person if this didn't need an answer, but alas, despite having perfectly fine working tools to build sites, with Drupal 8 we need to use composer and most modules are in beta.

# Answer
The reason this doesn't work because the "stable preference" of composer is not a preference but a hard choice which you can *not* override with anything except specifying an exact version.

If you have `"prefer-stable": true,` in your `composer.json` then the only way to install a beta module is `composer require 'drupal/bricks:2.0.2-beta2'`. Neither `2.0.*@dev` nor anything else will work except that.

Switching that setting off with `composer config prefer-stable false` is possible but it might affect other modules.

You can check why composer refuses to do what you tell it to do -- because of course it does -- with `composer why-not drupal/bricks:2.0.2-beta2`.
> 2 votes

# Answer
This installs the latest beta-12 for me:

```
composer require drupal/webform:5.0.*@dev

```

You need to do a bit of translation from the Drupal version number. From Using Composer to manage Drupal site dependencies:

> Specifying a version you can specify a version from the command line with:
>
> ```
>  $ composer require drupal/<modulename>:<version>
>
> ```
>
> For example:
>
> ```
>  $ composer require drupal/ctools:3.0.0-alpha26
>  $ composer require drupal/token:1.x-dev
>
> ```
>
> In these examples, the composer version 3.0.0-alpha26 maps to the drupal.org version 8.x-3.0-alpha26 and 1.x-dev maps to 8.x-1.x branch on drupal.org.
>
> If you specify a branch, such as 1.x you must add -dev to the end of the version.

Hence for Webform, 8.5 becomes 5.0.x, and that's what you need to use to identify the package correctly.
> 14 votes

---
Tags: 8, composer
---


# Question
Title: Don't see Mail System under Configuration
I'm currently going through the prerequisites of Acquias configuring platform email https://docs.acquia.com/cloud-platform/manage/platform-email/platform-email-configuration/#associate-domain

but I do not see the Mail System to check what our default Mail System is. Does this mean We are using a different one? I do see Nemo Integration but still expected to be able to access Mail System.

thanks

# Answer
Looks like you don't have the Mail System module installed and enabled on your site. If you want to use only the default Drupal PhpMailer, then you don't need Mail System. You only need to use Mail System if you install a different mailer and want to use that different mailer.
> 4 votes

---
Tags: emails, configuration
---


# Question
Title: Why isn't the Endroid\QrCode\QrCode found?
I created a custom module and installed the *endroid/qrcode* library in my module using Composer. When I try to use that library, I get the following error.

> Error: Class 'Endroid\QrCode\QrCode' not found in Drupal\shopexp\Plugin\Block\ShopExp-\>build() (line 25 of modules\custom\shopexp\src\Plugin\Block\ShopExp.php).

The code using the library is the following one.

```
namespace Drupal\shopexp\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Endroid\QrCode\QrCode;

class ShopExp extends BlockBase {
  public function createpr() {
      $qr = QrCode::create("https://site.com");
  }
  public function build() {
    $qr = new QrCode();
    return [
      '#markup' => 'test msg',
    ];
  }
}

```

The *composer.json* file used by the module is the following one.

```
{
    "require": {
        "endroid/qr-code": "^2.5"
    }
}

```

The folder structure is the following one.

>

# Answer
You have to `composer require endroid/qrcode` from the Drupal root directory, not from your custom module directory. The package needs to be installed in the main vendor directory along with all the other packages used by Drupal, otherwise the class loader can't find it.
> 1 votes

---
Tags: 8
---


# Question
Title: How do I add ajax callback to a form element which is created in a foreach loop
Please see the following code:

```
foreach ($formaddresses as $key => $val) {
  // Add edit buttons to custom client-side created addresses.
  if (!isset($val['accountnumber'])) {
    $form['orderinfo']['billshipaddresses']['billingaddresses'][$key]['#description'] = '<a class="edit-stored-address edit-stored-address-target-' . $key . '">Edit</a>';
    $form['orderinfo']['billshipaddresses']['shippingaddresses'][$key]['#description'] = '<a class="edit-stored-address edit-stored-address-target-' . $key . '">Edit</a>';
  }
}

```

Here this loop is creating some anchors in my form. I just need to **attach/add '#ajax' callback** to it. How can I achieve this?

Something like the following code:

```
$form['orderinfo']['billshipaddresses']['shippingaddresses'] = [
  '#type' => 'radios',
  '#title' => 'Shipping Address',
  '#options' => $formaddressesOptions,
  '#default_value' => '',
  '#ajax' => [
    'callback' => '::buildShipBillAddresses',
    'wrapper' => 'shippingaddresses',
    'event' => 'change'
  ],
];

```

Here we can see if the above radio is change then an ajax callback will work and will call this method **buildShipBillAddresses** Thanks!

# Answer
> 1 votes
Actually, the anchor element to which you want to add an AJAX callback isn't a form element. The Ajax API page says how to trigger AJAX for a link.

> Add class 'use-ajax' to a link. The link will be loaded using an Ajax call. When using this method, the href of the link can contain '/nojs/' as part of the path. When the Ajax JavaScript processes the page, it will convert this to '/ajax/'. The server is then able to easily tell if this request was made through an actual Ajax request or in a degraded state, and respond appropriately.

This means that for a link, the following code would work.

```
foreach ($formaddresses as $key => $val) {
  // Add edit buttons to custom client-side created addresses.
  if (!isset($val['accountnumber'])) {
    $form['orderinfo']['billshipaddresses']['billingaddresses'][$key]['#description'] = '<a href="/nojs/edit-billing-address" class="use-ajax edit-stored-address edit-stored-address-target-' . $key . '">Edit</a>';
    $form['orderinfo']['billshipaddresses']['shippingaddresses'][$key]['#description'] = '<a href="/nojs/edit-shipping-address" class="use-ajax edit-stored-address edit-stored-address-target-' . $key . '">Edit</a>';
  }
}

```

The module needs to define two routes for those links. I cannot tell you the code for those route callbacks, but they should render the *Edit* form to make it appear on that form.

# Answer
> 0 votes
This isn't really a Drupal question so much as a PHP question, but to answer your question:

```
foreach ($formaddresses as $key => $val) {
  // Add edit buttons to custom client-side created addresses.
  if (!isset($val['accountnumber'])) {
    $form['orderinfo']['billshipaddresses']['billingaddresses'][$key]['#ajax'] = [
      'callback' => '::buildShipBillAddresses',
      'wrapper' => 'shippingaddresses',
      'event' => 'change'
    ];
  }
}

```

---
Tags: 8, ajax
---


# Question
Title: Is it possible to check with Twig the role the current user has?
Is it possible to check with Twig the Group role the current user has, to use it as in the following code?

```
{% if is_member == true %}
  {# … #}
{% endif %}

```

I tried with `$group_memberships = \Drupal::service('group.membership_loader').loadByUser($account);` in the .theme file, but it doesn't work.

# Answer
to see the list of user roles try the following:

```
{% set roles = user.getroles() %}
{{ dump(roles) }}

```

if you want an specific role try

If you want to do anything only for the particular role then do this:

```
{% if 'ROLE_MACHINE_NAME' in user.getroles()  %}
  // do your stuffs here
{% endif %}

```
> 4 votes

---
Tags: 9, group
---


# Question
Title: Webform 'add element' and 'addpage' buttons do not appear
I am new to Drupal. I have Drupal 8 and installed Webform `8.x-5.1` module.
I can create a new webform but **'add element'** and **'add page'** do not appear so I cannot add any elements to the form as I see on tutorials online.
Any ideas?

# Answer
You need to go to admin/config/development/performance and clear the cache.
Add element and add page will appear.
> 12 votes

# Answer
I know this is an old question, but I just had the same issue. A reason for the buttons to disappear can also be the elements have been disabled in the general Webform settings.

1. Navigate to /admin/structure/webform/config/elements.
2. Under the "Element Types" block you can enable and disable elements. For example, enable the *Wizard page* element there.
> 1 votes

# Answer
When i had this issue it was because I'd just changed my admin theme to Seven and i hadn't configured secondary tabs inside the pre-content block. You can add these secondary tabs like normal tabs on the block layout page and configure them to "show secondary tabs" you may also wanna disable this option on the primary tabs to avoid conflicts.
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: Is it possible to use tokens in a menu link in Drupal8?
I need to add an option to "User account Menu" that shows the **current user name**. It is possible to do this using tokens or some other method?

Thanks!

# Answer
You can extend LoginLogoutMenuLink and override `getTitle()`

```
  public function getTitle() {
    return $this->currentUser->getDisplayName();
  }

```

and the cache context from role specific to general `user`:

```
  public function getCacheContexts() {
    return ['user'];
  }

```

and use the extended class in `mymodule.links.menu.yml`:

```
user.name:
  weight: 10
  menu_name: account
  class: Drupal\mymodule\Plugin\Menu\UserNameMenuLink

```
> 2 votes

# Answer
No, you cannot use tokens in menus out of the box.

Here are some options:

1. Use Views to create the link. This won't give you a menu, but you can make a block in Views and use that as a menu. You may have to hard-code the rest of your "menu" in the views block, which isn't ideal but if you can't code that may be your best option for now.
2. Code the menu link. See the routes documentation.
3. Watch the progress of the Menu Token module. This module does what you want but it doesn't have a stable release for Drupal 8 yet. I haven't used the D8 version so I don't know how well it works at the moment.
> 3 votes

# Answer
With twig\_tweak (for twig token filter, tested on 8.x-2.9) you can add a token based link to the user account menu in Drupal 8/9 (/admin/structure/menu/manage/account).

E.g. A menu link:

* title: \[current-user:name\]
* url: /user/\[current-user:uid\]/edit

Also works with multiple tokens.

* title: \[current-user:name\] and \[current-user:created\]
* url: /user/\[current-user:uid\]/edit/\[current-user:created\]

Note below codes:

* assumes no extra "\[" , "\]", or ":" in any parts of the title/link except for token.
* query params are broken (output as part of the url path)
* so room for improvement for the tech savvy

twig snippet for menu--account.html.twig.

* menu.html.twig \[drupal\]\core\themes\classy\templates\navigation\menu.html.twig)
* Tokens: @see \[drupal\]\web\modules\contrib\token\token.tokens.inc

```
{# CUSTOM START #}
{% if '[' in item.title %}
  {% set item = item|merge({'title': item.title
    |split(']')
    |map(t => drupal_token(t, {'menu-link': item.original_link}) )
    |join
    |replace({
      '[':'',
      ']':'',
    })
  }) %}
{% endif %}
{# Only support internal URLs, being with '/' for now. #}
{% if ('%5B' in item.url.toString()) and (item.url.toString() starts with '\/') %}
  {% set item = item|merge({'url': 'base:' ~ item.url.toString()
    |replace({
      '%5B':'[',
      '%5D':']',
      '%3A':':',
    })
    |split(']')
    |map(t => drupal_token(t, {'menu-link': item.original_link}) )
    |join
    |replace({
      '[':'',
      ']':'',
      ':':'%3A',
    })
  }) %}
{% endif %}
{# CUSTOM END #}

```
> 0 votes

---
Tags: users, navigation, tokens
---


# Question
Title: How do I implement a JSON/JSONB data type field to display data as separate columuns?
I have a custom table that consists of 2 columns, *id* and *data*. I want to create a view table with filter. The table columns should be *id*, *product*, and *item*. *product* and *item* are from the *data* column which contains JSON data (for example `{"product": "a", "item": "b"}`).

Is it possible to create this type of view?

As per my knowledge, it's not possible to create because a view works with columns that exist in the database table.

# Answer
JSONB is Postgres only but Drupal can create JSON field storage types for MySQL too. There are modules that can do both. However, Views support will be light until the additional query functions for JSON are supported. But, you can write the queries yourself in code and it will work.

As for getting Views to query custom tables, this is possible if you describe your data to Views using its API hook(s).
> 1 votes

---
Tags: views, 9
---


title: Migrate order billing profile

text:
# Question
Title: Migrate order billing profile
I'm trying to migrate order data from an existing site using CSV files and I can't get the billing profile to relate.

In trying to troubleshoot this, I have it set just to insert a default value of a known profile and it's still not working for me. Currently, in the process section of my YML migration file I have these lines, but I still end up with `<null>` in the database.

```
billing_profile/target_id:
  plugin: default_value
  default_value: 34338

```

I have also tried `billing_profile__target_id` and `billing_profile/0/target_id` instead of `billing_profile/target_id`.

What am I missing?

# Answer
OK, I figured it out. I'm new to using the Migrate system, so this may apply to anything with revisions like this, but apparently you MUST set both.

```
billing_profile/target_id:
  plugin: default_value
  default_value: 34338
billing_profile/target_revision_id:
  plugin: default_value
  default_value: 34338

```

Only setting `target_id` fails.
> 0 votes

---
Tags: commerce, migrations, 9
---


# Question
Title: What are the causes of the malfunction (The provided host name is not valid for this server) and how to fix it?
My site stopped suddenly, with an error message

> The provided host name is not valid for this server.

And even though I removed

> $settings\['trusted\_host\_patterns'\]

Completely from the settings file and cleared the cache via Drush

```
drush cache-rebuild

```

also, i tried use this settings:

`$settings['trusted_host_patterns'] = [ '.*' ]; and $settings['trusted_host_patterns'] = [];`

but, the site still shows the same error, and i cant access Drupal log or anywhere to detected the problem cause.

Apache settings are also fine, like mentioned in one of the previous experiments here

**What are the causes of this error and how can it be fixed?**

**note:**

1. The site was previously working with trusted\_host\_patterns settings.
2. my domain name has dash (-), so i used this pattern:

`$settings['trusted_host_patterns'] = ['^[domain/-/name]\.com$', '^www\.[domain/-/name]\.com$', '^www\.[domain\-name]\.com$', '[domain\-name]\.com$', ];`

two week ago, but it stopped working suddenly today, and I removed trusted\_host\_patterns setting, but it not resolved.

Note: I checked adding `$settings['trusted_host_patterns'] = [ '.*' ];` and `$settings['trusted_host_patterns'] = [];` either, both don't work.

# Answer
i resolved the problem by:

1. in centos:

> /etc/httpd/sites-available/\[domain\_name\].conf
> \<VirtualHost \[domain\_name\]:80\>
> ServerName www.\[domain\_name\]
> ServerAlias \[domain\_name\]

and, since my domain name has dash, i used this regex:

> \[.\_:-\]
> -2 votes

---
Tags: configuration, installation
---


title: Multiple sites/default folders

text:
# Question
Title: Multiple sites/default folders
I have a Drupal 8 website on Docker containers. Drupal sites folders contains, besides the *default* folder, two folders, the *settings.php* file, and configuration.

The goal is to have different configuration inside each folder (inside each settings.php) and connected to same or different database.

Because client wants only one instance of Drupal (a single set of containers), how can I manage the website to change symlink from the *default* folder to each folders with different configurations?

# Answer
sites/sites.php is the file that allows to define a set of aliases that map hostnames, ports, and pathnames to configuration directories in the sites directory
> 2 votes

---
Tags: 8, configuration
---


# Question
Title: Is there an event related to the creation of a session cookie for anonymous users?
I need to set an additional cookie whenever an anonymous user received a session cookie. This happens when selecting a facet in Search API for example. The specific use case is that I need an extra cookie set specifically for a third-party integration (GTranslate). hook\_user\_login doesn't meet the use case because the user isn't actually logged in but they do receive a session cookie upon selecting a facet. Is there some event I can subscribe to when that happens so I can inject my custom cookie?

# Answer
You can try out an event response event subscriber. For E.g: Create a file in **CUSTOM\_MODULE/src/EventSubscriber/SetSessionCookieSubscriber.php**

```
namespace Drupal\CUSTOM_MODULE\EventSubscriber;

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;

class SetSessionCookieSubscriber implements EventSubscriberInterface {
  public function onResponse(FilterResponseEvent $event) {
    /** @var Request $request */
    $request = $event->getRequest();
    // Check if this is the right request, for example posting facets
    $session = $request->getSession();
    // Check for session values
    $response = $event->getResponse();
    /** Your custom code goes here */
    $response->headers->setCookie(new Cookie(...));
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['onResponse'];
    return $events;
  }
}

```

Register it in your services file **CUSTOM\_MODULE.services.yml**

```
services:
  CUSTOM_MODULE.setsessioncookie:
  class: Drupal\CUSTOM_MODULE\EventSubscriber\SetSessionCookieSubscriber
  tags:
    - { name: event_subscriber }

```
> 1 votes

---
Tags: 9, sessions, event-subscribers
---


# Question
Title: Joining two text fields in a Computed Text field
I have two fields whose type is *List (text)*. In the allowed values list, i want to join them. I used the following code.

```
$value = $entity->field_a->value . $entity->field_b->value;
$value = $fields['field_a'][0]['value'] . $fields['field_b'][0]['value'];

```

I can get the result fine, but the value returns the keys only. How can I get the labels?

# Answer
> 2 votes
To get the allowed values set in your field settings you need to call as follows

```
$entity->field_my_field->getSetting('allowed_values')[$entity->field_my_field->value];

```

your code should look like this

```
$value = $entity->field_a->getSetting('allowed_values')[$entity->field_a->value] . $entity->field_b->getSetting('allowed_values')[$entity->field_b->value];

```

# Answer
> 0 votes
Although the question is not very clear to me, but I guess the following could help you,

```
$key1 = $entity->field_a->value;
$key2 = $entity->field_b->value;
$value1= $fields['field_a']["#options"][$key1];
$value2= $fields['field_b']["#options"][$key2];
$value = $value1 . $value2;

```

---
Tags: 8, entities
---


# Question
Title: Access product field from variation field
There are a bunch of product images that are named same as SKU, so I'm just using *field--commerce-product-variation--sku.html.twig* to show them. All is fine.

I'd like to use the parent product image as fallback image for when the SKU image doesn't exist.

How do I access a parent product field from the product variation field template?

# Answer
You'll get the variation object in `element['#object']`

```
{% set variation_object = element['#object'] %}
{% set product_object = variation_object.product_id.entity %}

```

then from `product_object` you can access the image field
> 2 votes

---
Tags: 8, theming, commerce
---


title: Cloudflare cache everything

text:
# Question
Title: Cloudflare cache everything
we have a Drupal 8 with Cloudflare cache rule. By default we have always GBP currency, then we developed a module that allow users change their currency with a footer dropdown and saves it on the user session.

Without Cloudflare cache rule, the webpage works correctly. The problem is if the rule is active, the first visit to the web is cached with the default currency, then if someone try to change the currency to EUR, the web page is reloaded and it shows the cached page with default currency and not EUR.

Cloudflare cache is by URL and we always keep the same URL for all currencies.

---

---

---

***Start Clodflare screeshots***

***End Clodflare screeshots***

---

---

---

A solution that we thought is to add/force the currency as a parameter of the URL.

```
https://www.amazon.com/
https://www.amazon.com/?currency=EUR&language=es_US
https://www.amazon.com/?currency=EUR&language=en_US
https://www.amazon.com/?currency=USD&language=es_US

```

Is possible to force a request to have always a param? Is there any way to do this? Like an EventSubscriber?

Thank u all.

# Answer
Cloudflare has an option that is Custom Cache Key. Here I can configure cache by cookie name and/or cookie name and value.

We save the currency in a cookie and Cloudflare is able to detect that cookie name with the specified currency.
> 0 votes

# Answer
Yes, you can force the request to have always query parameters by redirecting in an event subscriber. The problem is, how do you know what currency the user is requesting if the parameter is missing? So what you probably want is to process outbound paths to have already the correct parameters.

BTW your question is a bit confusing. The first part is talking about logged-in users. Then the solution is not query parameters but to configure the CDN to bypass cache on `SESS.*` cookies (which you need anyway to keep the user logged in). See https://support.cloudflare.com/hc/en-us/articles/115002911927-Caching-HTML-with-Drupal
> 1 votes

---
Tags: 8, caching
---


# Question
Title: Composer won't upgrade drupal/core-recommended
My composer.json is below

```
{                                                                                "name": "drupal/recommended-project",                                                                                "description": "Project template for Drupal 8 projects with a relocated document root",                                 "type": "project",                                                                                "license": "GPL-2.0-or-later",                                                                                "homepage": "https://www.drupal.org/project/drupal",                                                                    "support": {                                                                                "docs": "https://www.drupal.org/docs/user_guide/en/index.html",                                                         "chat": "https://www.drupal.org/node/314178"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        }
    ],
    "require": {
        "composer/installers": "^1.9",
        "drupal/ckeditor_a11ychecker": "^1.0",
        "drupal/ckeditor_bs_grid": "^2.0",
        "drupal/ckeditor_indentblock": "^1.0@beta",
        "drupal/ckeditor_youtube": "^1.3",
        "drupal/codesnippet": "^1.7",
        "drupal/colorbutton": "^1.2",
        "drupal/core-composer-scaffold": "^9",
        "drupal/core-project-message": "^9",
        "drupal/core-recommended": "^9",
        "drupal/danland": "^1.0",
        "drupal/devel": "^4.0",
        "drupal/devel_entity_updates": "^3.0.",
        "drupal/diff": "^1.0",
        "drupal/domain": "^1.0@beta",
        "drupal/facets": "^1.5",
        "drupal/image_resize_filter": "^1.1",
        "drupal/ldap_auth": "^1.16",
        "drupal/search_api": "^1.17",
        "drupal/search_api_db": "^1.17",
        "drupal/search_api_solr": "^4.1",
        "drupal/vartheme_bs4": "^6.13",
        "typo3/phar-stream-wrapper": "^3.1"
    },
    "conflict": {
        "drupal/drupal": "*"
    },
    "minimum-stability": "stable",
    "prefer-stable": true,
    "config": {
        "sort-packages": true
    },
    "extra": {
        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            }
        },
        "installer-paths": {
            "web/core": [
                "type:drupal-core"
            ],
            "web/libraries/{$name}": [
                "type:drupal-library"
            ],
            "web/modules/contrib/{$name}": [
                "type:drupal-module"
            ],
            "web/profiles/contrib/{$name}": [
                "type:drupal-profile"
            ],
            "web/themes/contrib/{$name}": [
                "type:drupal-theme"
            ],
            "drush/Commands/contrib/{$name}": [
                "type:drupal-drush"
            ],
            "web/modules/custom/{$name}": [
                "type:drupal-custom-module"
            ],
            "web/themes/custom/{$name}": [
                "type:drupal-custom-theme"
            ]
        },
        "drupal-core-project-message": {
            "include-keys": [
                "homepage",
                "support"
            ],
            "post-create-project-cmd-message": [
                "<bg=blue;fg=white>                                                         </>",
                "<bg=blue;fg=white>  Congratulations, you’ve installed the Drupal codebase  </>",
                "<bg=blue;fg=white>  from the drupal/recommended-project template!          </>",
                "<bg=blue;fg=white>                                                         </>",
                "",
                "<bg=yellow;fg=black>Next steps</>:",
                "  * Install the site: https://www.drupal.org/docs/8/install",
                "  * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html",
                "  * Get support: https://www.drupal.org/support",
                "  * Get involved with the Drupal community:",
                "      https://www.drupal.org/getting-involved",
                "  * Remove the plugin that prints this message:",
                "      composer remove drupal/core-project-message"
            ]
        }
    }
}

```

When I run `composer update drupal/core-recommended --with-dependencies` i get this:

```
Dependency "typo3/phar-stream-wrapper" is also a root requirement, but is not explicitly allowed. Ignoring.
Dependency "typo3/phar-stream-wrapper" is also a root requirement, but is not explicitly allowed. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - drupal/core 8.7.9 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.8 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.7 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.6 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.5 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.4 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.3 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.2 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.14 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.13 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.12 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.11 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.10 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.1 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.7.0 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.9 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.8 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.7 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.6 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.18 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.17 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.16 requires typo3/phar-stream-wrapper ^2.1.1 -> satisfiable by typo3/phar-stream-wrapper[v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.15 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.14 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.13 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.12 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.11 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.6.10 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.9 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.15 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.14 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.13 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.12 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.11 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core 8.5.10 requires typo3/phar-stream-wrapper ^2.0.1 -> satisfiable by typo3/phar-stream-wrapper[v2.0.1, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.1.5, v2.2.0, v2.2.1, v2.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.1 requires drupal/core 9.1.x-dev -> satisfiable by drupal/core[9.1.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.0 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - drupal/core-recommended 9.1.2 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - drupal/core-recommended 9.1.3 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - drupal/core-recommended 9.1.4 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - Conclusion: don't install typo3/phar-stream-wrapper v3.1.6
    - Conclusion: remove drupal/core 9.0.11
    - Conclusion: don't install drupal/core 8.9.13
    - Conclusion: don't install drupal/core 9.0.11
    - Conclusion: don't install drupal/core 8.9.12
    - drupal/core-recommended 9.0.11 requires drupal/core 9.0.11 -> satisfiable by drupal/core[9.0.11].
    - drupal/core-recommended 9.0.11 requires drupal/core 9.0.11 -> satisfiable by drupal/core[9.0.11].
    - drupal/core-recommended 9.0.11 requires drupal/core 9.0.11 -> satisfiable by drupal/core[9.0.11].
    - Conclusion: don't install drupal/core 9.0.11
    - Conclusion: don't install drupal/core 8.9.11
    - drupal/core-recommended 9.0.10 requires drupal/core 9.0.10 -> satisfiable by drupal/core[9.0.10].
    - Conclusion: don't install drupal/core 9.0.10
    - Conclusion: don't install drupal/core 8.9.10
    - drupal/core-recommended 9.0.9 requires drupal/core 9.0.9 -> satisfiable by drupal/core[9.0.9].
    - Conclusion: don't install drupal/core 9.0.9
    - Conclusion: don't install drupal/core 8.9.9
    - drupal/core-recommended 9.0.8 requires drupal/core 9.0.8 -> satisfiable by drupal/core[9.0.8].
    - Conclusion: don't install drupal/core 9.0.8
    - Conclusion: don't install drupal/core 8.9.8
    - drupal/core-recommended 9.0.7 requires drupal/core 9.0.7 -> satisfiable by drupal/core[9.0.7].
    - Conclusion: don't install drupal/core 9.0.7
    - Conclusion: don't install drupal/core 8.9.7
    - drupal/core-recommended 9.0.6 requires drupal/core 9.0.6 -> satisfiable by drupal/core[9.0.6].
    - Conclusion: don't install drupal/core 9.0.6
    - Conclusion: don't install drupal/core 8.9.6
    - drupal/core-recommended 9.0.5 requires drupal/core 9.0.5 -> satisfiable by drupal/core[9.0.5].
    - Conclusion: don't install drupal/core 9.0.5
    - Conclusion: don't install drupal/core 8.9.5
    - drupal/core-recommended 9.0.4 requires drupal/core 9.0.4 -> satisfiable by drupal/core[9.0.4].
    - Conclusion: don't install drupal/core 9.0.4
    - Conclusion: don't install drupal/core 8.9.4
    - drupal/core-recommended 9.0.3 requires drupal/core 9.0.3 -> satisfiable by drupal/core[9.0.3].
    - Conclusion: don't install drupal/core 9.0.3
    - Conclusion: don't install drupal/core 8.9.3
    - drupal/core-recommended 9.0.2 requires drupal/core 9.0.2 -> satisfiable by drupal/core[9.0.2].
    - Conclusion: don't install drupal/core 9.0.2
    - Conclusion: don't install drupal/core 8.9.2
    - Installation request for typo3/phar-stream-wrapper (locked at v3.1.4, required as ^3.1) -> satisfiable by typo3/phar-stream-wrapper[v3.1.4].
    - Removal request for drupal/ckeditor_a11ychecker == 1.9999999.9999999.9999999-dev
    - Installation request for drupal/ckeditor_a11ychecker ^1.0 -> satisfiable by drupal/ckeditor_a11ychecker[1.0.0, 1.x-dev].
    - drupal/core-recommended 9.0.1 requires drupal/core 9.0.1 -> satisfiable by drupal/core[9.0.1].
    - Conclusion: don't install drupal/core 9.0.1
    - drupal/ckeditor_a11ychecker 1.0.0 requires drupal/core ^8 -> satisfiable by drupal/core[8.0.0, 8.0.1, 8.0.2, 8.0.3, 8.0.4, 8.0.5, 8.0.6, 8.1.0, 8.1.1, 8.1.10, 8.1.2, 8.1.3, 8.1.4, 8.1.5, 8.1.6, 8.1.7, 8.1.8, 8.1.9, 8.2.0, 8.2.1, 8.2.2, 8.2.3, 8.2.4, 8.2.5, 8.2.6, 8.2.7, 8.2.8, 8.3.0, 8.3.1, 8.3.2, 8.3.3, 8.3.4, 8.3.5, 8.3.6, 8.3.7, 8.3.8, 8.3.9, 8.4.0, 8.4.1, 8.4.2, 8.4.3, 8.4.4, 8.4.5, 8.4.6, 8.4.7, 8.4.8, 8.5.0, 8.5.1, 8.5.10, 8.5.11, 8.5.12, 8.5.13, 8.5.14, 8.5.15, 8.5.2, 8.5.3, 8.5.4, 8.5.5, 8.5.6, 8.5.7, 8.5.8, 8.5.9, 8.6.0, 8.6.1, 8.6.10, 8.6.11, 8.6.12, 8.6.13, 8.6.14, 8.6.15, 8.6.16, 8.6.17, 8.6.18, 8.6.2, 8.6.3, 8.6.4, 8.6.5, 8.6.6, 8.6.7, 8.6.8, 8.6.9, 8.7.0, 8.7.1, 8.7.10, 8.7.11, 8.7.12, 8.7.13, 8.7.14, 8.7.2, 8.7.3, 8.7.4, 8.7.5, 8.7.6, 8.7.7, 8.7.8, 8.7.9, 8.8.0, 8.8.1, 8.8.10, 8.8.11, 8.8.12, 8.8.2, 8.8.3, 8.8.4, 8.8.5, 8.8.6, 8.8.7, 8.8.8, 8.8.9, 8.9.0, 8.9.1, 8.9.10, 8.9.11, 8.9.12, 8.9.13, 8.9.2, 8.9.3, 8.9.4, 8.9.5, 8.9.6, 8.9.7, 8.9.8, 8.9.9].
    - Can only install one of: drupal/core[9.0.0, 8.0.0].
    - Can only install one of: drupal/core[9.0.0, 8.0.1].
    - Can only install one of: drupal/core[9.0.0, 8.0.2].
    - Can only install one of: drupal/core[9.0.0, 8.0.3].
    - Can only install one of: drupal/core[9.0.0, 8.0.4].
    - Can only install one of: drupal/core[9.0.0, 8.0.5].
    - Can only install one of: drupal/core[9.0.0, 8.0.6].
    - Can only install one of: drupal/core[9.0.0, 8.1.0].
    - Can only install one of: drupal/core[9.0.0, 8.1.1].
    - Can only install one of: drupal/core[9.0.0, 8.1.10].
    - Can only install one of: drupal/core[9.0.0, 8.1.2].
    - Can only install one of: drupal/core[9.0.0, 8.1.3].
    - Can only install one of: drupal/core[9.0.0, 8.1.4].
    - Can only install one of: drupal/core[9.0.0, 8.1.5].
    - Can only install one of: drupal/core[9.0.0, 8.1.6].
    - Can only install one of: drupal/core[9.0.0, 8.1.7].
    - Can only install one of: drupal/core[9.0.0, 8.1.8].
    - Can only install one of: drupal/core[9.0.0, 8.1.9].
    - Can only install one of: drupal/core[9.0.0, 8.2.0].
    - Can only install one of: drupal/core[9.0.0, 8.2.1].
    - Can only install one of: drupal/core[9.0.0, 8.2.2].
    - Can only install one of: drupal/core[9.0.0, 8.2.3].
    - Can only install one of: drupal/core[9.0.0, 8.2.4].
    - Can only install one of: drupal/core[9.0.0, 8.2.5].
    - Can only install one of: drupal/core[9.0.0, 8.2.6].
    - Can only install one of: drupal/core[9.0.0, 8.2.7].
    - Can only install one of: drupal/core[9.0.0, 8.2.8].
    - Can only install one of: drupal/core[9.0.0, 8.3.0].
    - Can only install one of: drupal/core[9.0.0, 8.3.1].
    - Can only install one of: drupal/core[9.0.0, 8.3.2].
    - Can only install one of: drupal/core[9.0.0, 8.3.3].
    - Can only install one of: drupal/core[9.0.0, 8.3.4].
    - Can only install one of: drupal/core[9.0.0, 8.3.5].
    - Can only install one of: drupal/core[9.0.0, 8.3.6].
    - Can only install one of: drupal/core[9.0.0, 8.3.7].
    - Can only install one of: drupal/core[9.0.0, 8.3.8].
    - Can only install one of: drupal/core[9.0.0, 8.3.9].
    - Can only install one of: drupal/core[9.0.0, 8.4.0].
    - Can only install one of: drupal/core[9.0.0, 8.4.1].
    - Can only install one of: drupal/core[9.0.0, 8.4.2].
    - Can only install one of: drupal/core[9.0.0, 8.4.3].
    - Can only install one of: drupal/core[9.0.0, 8.4.4].
    - Can only install one of: drupal/core[9.0.0, 8.4.5].
    - Can only install one of: drupal/core[9.0.0, 8.4.6].
    - Can only install one of: drupal/core[9.0.0, 8.4.7].
    - Can only install one of: drupal/core[9.0.0, 8.4.8].
    - Can only install one of: drupal/core[9.0.0, 8.5.0].
    - Can only install one of: drupal/core[9.0.0, 8.5.1].
    - Can only install one of: drupal/core[9.0.0, 8.5.2].
    - Can only install one of: drupal/core[9.0.0, 8.5.3].
    - Can only install one of: drupal/core[9.0.0, 8.5.4].
    - Can only install one of: drupal/core[9.0.0, 8.5.5].
    - Can only install one of: drupal/core[9.0.0, 8.5.6].
    - Can only install one of: drupal/core[9.0.0, 8.5.7].
    - Can only install one of: drupal/core[9.0.0, 8.5.8].
    - Can only install one of: drupal/core[9.0.0, 8.6.0].
    - Can only install one of: drupal/core[9.0.0, 8.6.1].
    - Can only install one of: drupal/core[9.0.0, 8.6.2].
    - Can only install one of: drupal/core[9.0.0, 8.6.3].
    - Can only install one of: drupal/core[9.0.0, 8.6.4].
    - Can only install one of: drupal/core[9.0.0, 8.6.5].
    - Can only install one of: drupal/core[9.0.0, 8.8.0].
    - Can only install one of: drupal/core[9.0.0, 8.8.1].
    - Can only install one of: drupal/core[9.0.0, 8.8.10].
    - Can only install one of: drupal/core[9.0.0, 8.8.11].
    - Can only install one of: drupal/core[9.0.0, 8.8.12].
    - Can only install one of: drupal/core[9.0.0, 8.8.2].
    - Can only install one of: drupal/core[9.0.0, 8.8.3].
    - Can only install one of: drupal/core[9.0.0, 8.8.4].
    - Can only install one of: drupal/core[9.0.0, 8.8.5].
    - Can only install one of: drupal/core[9.0.0, 8.8.6].
    - Can only install one of: drupal/core[9.0.0, 8.8.7].
    - Can only install one of: drupal/core[9.0.0, 8.8.8].
    - Can only install one of: drupal/core[9.0.0, 8.8.9].
    - Can only install one of: drupal/core[9.0.0, 8.9.0].
    - Can only install one of: drupal/core[9.0.0, 8.9.1].
    - drupal/core-recommended 9.0.0 requires drupal/core 9.0.0 -> satisfiable by drupal/core[9.0.0].
    - Installation request for drupal/core-recommended ^9 -> satisfiable by drupal/core-recommended[9.0.0, 9.0.1, 9.0.10, 9.0.11, 9.0.2, 9.0.3, 9.0.4, 9.0.5, 9.0.6, 9.0.7, 9.0.8, 9.0.9, 9.1.0, 9.1.1, 9.1.2, 9.1.3, 9.1.4].

```

When I run `composer require drupal/core-recommended` I get :

```
Using version ^9.1 for drupal/core-recommended
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for typo3/phar-stream-wrapper (locked at v3.1.4, required as ^3.1) -> satisfiable by typo3/phar-stream-wrapper[v3.1.4].
    - drupal/core-recommended 9.1.1 requires drupal/core 9.1.x-dev -> satisfiable by drupal/core[9.1.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.0 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - drupal/core-recommended 9.1.2 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - drupal/core-recommended 9.1.3 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - drupal/core-recommended 9.1.4 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6].
    - Conclusion: don't install typo3/phar-stream-wrapper v3.1.6
    - Installation request for drupal/core-recommended ^9.1 -> satisfiable by drupal/core-recommended[9.1.0, 9.1.1, 9.1.2, 9.1.3, 9.1.4].

Installation failed, reverting ./composer.json to its original content.

```

Not sure what to do. I thought changing my min stability from 'dev' to 'stable' per the notes on upgrading to Drupal 9.1 would be enough but it still won't upgrade. Any help would be appreciated

EDIT 2:

Tried to remove the problematic module and got this:

```
Dependency "typo3/phar-stream-wrapper" is also a root requirement, but is not explicitly allowed. Ignoring.             Loading composer repositories with package information                                                                  Updating dependencies (including require-dev)                                                                           Your requirements could not be resolved to an installable set of packages.                                                                                Problem 1                                                                                - The requested package drupal/core-recommended (locked at 9.0.11, required as ^9.1) is satisfiable by drupal/core-recommended[9.0.11] but these conflict with your requirements or minimum-stability.                                        Problem 2                                                                                - The requested package typo3/phar-stream-wrapper (locked at v3.1.4, required as 3.1.5) is satisfiable by typo3/phar-stream-wrapper[v3.1.4] but these conflict with your requirements or minimum-stability.                                   Problem 3
    - drupal/core-recommended 9.1.5 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.4 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.3 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.2 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.1 requires drupal/core 9.1.x-dev -> satisfiable by drupal/core[9.1.x-dev] but these conflict with your requirements or minimum-stability.
    - drupal/core-recommended 9.1.0 requires typo3/phar-stream-wrapper v3.1.6 -> satisfiable by typo3/phar-stream-wrapper[v3.1.6] but these conflict with your requirements or minimum-stability.
    - Installation request for drupal/core-recommended ^9.1 -> satisfiable by drupal/core-recommended[9.1.0, 9.1.1, 9.1.2, 9.1.3, 9.1.4, 9.1.5].

```

# Answer
The error is here:

```
- drupal/ckeditor_a11ychecker 1.0.0 requires drupal/core ^8 -> satisfiable by drupal/core[8.0.0, 8.0.1, 8.0.2, 8.0.3, 8.0.4,...].

```

The `^8` in this line means that the version number of `drupal/core` must begin with an 8. You are requesting a version of core that begins with a 9. Therefore the installation fails.

The solution is to run `composer remove drupal/ckeditor_a11ychecker` before running your update process, to remove this conflict.
> 0 votes

# Answer
Due to the Composer documentation, there is the \`--with dependencies which:

> Update also dependencies of packages in the argument list, except those which are root requirements.

This option is not suitable in your case as the `typo3/phar-stream-wrapper` dependency is the root-package dependency and for `drupal/core-recommended`.

`--with-all-dependencies`:

> Update also dependencies of packages in the argument list, including those which are root requirements. This option will suit better in this case.

But my recommendation is to keep dependency versioning of `typo3/phar-stream-wrapper` package for `drupal/core-recommended` package and remove direct dependency to `typo3/phar-stream-wrapper` package. After removal, an example of updating of `drupal/core-recommended` has to work as expected, saving the project from dependency hell.
> 0 votes

---
Tags: composer, upgrading
---


# Question
Title: What function/method can I use to redirect users to a different page?
In Drupal 7, I use the following code.

```
function my_goto($path) {
  drupal_goto($path, array(), 301);
}

```

What code should I use in Drupal 8?

# Answer
> 35 votes
This is the code that should be used in Drupal 8. See change Record for more info.

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

function my_goto($path) {
  $response = new RedirectResponse($path);
  $response->send();
  return;
}

```

# Answer
> 31 votes
First (but read on for the correct, better aproach) it's important to note that Drupal 9.2 broke the simple way of doing it:

```
$response = new RedirectResponse($path);
$response->send();

```

You **have to** use the full code from the `drupal_goto()` changelog, namely:

```
$response = new RedirectResponse($url->toString());
$request = \Drupal::request();
// Save the session so things like messages get saved.
$request->getSession()->save();
$response->prepare($request);
// Make sure to trigger kernel events.
\Drupal::service('kernel')->terminate($request, $response);
$response->send();

```

**Still, this solution is not OK in many cases.** One prominent case is using it in hooks like eg. many modules that provide redirection after user login. Redirecting inside a hook means that the chain of hooks gets broken, there will be other hooks that don't get a chance to run after yours. This is wrong. The proper way to do it has been different for some time.

You create a middleware service that can be used for the purpose. Put this into `src/Middleware/Redirect.php`:

```
namespace Drupal\yourmodule\Middleware;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

class Redirect implements HttpKernelInterface {
  protected $httpKernel;
  protected $redirectResponse;

  public function __construct(HttpKernelInterface $http_kernel) {
    $this->httpKernel = $http_kernel;
  }

  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
    $response = $this->httpKernel->handle($request, $type, $catch);
    return $this->redirectResponse ?: $response;
  }

  public function setRedirectResponse(?RedirectResponse $redirectResponse) {
    $this->redirectResponse = $redirectResponse;
  }

}

```

refer to it in your `services.yml`:

```
services:
  http_middleware.yourmodule_redirect:
    class: Drupal\yourmodule\Middleware\Redirect
    tags:
      - { name: http_middleware }

```

and use it like any other service:

```
$url = Url::fromRoute('<front>', [], ['absolute' => 'true']);
$response = new RedirectResponse($url->toString());
\Drupal::service('http_middleware.yourmodule_redirect')->setRedirectResponse($response);

```

Yes, slightly more code, although the service can be reused any time, of course, calling it is simple enough. But this solution will not immediately halt execution, it will note your redirect request, do the proper thing and redirect on the next turn. A solution like that might get added to the core itself because there are places that would benefit from it, but until then, use your own, doing it correctly.

Credit goes to: https://www.drupal.org/project/redirect\_after\_login/issues/3214949

# Answer
> 9 votes
To build on Anu Mathew's response;

To add a status code, its just the second param in the RedirectResponse class;

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

function my_goto($path) {
  $response = new RedirectResponse($path, 302);
  $response->send();
  return;
}

```

# Answer
> 9 votes
This can be achieved by leveraging built-in symphonies EventDispatcher Component. All you have to do is create a custom module. Add your services.yml file and provide appropriate service config.

```
services:
  mymodue.subscriber:
    class: Drupal\my_module\EventSubscriber
    tags:
      - { name: event_subscriber }

```

in Your modules src directory add the EventSubscriber.php class and describe you methods here.

```
<?php
namespace Drupal\my_module;

use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class EventSubscriber implements EventSubscriberInterface {

  public function checkForCustomRedirect(RequestEvent $event) {
    $request = $event->getRequest();
    $route_name = $request->attributes->get('_route');
    if($route_name === 'module.testPage') {
      $url = Url::fromRoute('<front>')->toString();
      $event->setResponse(new RedirectResponse($url));
    }
  }

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

```

# Answer
> 8 votes
**Never use `$response->send()` under any circumstances**. This results in unpredictable behavior and might fail in different environments, when moving from dev to prod, for example, or in future updates, like it did for Drupal 9.2. (Edit: Recent example Site stuck in 'headers have already been sent' login loop after D9 upgrade)

The correct method depends on where you want to use it:

# Answer
> 6 votes
I didn't work in drupal 8 yet but as per the documentation `drupal_goto` is removed from Drupal 8.

In place of `drupal_goto` you need to write:

```
return new RedirectResponse(\Drupal::url('route.name'));

```

and something like this with parameters :

```
return new RedirectResponse(\Drupal::url('route.name', [], ['absolute' => TRUE]));

```

Check here https://www.drupal.org/node/2023537 and class RedirectResponse

# Answer
> 2 votes
this works for internal or external redirection:

```
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Url;

   $url = Url::fromUri('internal:/node/27'); // choose a path
   // $url =  Url::fromUri('https://external_site.com/');
    $destination = $url->toString();
    $response = new RedirectResponse($destination, 301);
    $response->send();

```

# Answer
> 1 votes
Perfectly working redirect code for me is the following:

```
$response = new RedirectResponse($path);
return $response->send();

```

In any other cases I'm getting some kind of exceptions or errors, for example: **LogicException: The controller must return a response...**

**OR**

https://www.drupal.org/project/drupal/issues/2852657

There is already a discussion about it, hope that helps!

# Answer
> 1 votes
*Gàbor's answer* with middleware implementation is perfect, thanks to him !

But I encountered the following error, introduced by **PHP 7.4 properties type-hinting** :

> Error: Typed property Drupal\your\_module\Middleware\Redirect::$redirectResponse must not be accessed before initialization.

I first tried to add RedirectResponse as an argument to the service and initialize it in the \__construct, but this resulted much simpler : declaring `$redirectResponse` **as nullable with default null** :

```
protected ?RedirectResponse $redirectResponse = null;

```

Full middleware below, credits again to Gàbor.

```
<?php
namespace Drupal\mail_forward_management\Middleware;

use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

class Redirect implements HttpKernelInterface {

  protected HttpKernelInterface $httpKernel;
  protected ?RedirectResponse $redirectResponse = null;

  public function __construct(HttpKernelInterface $httpKernel) {
    $this->httpKernel = $httpKernel;
  }

  /**
   * @inheritDoc
   */
  public function handle(
    Request $request,
    $type = self::MASTER_REQUEST,
    $catch = TRUE
  ) {
    $response = $this->httpKernel->handle($request, $type, $catch);
    return $this->redirectResponse ?: $response;
  }

  protected function setRedirectResponse(?RedirectResponse $redirectResponse) {
    $this->redirectResponse = $redirectResponse;
  }

  /**
   * Creates a new Url object for a URL that has a Drupal route,
   * and redirects to it.
   *
   * See \Drupal\Core\Url::fromRoute() for params details.
   *
   * @param string $route
   *    A Drupal route.
   * @param array $route_params
   *    (optional) An associative array of route parameter names and values.
   * @param array $opts
   *    (optional) An associative array of options.
   */
  public function redirectToRoute(string $route, array $route_params, array $opts ) {
    $destination = URL::fromRoute($route, $route_params, $opts);
    $response = new RedirectResponse($destination->toString());
    $this->setRedirectResponse($response);
  }

  /**
   * Creates a new Url object from a URI,
   * and redirects to it.
   *
   * See \Drupal\Core\Url::fromUri() for params details.
   *
   * @param string $uri
   *    The URI of the resource including the scheme.
   * @param array $opts
   *    (optional) An associative array of additional URL options.
   */
  public function redirectToUri(string $uri, array $opts ) {
    $destination = URL::fromUri($uri, $opts);
    $response = new RedirectResponse($destination->toString());
    $this->setRedirectResponse($response);
  }

}

```

**some\_module.services.yml**

```
services:
  http_middleware.some_module_redirect:
    class: Drupal\some_module\Middleware\Redirect
    tags:
      - { name: http_middleware }

```

**reusable service call**

```
 Drupal::service('http_middleware.some_module_redirect')
   ->redirectToRoute('user.page', [], ['absolute' => 'true']);

 // OR
 Drupal::service('http_middleware.some_module_redirect')
   ->redirectToUri('https://example.com/foo', [
      'query' => ['bar' => 'baz'],
    ]);

```

---
Tags: redirection, 8
---


# Question
Title: How do I suggest to use a template name like "node--[content-type-name]"?
I would like to name my node template after the content type title, but my suggestions only show the node number.

> FILE NAME SUGGESTIONS:
>
> * html--node--1.html.twig
> * html--node--%.html.twig
> * html--node.html.twig
> * x html.html.twig

I don't want to name it *node--1* just in case the node ID changes in the future. I'd like to name it *node--content-type-name*.

Is there a setting to enable this?

# Answer
> -1 votes
Just to be sure, do you want to name your node template (node.html.twig) or your html template (html.html.twig) after your content type name?

In the first case, the node type name template suggestion is accessible out of the box on the `node` template level. You just need to dig a bit further down into your html to where you are displaying the node (usually in the Main content block) to see the list of template suggestions.

In the event of the `html` template, since it is the top-level template and its {{content}} may contain anything (nodes, taxonomy terms, blocks...) you will have to rely on theme hook suggestions to build your own template name suggestions and tell Drupal about it. In that case, you have to use `hook_theme_suggestions_html_alter()` (See documentation about this hook).

---
Tags: theming, nodes, 9
---


# Question
Title: Drupal\Component\Plugin\Exception\PluginNotFoundException: The "<whatever>" plugin does not exist
After updading a Drupal site from 8.6.16 to 8.7.1 (PostgreSQL 9.6.13 , Nginx) I get this error in almost every operation (creating a view , installing a module, creating a content type, creating a menu, importing feeds, ....) with diferent plugins ("views.view.*","core.extension","node.type.*","system.menu.\*" )

```
Drupal\Component\Plugin\Exception\PluginNotFoundException: The "{whatever}" plugin does not exist.
Valid plugin IDs for Drupal\Core\TypedData\TypedDataManager are: filter_format, any, float, string, boolean, timespan,[...]
in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 53 de /"path-to-drupal"/web/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).

```

but there is **no error** when I create/delete a content (article), user, menu item, ...

I use the drupal-project composer template so my update process was:

```
composer update --with-dependencies webflo/drupal-core-require-dev drupal/* "symfony/*" -d /<path/to/site> --no-interaction ;
cd /path/to/site>
drush updb
drush cron
drush cr

```

It was not successfull, so I do this:

```
rm -rf vendor/*
composer update

```

and run again previous commands which It worked.

I though that I could be a problem with PHP version so I update from PHP 7.0 to PHP 7.3, but the error still remains. I also thought that it could be related with a feeds module installation so delete all feeds content, feeds types, etc .. and unistall and reinstall the module several times (also run drush devel-entity-updates because drupal status report warned of a feeds field that needed to be deleted)although two tables "feeds\_feed" and "feeds\_subscriptions" still remains in database.

After see that the problem was related with multiples plugins I start looking for a more generic issue (config?, permissions?, ...) but I dont find cause/solution.

**EDIT 1**

Looking for a stack trace I try using drupal console:

```
drupal site:mode dev -v

```

and get this:

```
In DiscoveryTrait.php line 53:

  [Drupal\Component\Plugin\Exception\PluginNotFoundException]
  The "system.performance" plugin does not exist. Valid plugin IDs for Drupal\Core\TypedData\TypedDataManager are: filter_format, any, float, string, boolean, timespan, language_reference, language, map
  , binary, timestamp, list, datetime_iso8601, uri, integer, duration_iso8601, email, field_item:comment, field_item:datetime, field_item:daterange, field_item:file_uri, field_item:file, field_item:font
  awesome_icon, field_item:image, field_item:link, field_item:list_integer, field_item:list_float, field_item:list_string, field_item:path, field_item:telephone, field_item:text, field_item:text_long, f
  ield_item:text_with_summary, field_item:time_range, field_item:time, field_item:webform, field_item:email, field_item:uri, field_item:entity_reference, field_item:uuid, field_item:timestamp, field_ite
  m:string_long, field_item:language, field_item:password, field_item:changed, field_item:float, field_item:decimal, field_item:map, field_item:boolean, field_item:integer, field_item:created, field_ite
  m:string, entity, entity:block, entity:block_content_type, entity:block_content, entity:block_content:basic, entity:captcha_point, entity:comment, entity:comment:comment_forum, entity:comment_type, en
  tity:contact_form, entity:contact_message, entity:contact_message:feedback, entity:contact_message:personal, entity:editor, entity:field_config, entity:field_storage_config, entity:file, entity:filter
  _format, entity:image_style, entity:imce_profile, entity:language_content_settings, entity:configurable_language, entity:media_type, entity:media, entity:media:audio, entity:media:file, entity:media:i
  mage, entity:media:remote_video, entity:media:video, entity:node_type, entity:node,[...], entity:node:page, entity:node:position, entity:rdf_mapping, entity:responsive_image_style, entity:rest_resource_config, entity:rules_reaction_rule, entity:rules_component, entity:s
  earch_page, entity:shortcut_set, entity:shortcut, entity:shortcut:default, entity:action, entity:menu, entity:taxonomy_vocabulary, entity:taxonomy_term, entity:taxonomy_term:badge_type, entity:taxonom
  y_term:categories, entity:taxonomy_term:forums, entity:taxonomy_term:materials, entity:taxonomy_term:nivel, entity:taxonomy_term:tags, entity:toolbar_menu_element, entity:tour, entity:user, entity:use
  r_role, entity:webform_options, entity:webform, entity:webform_submission, [..], entity:menu_link_content, entity:pathauto_pattern, entity
  :view, entity:base_field_override, entity:entity_view_mode, entity:entity_view_display, entity:entity_form_mode, entity:entity_form_display, entity:date_format, entity_reference

Exception trace:
 () at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php:53
 Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryCachedTrait.php:25
 Drupal\Core\Plugin\DefaultPluginManager->getDefinition() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/TypedData/DataDefinition.php:195
 Drupal\Core\TypedData\DataDefinition->getClass() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php:86
 Drupal\Core\TypedData\TypedDataManager->createInstance() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php:103
 Drupal\Core\TypedData\TypedDataManager->create() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/Config/TypedConfigManager.php:394
 Drupal\Core\Config\TypedConfigManager->createFromNameAndData() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/Config/StorableConfigBase.php:134
 Drupal\Core\Config\StorableConfigBase->getSchemaWrapper() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/Config/StorableConfigBase.php:179
 Drupal\Core\Config\StorableConfigBase->castValue() at /home/"<user>"/www/"<site>"/web/core/lib/Drupal/Core/Config/Config.php:212
 Drupal\Core\Config\Config->save() at /home/"<user>"/www/"<site>"/vendor/drupal/console/src/Command/Site/ModeCommand.php:150
 Drupal\Console\Command\Site\ModeCommand->overrideConfigurations() at /home/"<user>"/www/"<site>"/vendor/drupal/console/src/Command/Site/ModeCommand.php:87
 Drupal\Console\Command\Site\ModeCommand->execute() at /home/"<user>"/www/"<site>"/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /home/"<user>"/www/"<site>"/vendor/symfony/console/Application.php:987
 Symfony\Component\Console\Application->doRunCommand() at /home/"<user>"/www/"<site>"/vendor/symfony/console/Application.php:255
 Symfony\Component\Console\Application->doRun() at /home/"<user>"/www/"<site>"/vendor/drupal/console-core/src/Application.php:184
 Drupal\Console\Core\Application->doRun() at /home/"<user>"/www/"<site>"/vendor/drupal/console/src/Application.php:64
 Drupal\Console\Application->doRun() at /home/"<user>"/www/"<site>"/vendor/symfony/console/Application.php:148
 Symfony\Component\Console\Application->run() at /home/"<user>"/www/"<site>"/vendor/drupal/console/bin/drupal.php:89
 require() at /home/"<user>"/www/"<site>"/vendor/drupal/console/bin/drupal:4

```

**EDIT 2**

looking at the database I found two tables from feeds module (supposed to be uninstalled)

feeds\_feed feeds\_subscription

running drupal console commnand `drupal debug:module` feeds appears as the only module uninstalled with a schema version defined

```
ID     Name   Package  version      schema version  status      origin
...
feeds  Feeds  Feeds  8.x-3.0-alpha5    8001         Uninstalled no core
...

```

**EDIT 3**

After enable debugging (How do I enable developer/debug mode?)

I got new clues about the error ( trying to create a view) but my lack of drupal core knowledge stops me from understanding where final cause is:

```
</br></br><em class="placeholder">Drupal\Component\Plugin\Exception\PluginNotFoundException</em>: The "views.view.*" plugin does not exist. Valid plugin IDs for Drupal\Core\TypedData\TypedDataManager are: filter_format, any, float, string, boolean, timespan, language_reference, language, map, binary, timestamp, list, datetime_iso8601, uri, integer, duration_iso8601, email, field_item:comment, field_item:datetime, field_item:daterange, field_item:file_uri, field_item:file, field_item:fontawesome_icon, field_item:image, field_item:link, field_item:list_integer, field_item:list_float, field_item:list_string, field_item:path, field_item:telephone, field_item:text, field_item:text_long, field_item:text_with_summary, field_item:time_range, field_item:time, field_item:webform, field_item:email, field_item:uri, field_item:entity_reference, field_item:uuid, field_item:timestamp, field_item:string_long, field_item:language, field_item:password, field_item:changed, field_item:float, field_item:decimal, field_item:map, field_item:boolean, field_item:integer, field_item:created, field_item:string, entity, entity:block, entity:block_content_type, entity:block_content, entity:block_content:basic, entity:captcha_point,
[...]
entity:entity_view_mode, entity:entity_view_display, entity:entity_form_mode, entity:entity_form_display, entity:date_format, entity_reference in <em class="placeholder">Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition()</em> (line <em class="placeholder">53</em> of <em class="placeholder">core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php</em>). <pre class="backtrace">Drupal\Core\Plugin\DefaultPluginManager->getDefinition('views.view.*') (Line: 195)
Drupal\Core\TypedData\DataDefinition->getClass() (Line: 86)
Drupal\Core\TypedData\TypedDataManager->createInstance('views.view.*', Array) (Line: 103)
Drupal\Core\TypedData\TypedDataManager->create(Object, Array) (Line: 394)
Drupal\Core\Config\TypedConfigManager->createFromNameAndData('views.view.test2', Array) (Line: 134)
Drupal\Core\Config\StorableConfigBase->getSchemaWrapper() (Line: 179)
Drupal\Core\Config\StorableConfigBase->castValue('uuid', 'c2f6326b-a77f-4f1e-9698-cb96154252cb') (Line: 212)
Drupal\Core\Config\Config->save() (Line: 284)
Drupal\Core\Config\Entity\ConfigEntityStorage->doSave('test2', Object) (Line: 449)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 263)
Drupal\Core\Config\Entity\ConfigEntityStorage->save(Object) (Line: 394)
Drupal\Core\Entity\EntityBase->save() (Line: 613)
Drupal\Core\Config\Entity\ConfigEntityBase->save() (Line: 993)
Drupal\views_ui\ViewUI->save() (Line: 191)
Drupal\views_ui\ViewAddForm->submitForm(Array, Object)
call_user_func_array(Array, Array) (Line: 111)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 51)
Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 590)
Drupal\Core\Form\FormBuilder->processForm('view_add_form', Array, Object) (Line: 319)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 93)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
</pre>

```

# Answer
The cause of issue was an indentation error on a config file in a subtheme (../config/schema/subtheme.schema.yml).

This file (from a my custom Bootstrap Barrio subtheme) have no indentation after "mapping:" :

```
#Schema for the configuration files of the Bootstrap Barrio Subtheme.

totaltheme.settings:
  type: theme_settings
  label: 'Totaltheme settings'

mapping:
  bootstrap_barrio_sidebar_position:
    type: text
    label: 'Sidebar Position'
  bootstrap_barrio_content_offset:
  ...

```

instead of this

```
#Schema for the configuration files of the Bootstrap Barrio Subtheme.

totaltheme.settings:
  type: theme_settings
  label: 'Totaltheme settings'
  mapping:
    bootstrap_barrio_sidebar_position:
      type: text
      label: 'Sidebar Position'
    bootstrap_barrio_content_offset:
    ...

```

This thing caused all "Drupal\Component\Plugin\Exception\PluginNotFoundException: The "{whatever}" plugin does not exist." errors.

I found a copy of the file with .save at end of filename (subtheme.schema.yml.save) with the correct indentation so I supposed something happened while editing the file (using nano in linux).
> 1 votes

# Answer
Try this command, it works well.

```
drush eval "drupal_flush_all_caches();"

```

or

```
drush cr discovery

```

Refer: https://www.drupal.org/project/drupal/issues/3056633
> 1 votes

# Answer
possibly an APC server cache problem ?

Add this to local.settings.php

```
$settings['class_loader_auto_detect'] = FALSE;

```

or restart server
> 1 votes

---
Tags: updating, plugins
---


# Question
Title: Views Reference Field shows nodes of all groups
On my website users can create groups. All groups have two content types:

* Book
* Chapter (is always a child of content type Book)

Only administrators are allowed to create new nodes. An administrator could be a member of two groups.

In the content type Book a Views Reference Field is created, which all nodes from the content type Chapter shows.

The problem I'm facing: If an administrator creates a new Book node, he could use the Views Reference Field to connect chapter to the book. But the Views Reference Field shows lessons of both groups.. it should only show the lessons which are created in the group he is working in.

Any ideas how I can restrict the Views Reference Field to the current group of the administrator?

# Answer
On the field settings administration page, you can set the **Reference method** to a view that you create (create a new view or add a Entity Reference display to an existing view), so you could filter the available results of the autocomplete field according to your criteria (I believe that contextual filters should be available in that view as well)
> 0 votes

---
Tags: views, 9, group
---


# Question
Title: How do I migrate body content with [embed]*[/embed] tags?
Currently I am working on migrating a Drupal 7 site to Drupal 9. The nodes in the site has nodes with content similar to the following one.

```
<h3><strong>WHAT WILL YOUR NEXT MEAL BE?</strong></h3>
<p>[embed]https://www.youtube.com/watch?v=Np28O3Y_P2o[/embed]</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry galley of type and Lorem Ipsum</p>

```

I tried to dump the value into the *Body* field with the *Rich Text Filter*, but the nodes are displayed with a link between `[embed]` and `[/embed]`, instead of a render item.

Can anyone please suggest a migration plugin or a way to convert `<p>[embed]https://www.youtube.com/watch?v=Np28O3Y_P2o[/embed]</p>` to Drupal 9 Media entities?

# Answer
> 1 votes
I am not aware about any plugins for this case.

But you can write your custom plugin.

In the custom plugin you will need to parse text by a regular expression and create youtube media entities from it manually.

Here are some code examples to point you to a right direction.

The migration process plugin will parse the text, and process embed parts:

```
<?php

namespace Drupal\my_migrate\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Provides a body text migrate process plugin.
 *
 * @MigrateProcessPlugin(
 *  id = "body_text"
 * )
 */
class BodyText extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $body = '';

    if (preg_match_all('/[embed](.*)[/embed]/Usi', $text, $matches)) {
      // Text parts splitted by embeds.
      $text_parts = preg_split('/[embed](.*)[/embed]/Usi', $text);

      $body = $text_parts[0];
      unset($text_parts[0]);
      $text_parts = array_values($text_parts);

      // Loop text parts, create media embeds.
      foreach ($text_parts as $key => $text_part) {
        if (isset($matches[1][$key])) {
          $embed = $matches[1][$key];
          if (!$text) {
            $this->addTag(MigrationTags::TAG_MISSING_QUOTE);
          }
          $body .= $this->createYoutubeEmbed($embed);
        }

        $body .= $text_part;
      }
    }
    return $body;
  }

  protected function createYoutubeEmbed($embed) {
    // 1. Create youtube media entity using the URL.
    // 2. Generate media embed.
  }

}

```

In the `createYoutubeEmbed` method you will need to

1. Create youtube media entity using the URL.
2. Generate media embed. To figure out how the youtube media embed should look like, create some content in Drupal manually and see the source code in the CKEditor.

This is an example for media image embed that I implemented in my migration:

```
/**
   * Creates media image embed for text paragraphs.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media image.
   * @param string $align
   *   (optional) The image alignment, allowed values: left, right, center.
   * @param string $display
   *   (optional) The image display variant. Allowed values: large (default),
   *   medium, small.
   * @param string $link
   *   (optional) Link URL.
   *
   * @return string
   *   The embed code.
   */
  protected function createMediaImageEmbed(MediaInterface $media, $align = '', $display = 'large', $link = NULL) {
    $attributes = [
      'data-embed-button' => $media->bundle(),
      'data-entity-embed-display' => 'view_mode:media.' . $display,
      'data-align' => $align,
      'data-entity-type' => 'media',
      'data-entity-uuid' => $media->uuid(),
      'data-langcode' => 'de',
    ];
    if ($link) {
      $link = str_replace("/", "\/", $link);
      $attributes['data-entity-embed-display-settings'] = '{"link_url":"' . $link . '\/","link_url_target":0}';
    }
    $embed = '<drupal-entity';
    foreach ($attributes as $key => $value) {
      $embed .= " $key=\"$value\"";
    }
    $embed .= '></drupal-entity>';
    return $embed;
  }

```

---
Tags: media, migrations, 9
---


# Question
Title: Can I use two different forms in one module?
I'm new to Drupal 8 and I was wondering if I can use two forms which are inside the Form folder(mymodule/src/Form/). The name of my forms are FormOne.php and FormTwo.php.

I can only display and use FormOne.php through my entire module.

I have researched it and can't find an answer.

Can you help me on displaying the second form?

# Answer
Yes, you can define as many forms in a module as you need.

If you want to include two forms into one page, you can do so by using the form builder in your controller to call both forms and build a render array.

Instead of using `_form` in your `*.routing.yml` file, you would instead use `_controller`, and define a controller callback rather than a form callback. Your controller would then be something like this:

```
class ExampleController extends Drupal\Core\Controller\ControllerBase {

  function examplePageCallback() {
    // Note - you should use dependency injection to inject this service,
    // rather than this method.
    $form_builder = \Drupal::service('form_builder');

    $return [
      'form_a' => $form_builder->getForm('Drupal\[MODULE]\Form\FormA'),
      'form_b' => $form_builder->getForm('Drupal\[MODULE]\Form\FormB'),
    ];
  }
}

```
> 2 votes

# Answer
You can create a custom Form in `MyCustomFormA.php`

```
<?php

namespace Drupal\MY_MODULE\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class MyCustomFormA.
 */
class MyCustomFormA extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'my_custom_form_a';
  }
.....
}

```

Same way you can create another Form in `MyCustomFormB.php`

```
<?php

namespace Drupal\MY_MODULE\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class MyCustomFormB.
 */
class MyCustomFormB extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'my_custom_form_b';
  }
....
}

```

In your `MY_MODULE.routing.yml`

```
MY_MODULE.my_custom_form_a:
  path: '/MY_MODULE/my_custom_form_a'
  defaults:
    _form: '\Drupal\MY_MODULE\Form\MyCustomFormA'
    _title: 'My Custom Form A Form'
  requirements:
    _permission: 'access content'
MY_MODULE.my_custom_form_b:
  path: '/MY_MODULE/my_custom_form_b'
  defaults:
    _form: '\Drupal\MY_MODULE\Form\MyCustomFormB'
    _title: 'My Custom Form B Form'

  requirements:
    _permission: 'access content'

```
> 2 votes

---
Tags: forms
---


# Question
Title: Is there a way to render the title of every node from a single content type?
I have a page on a Drupal 9 site that will have a filter and a search bar. The filter needs to have each product and each region the product is sold in.

So I created 2 content types - Product and Region, and created a node for each one that just has a title.

I want to loop through each Product and Region node and display them on the page that has the filter.

Is it possible to render this data in a TWIG file?

# Answer
Templates are for formatting the output of data. They essentially wrap the data in HTML. Data generation is not handled in templates, it happens earlier in the pipeline, and the data is passed to the template, to wrap the data in HTML.

In this case, you want a View, as Kevin indicated in the comments. Views is a Drupal core module that provides a GUI for creating database queries and outputting the resulting data. You can then use the Twig Tweaks module and call a view in your Twig template as follows:

```
{{ drupal_view('who_s_new', 'block_1') }}

```

If you need to theme the output of the view, the Views module provides methods for templating the output of the view.
> 2 votes

---
Tags: theming, nodes, 9
---