# Question
Title: Gracefully handle URL/URI/Link exceptions when using Link field formatter?
Occasionally I am encountering an error along these lines:

```
The website encountered an unexpected error. Please try again later.InvalidArgumentException: The URI 'XYZ' is invalid. You must use a valid URI scheme. in Drupal\Core\Url::fromUri() (line 290 of core/lib/Drupal/Core/Url.php).

```

We are migrating data frequently and one thing that can happen is link field URIs can come in like that. The core LinkFormatter class does not seem to handle exceptions, although there is this issue:

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

If this patch does not apply/work, what other resolution is there? Should I point the LinkFormatter class definition to a custom class that catches exceptions?

# Answer
Turns out that the patch for this core LinkFormatter class (#50) works against Drupal 9.2.6 currently.

There are a few ways this data can get into the application outside of user-entry in Drupal forms where we cannot always validate that a link URI is good or whats intended from external API sources. This patch catches exceptions and allows the site to function normally for the public.
> 1 votes

---
Tags: entities, uri, 9
---


# Question
Title: How can I programmatically delete a user without deleting their content?
I want to delete a user with this code:

```
$account = User::load(19920);
$account->delete();

```

How can I do that without also deleting the user's content?

I've been reviewing \_user\_cancel() hooks, but they all seem to be about doing things in the admin UI.

This hook works the way I expect it to and removes the user\_cancel\_delete radio button option from the admin UI.

```
/**
 * Implements hook_user_cancel_methods_alter().
 */
function my_user_module_user_cancel_methods_alter(&$methods) {
  // Remove Delete the account and its content method.
  unset($methods['user_cancel_delete']);
}

```

but I want to not delete content when `$account->delete()` is called in my update hook.

# Answer
> 5 votes
Yes, you can use the user\_cancel process to prevent content being deleted. As you found out it doesn't help to remove the options from UI. Programmatically you need to call the function directly, specifying the method `user_cancel_reassign` to replace the author with anonymous before deleting the user:

```
user_cancel([], $uid, 'user_cancel_reassign');
$account = User::load($uid);
$account->delete();

```

Caveat: This doesn't work for more than 10 pieces of content. Then you need to run this as a batch, which also would delete the user as final step of the batch process. See user deletion : user\_cancel\_reassign not working when user has more than 10 associated contents

---
Tags: users, 9
---


# Question
Title: Disable user login, register and password reset
I am working on a Drupal 8 site that for all intents and purposes will be used as a company intranet. I'm also using the Social Auth Google module to allow only company-registered GSuite accounts to use the site.

I have tested this module, and it works great! However, I'd like to remove the /user/login, /user/register, and /user/password routes, as well as the associated tabs (as per screenshot below), to prevent anyone using **anything but** the Google Social Auth login feature.

>

Sure, I could use CSS to *hide* these elements, but that doesn't feel right to me.

I'd appreciate any guidance on how to achieve this.

# Answer
in a custom module that we call 'custom', have custom.services.yml with content :

```
    services:
  custom.route_subscriber:
    class: Drupal\custom\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

```

then create the file src/Routing/RouteSubscriber.php with the following :

```
<?php

namespace Drupal\custom\Routing;

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

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Always deny access to unwanted routes.
    $disallow_routes = [
      'user.login',
      'user.register',
      'user.pass',
    ];
    foreach ($disallow_routes as $disallow_route) {
      if ($route = $collection->get($disallow_route)) {
        $route->setRequirement('_access', 'FALSE');
      }
    }
  }

}

```

enable the 'custom' module and this should work :)
> 7 votes

# Answer
You could disable the login page with the Disable Login Page module. This will disallow accessing the login page without the required key value pair in the querystring.
> 0 votes

---
Tags: 8, users
---


# Question
Title: How accurate is the field list for estimating where fields are used?
I am trying to locate all places where a particular field is used. I am trying to see especially which all Views have required the field.

I was planning to do a manual search using editor Find and grep. Then I came to know about the field list option under Reports - /admin/reports/fields

It showed that the field is not being used by an views.

How accurate is this report? Can it be trusted blindly or do we need to complement it with an additional search?

# Answer
> 0 votes
As @leymannx mentioned I did a grep of the field in the config folder and although the field did come up in one of the Views on my Drupal site, it was mostly registered as a dependency and not used. So it is safe to say that the field list is somewhat accurate.

---
Tags: 8, entities
---


# Question
Title: Show the same content with different urls
I need to show the same content with different urls.

I would like to create dynamic routes when saving a node in Drupal 9.

Does this seem the right way?

Some other solution or similar module.

A specific use case:

node/1 -\> 'How to sign up'

url -\> '/actor/how-to-sign-up', '/supporter/how-to-sign-up'

P.S. I need the first part of the path (actor,supporter) for various checks

# Answer
> 1 votes
The only example in Drupal core for a dynamic route depending on user saved data is a View with a page display and this takes a very long time to save. Views needs routes for contextual filters. Unless you have such a specific use case for content (please edit your question if you have one), the right way would be aliases. In the node edit form you can add only one alias, but you can add more in */admin/config/search/path*. If you want that in one place you could alter the node edit form for multiple aliases.

If you don't want to create each alias by hand and the paths have a pattern you can use a path processor. You can create the scaffolding with drush

```
drush gen path-processor

```

and put the regex pattern in the inbound method:

*/modules/custom/mymodule/src/PathProcessor/PathProcessorMymodule.php*

```
<?php

namespace Drupal\mymodule\PathProcessor;

use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Path processor to remove a prefix.
 */
class PathProcessorMymodule implements InboundPathProcessorInterface {

  /**
   * {@inheritdoc}
   */
  public function processInbound($path, Request $request) {
    return preg_replace('#^/(author|supporter)/#', '/', $path);
  }

}

```

You can get the original path later with

```
\Drupal::request()->getPathInfo()

```

or you could store the prefix in a service property before removing it to make it globally available.

If your checks produce rendered output then add the `url.path` cache context.

---
Tags: routes
---


title: Syncing of order and shipping states

text:
# Question
Title: Syncing of order and shipping states
In Drupal 9, I have defined the following order workflow for Drupal Commerce:

```
miss_pomela_fulfillment_processing:
  id: miss_pomela_fulfillment_processing
  group: commerce_order
  label: 'Miss Pomela Fulfillment, with processing'
  states:
    draft:
      label: Draft
    pending:
      label: Pending
    processing:
      label: En preparación
    packed:
      label: Ready to ship
    fulfillment:
      label: Shipped
    completed:
      label: Completed
    canceled:
      label: Canceled
  transitions:
    place:
      label: 'Create order'
      from: [draft]
      to: pending
    process:
      label: 'Process order'
      from: [pending]
      to: processing
    fulfill:
      label: 'Mark as ready to ship'
      from: [processing]
      to: packed
    ship:
      label: 'Ship'
      from: [packed]
      to: fulfillment
    complete:
      label: 'Mark as completed'
      from: [processing, pending, packed, fulfillment]
      to: completed
    cancel:
      label: 'Cancel order'
      from: [draft, processing, fulfillment, pending, completed]
      to:   canceled

```

I'm trying to understand how to sync the order state with the shipping state the way I need.

Right now, with this workflow, the shipping state changes automatically to Shipped when the packed state order is set, so when the fulfill transition is occurs. But what I want to have is the shipping state as Ready when the state order is packed, and shipped when the state order is fulfillment.

I have tried to find out how to tell the shipping module how to set how to synchronize both states but I'm a bit lost.

Any ideas?

# Answer
There is no configuration solution for syncing states between these items. It's ordinarily managed via custom event subscribers. Your code reacts to a given order transition and then loads a shipment and applies whatever transition you think is appropriate. There are examples of event subscribers in core if you need a reference, e.g. the `OrderAssignSubscriber` in the payment module that assigns payment methods related to an order to the same user account as the order is being assigned to.
> 0 votes

---
Tags: commerce, 9
---


title: How many product types do I need?

text:
# Question
Title: How many product types do I need?
I am in the process of creating an e-commerce site with drupal commerce 2. This site is dedicated to selling clothes for men, women and children. I created a type of clothing product I called *Clothes*. I have implemented the management of color and size attributes, but my problem is knowing how to manage clothes for men and women with the same type of clothing content. Should we create a type of content clothing for men, a type of clothing for women knowing that men do not wear specific dresses for women?

Shoud I create a product type for woman called clothes\_for\_woman and clothes\_for\_man, or use the same content type for all? How do I manage it?

Note: This is the idea I thought of: add an additional field to specify whether it is clothing for women, men or children. A civility or gender field with terms like Male, Female, Boy, Girl or Baby isn't it? When entering a product, make this field mandatory. –

# Answer
The *gender field* you mentioned can perfectly be implemented as a product attribute, so just an appropriate field for product type “clothes”. I.e. for that you do not need to create multiple product types.
> 1 votes

# Answer
I would not recommend this as a product attribute since clothes gender types (male/female/kids(girl/boy)) are not "variations", and should not be stored as such, and we know attributes are for creating variations of the same product entity. This might also complicate and reduce the flexibility when creating views for categorising based on gender and creating pages for them. I agree with another comment made that this is very subjective and could be done in many ways, but I prefer to solve this with a taxonomy field "Gender" with the terms, Male, Female, Kids (Boy, Girl). Make this field mandatory when adding a product of type "Clothes". This method will simplify the creation of search/filter pages of views categories as you want to distinguish clothes based on gender etc. And would also simplify creating facets on search pages.
> 0 votes

---
Tags: commerce, 9
---


# Question
Title: Could not initialize PECL extension even though memcached installed
I am migrating a site from one remote server to another. I have set up the new server will all the prerequisites installed memcached server and its extension too. But when I try to run drush cr I get the error `Could not initialize PECL extension`

I wrote a simple php code to check if memcached is running and if the php code is able to read and write to memcached and it works just fine. Please find sample code below

```
<?php

$memcache = new Memcached;
$memcache->addServer('localhost', 11211) or die ("Could not connect");

$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/>\n";

$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;

$memcache->set('key', $tmp_object, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>\n";

$get_result = $memcache->get('key');
echo "Data from the cache:<br/>\n";

var_dump($get_result);

?>

```

My issue is I keep getting the error as shown below

```
In DrupalMemcachedFactory.php line 53:

  Could not initialize  PECL extension

```

Would anyone of you have any idea why this might be happening? How do I get this sorted?

# Answer
> 1 votes
I encountered the same issue and after some digging I found that the issue was due to multiple php versions installed on server.

By default Drush uses the system php to run and in our case it didn't have any extensions loaded since it wasn't serving any websites.

Try to run drush using absolute path to the website's php like so:

```
/usr/bin/php74 /path/to/drush cr

```

*This assumes that the php74 executable is in /usr/bin which is usually the case*

---
Tags: drush
---


# Question
Title: How can i render a file using a formatter programmatically in a controller?
I'm trying to create a controller to render a swagger documentation using the module swagger\_ui\_formatter that provide a formatter to the file field that render swagger files (yml, yaml, json) using javascript libraries to show the documentation like swagger website do. Then i copy my yml file in my module directory and in my controller i can load this file.

```
  public function buildApiDocumentation() {

    $file_system = \Drupal::service('file_system');

    $searchFiles = '/^.*\.(yml)$/';
    $directory = dirname(__DIR__,2).'/docs';

    $file = $file_system->scanDirectory($directory, $searchFiles, ['recurse' => FALSE]);
}

```

But i don't know how can i render this file using the swagger formatter that the module provide, i can't use the traditional way to use this formatter, creating a content type with a file field and after that create a view and render it, because is a very manual process and i need to fix the api documentation file in a directory that only the dev team can update.

# Answer
You can return a BinaryFileRespose from your controller:

```
use Symfony\Component\HttpFoundation\BinaryFileResponse;

public function buildApiDocumentation() {

  $file_system = \Drupal::service('file_system');

  $searchFiles = '/^.*\.(yml)$/';
  $directory = dirname(__DIR__,2).'/docs';

  $file = $file_system->scanDirectory($directory, $searchFiles, ['recurse' => FALSE]);

  return new BinaryFileResponse($file);
}

```
> 0 votes

# Answer
as @apaderno mentioned we can't use a formatter that way, then i decided to build my own module to render my swagger documentation using the official swagger ui, and load the file using a javascript directive.

Thanks for helping.
> 0 votes

---
Tags: 8, files, page-controller
---


# Question
Title: How to get a delta value from a composite with ilimited values?
I have this webform with composite field where I add a file and a field where I add a number.

What I wish is using the token, to rename the file with number inputed in the number field. But the thing is I have a composite with multiple ilimited values and I can only do it if I declare a delta number as the following token: \[webform\_submission:values:element\_key:delta:sub\_element\_key\]

How can I do it programatically if it is possible?

Also, it's possible sum up composite multiple values using computed twig? As above, the delta seems the problem.

# Answer
For the first part of the question I still have no clue, it might not be (only) the delta the problem as I could work around it using computed twig data, but the fact the attachment and the number field are inside the composite, what may create a looping error.

As for the second question, here what worked for me using the computed twig from webform:

**SUM TOTAL OF THE COMPOSITE SUBELEMENT:**

```
{% for item in data.composite_element_key %}
  {% set sum = item.subelement_key + sum ?? 0 %}
  {% if loop.last %}{{ sum }}{% endif %}
{% endfor %}

```

Thanks to https://craftcms.stackexchange.com/a/16445
> 1 votes

---
Tags: webforms, tokens
---


# Question
Title: How to get table names from external DB in non public schema
I am writing a configuration entity modul in drupal 9. I want to list all tables, from an external database (postgis) in the schema called gi. The switch between the databases is no problem. I'm searching for a way, to only get the name of the table called gruenzuege to put this in a markup form.

//the form where to save the table

```
 $form['tables'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Tables'),
      '#collapsible' => TRUE, // Added
      '#collapsed' => FALSE,  // Added
  ];

```

//External Database connection

```
$postgis_database = array(
      'database' => $drugis_postgis_connection->getdatabase(),
      'username' => $drugis_postgis_connection->getusername(),
      'password' => $drugis_postgis_connection->getpassword(),
      'host' => $drugis_postgis_connection->gethost(),
      'driver' => 'pgsql'
  );
Database::addConnectionInfo('postgis', 'default', $postgis_database);
Database::setActiveConnection('default', 'postgis');

```

//example for fetching table:gruenzuege in drupal

```
    $results = Database::getConnection('default', 'postgis')->query('SELECT * FROM "gi"."gruenzuege"')->fetchAll();
dpm($results);

```

I don't understand how to query to another schema, to get only, the table names of the schema gi? It is actually the only table. Thanks for help

# Answer
> 0 votes
listing all table names in an array

```
$example_database = array(
      'database' => ...,
      'username' => ...,
      'password' => ...,
      'host' => ...,
      'driver' => 'pgsql'
  );

Database::addConnectionInfo('example_key', 'default', $example_database);
Database::setActiveConnection('default', 'example_key');

$result=Database::getConnection('default', 'example_key')->query("SELECT table_name FROM information_schema.tables WHERE table_schema = '" . example_schema . "';");
  $tables = $result->fetchAll();

foreach( $tables as $table ) {
      dpm($table->table_name);
      $tableNames[] = $table->table_name;
  }

Database::setActiveConnection();

```

---
Tags: database, 9
---


# Question
Title: Hook webform options WEBFORM OPTIONS ID alter()
`[{"value_1":"Dragon fly"},{"value_1":"Agapostemon angelicus"},{"value_1":"Albuna oberthuri"},{"value_1":"Callohesma flavopicta"}]`

This is a JSON data i need to use to import for radios in drupal 8 webforms. Iam using hook\_webform\_options\_WEBFORM\_OPTIONS\_ID\_alter() https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-use-options-from-an-external-webservice

I cant use value\_1 as a key in radios, cause it is not unique, so I need to somehow copy the value into the key and get the same data on both sides, too look like this.

`[{"Dragon fly":"Dragon fly"},{"Agapostemon angelicus":"Agapostemon angelicus"},{"Albuna oberthuri":"Albuna oberthuri"},{"Callohesma flavopicta":"Callohesma flavopicta"}]` there are many lists and many data but the same problem.

This is the code from the module I made followed by instructions:

```
 * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
 */
function my_module_webform_options_external_countries_alter(array &$options, array &$element) {
  // Load cached options.
  if ($cache = \Drupal::cache()->get('external_countries')) {
    $options = $cache->data;
    return;
  }

  // Get data as associative array from the external webservice.
  $external_countries_url = 'https://gist.githubusercontent.com/mshafrir/2646763/raw/8b0dbb93521f5d6889502305335104218454c2bf/states_hash.json';
  $options = json_decode(file_get_contents($external_countries_url), TRUE);

  // Cache options so that we don't have to make continual requests
  // to the external webservice.
  \Drupal::cache()->set('external_countries', $options);
}

```

# Answer
I just found a solution. I probably didn't explain it well, so there was no answer. I hope that the solution to the problem I had will better explain the situation I was in.

```
function external_usa_list_webform_options_external_countries_alter(array &$options, array &$element) {
  // Load cached options.
  if ($cache = \Drupal::cache()->get('external_countries')) {
    $options = $cache->data;
    return;
  }

  // Get data as associative array from the external webservice.
  $external_countries_url = 'https://gist.githubusercontent.com/mshafrir/2646763/raw/8b0dbb93521f5d6889502305335104218454c2bf/states_hash.json';
  $options = json_decode(file_get_contents($external_countries_url), TRUE);

  $options = array_combine(array_values($options), array_values($options));

  // Cache options so that we don't have to make continual requests
  // to the external webservice.
  \Drupal::cache()->set('external_countries', $options);
}

```
> 3 votes

---
Tags: 8, hooks
---


title: Comments on user profile not working

text:
# Question
Title: Comments on user profile not working
I want to add comments to user profiles. I added the comments in user profile under *Configuration \> People \> Account settings*, but when I add the field, the option to select the comment type is showing empty. What is the correct way to allow other users to give comments on user profiles?

# Answer
> 5 votes
Each **Comment Type** can only be applied to one type of entity (nodes (*content*), users, and taxonomy terms are examples of different types of entities).

By default, Drupal core only provides a comment type for nodes.

So, to add comments on users, you will need to create a user comment type.

1. Go to `/admin/structure/comment`.
2. Select *Add comment type*.
3. Add a **Label** such as *User comments*.
4. For **Target entity type**, select *Users*.
5. For the comments field at `/admin/config/people/accounts/fields`, select your new user comment type.

---
Tags: 8, comments
---


title: How do I disable the Quick edit module?

text:
# Question
Title: How do I disable the Quick edit module?
I tried uninstalling *Quick edit* via the user interface.

>

I cleared the cache via `drush cr`, but it doesn't work.

>

How can I disable it?

Even `drush en -y quickedit` and `drush pmu quickedit` don't work.

# Answer
> 7 votes
As far as I understand your question, you want to get rid of the "Edit" pen icon, displayed when you put the mouse over a node.

This is not provided by the "Quick Edit" module. You have to disable "Contextual Links" if you want to get rid of that menu.

Alternatively, if you are using those links for managing blocks for example, you might want to force hiding contextual links on nodes via CSS.

For example:

```
.your-node-selector .contextual {
  display: none!important;
}

```

# Answer
> 2 votes
The contextual links are cached in the browser local storage. If you are seeing outdated contextual links, open the developer toolbar and clear out the local storage and session storage. This will repopulate the contextual links from the backend and they will be correct again.

---
Tags: theming, 8
---


# Question
Title: Open new tab with external link using an image button
I am making a custom module with a form that has an image button. The image button will open the external link with the value of a textfield inside the form. I have searched any possible solution in the internet but can't find a solution.

How do I code a submitForm button to open an external link with a form value of a textfield inside the form.

Below is my sample codes:

```
$form['search'] = [
      '#type' => 'textfield',
      '#title' => 'Search for',
      '#required' => TRUE
];

$form['submit'] = [
    '#type' => 'image_button',
    '#value' => $this->t(''),
    '#src' => 'modules/myModule/src/images/myImage.png',
    '#submit' => ['::submitForm'],
];

```

I also try to use these codes for the button but still no luck:

```
$form['submit'] = [
    '#type' => 'item',
    '#markup' => $this->t('
        <a href=\'https://www.google.com/search?%search\' target="_blank">
           <img width="30" height="30" border="0" align="center"  src=\'modules/myModule/src/images/myImage.png\'/>
        </a>', ['%search' => $search]),
];

```

*Please note that these are not my actual codes but these are the concept of my codes.*

Any comments and suggestions are welcome.

Thank you in advance.

# Answer
If you use the `formtarget` HTML attribute on your image button, submit will happen in a new browser tab. Here is a basic example:

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $form['search'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Search for'),
    '#required' => TRUE,
  ];

  $form['image_button'] = [
    '#type' => 'image_button',
    '#value' => 'hello',
    '#src' => '/path/to/my/image',
    '#submit' => ['::mySubmitFunction'],
    '#attributes' => [
       // This attribute will open a new browser tab on form submission
      'formtarget' => '_blank'
    ]
  ];

  return $form;
}

public function validateForm(array &$form, FormStateInterface $form_state) {
  // Do whatever form validation is needed
}

public function mySubmitFunction(array &$form, FormStateInterface $form_state) {
  $search = $form_state->getValue('search'); // Fetch 'search' field value
  // since we want to redirect to an external url,
  // we need to use \Drupal\Core\Routing\TrustedRedirectResponse
  // because redirect to external URL is not allowed by default
  $externalURL = \Drupal\Core\Url::fromUri('https://example.com',
    ['query' => ['search' => $search]]
  );
  $response = new TrustedRedirectResponse($externalURL->toString());
  $form_state->setResponse($response);
}

```
> 2 votes

---
Tags: forms, 9
---


# Question
Title: How to remove big pipe <script> tags from page response
I need to remove `<script>` tags from some pages. I have managed to remove almost all of them, but these remain:

```
<script type="application/vnd.drupal-ajax" data-big-pipe-event="start"></script>

<script type="application/vnd.drupal-ajax" data-big-pipe-event="stop"></script>
</body>

```

How do I remove those scripts?

# Answer
> 2 votes
These scripts are added by the core module BigPipe.

If you want to remove them from a specific page then add the option `_no_big_pipe` to the route:

```
$route->setOption('_no_big_pipe', TRUE);

```

See https://www.drupal.org/docs/drupal-apis/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones

---
Tags: theming, hooks
---


# Question
Title: How do I install the commerceguys libraries?
While installing Drupal Commerce 8.x-2.x-dev on Drupal 8.0.0-rc4, I'm greeted by the announcements.

> Commerce Price requires the commerceguys/intl library.
> Commerce Tax requires the commerceguys/tax library.
> Address requires the commerceguys/addressing library.

How do I that? It's probably so obvious that I'm overlooking it.

>

# Answer
Download composer\_manager into your modules directory.

From the Drupal root directory, initialize composer\_manager, and run it for the first time:

```
php modules/composer_manager/scripts/init.php

composer drupal-update

composer dump-autoload

```

This will download the required libraries into the root vendor/ directory.

Enable modules now.
> 4 votes

# Answer
I ran into an issue where even though I installed via `composer require commerceguys/addressing` it picked up the stable release instead of the release required by `drupal/address`, and the error message is confusing.

However once I confirmed that the drupal module required a dev release rather than the stable release I was able to install by changing the version in composer.json to `^1.0` instead of `^0.8`.

In development it is often easier to checkout modules via git into the modules directory rather than to use the complexity of composer projects or requiring via `--prefer-source` because composer will remove development/IDE directories that you may be using in order to hack or develop on those modules. Thus it is important to pay strict attention to those modules' individual composer.json files and provide the correct versions when running `composer require` in the drupal root directory.
> 2 votes

# Answer
We have documented this process on the Drupal Commerce docs website at http://docs.drupalcommerce.org/v2/index.html. These are the commands to run on an existing site.

```
drupal module:download composer_manager
php modules/contrib/composer_manager/scripts/init.php
composer drupal-update
composer dump-autoload

```
> 1 votes

# Answer
Add these lines to the composer.json file.

```
"require": {
        "composer/installers": "^1.2",
        "drupal/core-composer-scaffold": "^8.8",
        "drupal/core-project-message": "^8.8",
        "drupal/core-recommended": "^8.8",
        "drupal/core-vendor-hardening": "^8.8",
    **"commerceguys/intl": "dev-master",
        "commerceguys/addressing": "dev-master"**
    },

```

Then run `composer update`, clear the cache, and try again to install Address. This worked for me.
> 1 votes

# Answer
The link to the installation instructions listed earlier seems to have changed. Developer guide \> Installation and updates \> Installing says that the following command will download Drupal 8 and Commerce 2.x with all dependencies in the *mystore* folder.

```
composer create-project drupalcommerce/project-base mystore --stability dev

```
> 1 votes

---
Tags: theming
---


# Question
Title: How do I allow users to sort articles by tag with the select field?
I have a view page (*articles*), with a taxonomy term relationship for the *tags* vocabulary. I have no context filters, and the filter criteria are the following.

* Published
* Type: article
* Taxonomy term (exposed) (with relationship "term", "tid" ID, no multiple choice, operator "one of", but I've also tried "all of" with no use)

At first, the article list on page displays correctly, but when I select tag in select-field and press "apply", I get an error.

> InvalidArgumentException: A valid cache entry key is required. Use getAll() to get all table data. in Drupal\views\ViewsData-\>get() (line 140 of core\modules\views\src\ViewsData.php).

What did I do wrong?

# Answer
Four hours later I found what was the mistake. I shouldn't use any relationship at all. All I need is the filter criteria "Content: Tags (exposed)" with the default settings.
> 1 votes

---
Tags: views, taxonomy-terms, 9
---


# Question
Title: Is there any problem with installing composer globally?
I have a VPS and will be hosting a mixture of drupal 8 and drupal 9 sites. I need to install composer to manage the sites.

Is there any need to install composer in a project folder or can I just install globally?

# Answer
There is no problem with installing Composer globally, but there may be a problem with using `composer global require` to install individual Composer-managed projects globally.

You should not run in to this trouble just using Composer on the server to `composer install` your various Drupal 8 and Drupal 9 sites, but you should be aware of the potential for dependency conflicts, especially in local development environments.

To avoid this, use `consolidation/cgr` instead of `composer global require`:

```
$ composer global require consolidation/cgr

```

After globally requiring that one package, you can use `cgr` as a drop-in replacement for `composer global require` and it will prevent dependency conflicts with globally-installed packages. For example, to install Drush globally:

```
$ cgr drush/drush

```

Note that current best practices now say to install a site-local Drush by adding Drush as a dependency of your Composer-managed Drupal project; I just used this as an example of how to use `cgr`.

By the way, if you are still running Drupal 8 sites, please be aware that Drupal 8 reaches its end of life on November 1, 2021. Here are some tips on upgrading Drupal 8 to Drupal 9.
> 3 votes

---
Tags: composer
---


title: Varnish in multilingual site

text:
# Question
Title: Varnish in multilingual site
I have a multilingual site where I use in most of my custom modules (.module files) and in the mycustomtheme.theme file these lines of code : `\Drupal::languageManager()->getCurrentLanguage()->getId();`

`\Drupal::service('domain.negotiator')->getActiveId();` I want to install Varnish on my site, and I know that I can specify some URLs not to be cached like for instance I specified the path of a custom controller where `\Drupal::languageManager()->getCurrentLanguage()->getId();` is used so that the page related to this controller is not cached. However, I don't know what to do for all the .module files where I used this line of code. Does this function `->getCurrentLanguage()->getId();` have a specific path so that I can specify its path to be ignored by varnish ? PS: this is important because some features differ from one user to another depending on the website's language.

# Answer
For anonymous traffic not `getCurrentLanguage()->getId()` is the problem, it's the language detection method. Browser based is not recommended. For cache performance it's a better idea to redirect to the path based language detection method after you have determined the browser language, for example with the module Redirect. For this you need to configure a language prefix for all languages.
> 2 votes

---
Tags: 8
---


# Question
Title: Does the login-link users receive upon registration actually expire?
I'm trying to expand the duration for the expiration of the one-time-login for the initial registration process:

* the user clicks on "create new account"
* after filling name and email and sending the request, user gets a notification with one-time-link

I have changed the duration of 'password\_reset\_timeout' with

```
drush config:set user.settings password_reset_timeout 100

```

to 100 sec for testing purposes. But the link does not expire after the set time...

When I use the "Reset your password" option and receive the one-time login, the message on the page shows the expiration date, but this isn't shown on the login page with the registration link.

So, does the **registration** one-time-link ever expire?

# Answer
Nope, new users' one-time-link do not expire. Only "forgot passwords"-links do.

Also, see this discussion. It might come in future Drupal 9 releases. https://www.drupal.org/project/drupal/issues/3097238
> 4 votes

---
Tags: 8, users, security
---


title: Get the image URL

text:
# Question
Title: Get the image URL
I want to render an image as a background image via an inline style in twig. I created a field called bg\_image and attached it to the standard plain page.

After fiddling around for hours I was able to get the Image URL in node.html.twig

```
{{ file_url(node.field_bg_image.0.entity.uri.value) }}

```

but I could not get it to work inside field--field-bg\_image.html.twig

Can I get the node from there anyhow, so I can then get the image?

How can I get the image URL to use as inline style? I thought maybe I can pass a variable from field--field-bg\_image.html.twig to image.html.twig and then just render

```
{{ uri }}

```

instead of

```
<img{{ attributes.addClass(classes) }} />

```

but I could not get it to pass the variable there unless I use includes

```
{% include 'image.html.twig' with {'image': image, 'isFromField': isFromField} %}

```

(isFromField is true, when it comes from the field--field-bg\_image.html.twig) But that didn't work either. The Image was never rendered that way.

Would be very glad if you can help - my php knowledge is very basic. Thanks

# Answer
> 36 votes
The variable `node` is only preloaded in the node template (and the page template, if the url contains the node). Now if you want to access node fields in a field template you have to look in a different place:

*field.html.twig:*

```
{{ file_url(element['#object'].field_image.0.entity.uri.value) }}

```

`element['#object']` is the parent entity in a field template and you can access any field from this entity (in your case the node).

If you want to access raw values from the actual field, it's better to follow the logic of the field twig and access the value inside of the items loop directly from the field item object `#item`:

```
{% for item in items %}
  {{ file_url(item.content['#item'].entity.uri.value) }}
{% endfor %}

```

---

**Edit: Get the url of an image style**

Install the module Twig Tweak and you can use the uri to get the url of an image style:

```
{% for item in items %}
  {{ item.content['#item'].entity.uri.value | image_style('thumbnail') }}
{% endfor %}

```

# Answer
> 32 votes
Just to mention that if you want to do the same in one of the new custom blocks this works:

```
{{ file_url(content.field_image['#items'].entity.uri.value) }}

```

# Answer
> 3 votes
I use this code in my .theme file:

```
function THEMENAME_preprocess_node(&$variables) {

  if ($variables['node']->field_image->entity) {
      $variables['image_url'] = $url = entity_load('image_style', 'medium')->buildUrl($variables['node']->field_image->entity->getFileUri());
  }
}

```

It could be improved. I'm checking for the image field, and loading its url with an image style.

Then in my node--page.html.twig file I have this:

```
{% if image_url is not empty %}
    <div class="featured-thumb">
        <img src="{{ image_url }}"/>
    </div>
{% endif %}

<div>{{ content.body|without('field_image') }}</div>

```

Again, that could use some improvement. thanks

# Answer
> 1 votes
I'd do it another way. In your node preprocess function :

```
use Drupal\image\Entity\ImageStyle; // Don't forget this use.

function THEMENAME_preprocess_node__NODETYPE(&$variables){
    $node = $variables['node'];

    if(isset($node->get('field_image')->entity)){
        $image_style = 'large'; // Or whatever your image style's machine name is.
        $style = ImageStyle::load($style);
        $variables['image'] = $style->buildUrl($node->get('field_image')->entity->getFileUri()); // Generates file url.
    }
}

```

Then, in your template (node--NODETYPE.html.twig), just render the image that way :

```
{% if image %}
    <img src="{{ image }}" />
{% endif %}

```

Although, if you ever have to render a big amount of images, I'd advise you to load the styles in an array before you loop on each images. I'm saying that because I've ran into serious load time problems because I had to load over 300 images and for each image, I was loading the style individually instead of loading them all before, here's an example, same base as above :

```
use Drupal\image\Entity\ImageStyle; // Don't forget this use.

function THEMENAME_preprocess_node__NODETYPE(&$variables){
    $node = $variables['node'];

    if(isset(node->get('field_images')[0]->entity)){ // Notice how, this time, I check if the FIRST image is set (if it's true, then u'll allow the loop for at least 1 element)
        $images_styles = [
            'large' => ImageStyle::load('large'),
            'thumbnail' => ImageStyle::load('thumbnail')
        ];
        $count = 0;

        foreach($node->get('field_images') as $image){
            $variables['images'][$count]['large'] = $images_styles['large']->buildUrl($image->getFileUri());
            $variables['images'][$count]['thumbnail'] = $images_styles['thumbnail']->buildUrl($image->getFileUri());
            $count++;
        }
    }
}

```

Then again, in your template (node--NODETYPE.html.twig), just render the images that way :

```
{% if images %}
    <ul>
        {% for image in images %}
            <li>
                <img src="{{ image.large }}" /> // Large image url.
                <img src="{{ image.thumbnail }}" /> // Thumbnail image url.
            </li>
        {% endfor %}
    </ul>
{% endif %}

```

I haven't really tested it and I'm getting all this out of my head so it might contain errors, feel free to warn me so I'll correct this :-).

# Answer
> 0 votes
After spending two days I found some answer to my similar code. With including and excluding some fields.

```
{%
set classes = [
'block',
'block-' ~ configuration.provider|clean_class,
'block-' ~ plugin_id|clean_class,
'cover-image',
]
%}

{% set background_image = file_url(content.field_banner_image['#items'].entity.uri.value) %}

<div{{ attributes.addClass(classes) }} style="background-image:
url({{background_image}})">

<div class="block-inner">
{{ title_prefix }}
{% if label %}
<h2{{ title_attributes }}>{{ label }}</h2>
{% endif %}
{{ title_suffix }}
{% block content %}
{{ content.field_media_image }}
<div class="summary">
{{ content|without('field_banner_image') }}
</div>
{% endblock %}
</div>
</div>

```

fine name in theme block--bundle--banner-block.html.twig This code is for custom block with images.

Another Example for simple file. not Pesting whole code, but only essential.

```
<a href="{{file_url(node.field_attachment1.entity.uri.value)  }}" ><h3>
{{content.field_short_information}} </h3></a>

```

This code snippets for node node--all\_notice.html.twig. All things currently working in drupal 8.8.3

below code work in Drupal 9 for getting image url

```
{{file_url(node.field_auditreport.entity.field_obsimg.entity.uri.value)}}

```

# Answer
> 0 votes
For maintainability, I'd recommend using preprocess function for this. For Drupal 8, 9 & 10:

```
function template_preprocess_node(array &$variables) {
  foreach (Element::children($variables['elements']) as $key) {
    if ($variables['elements']['node']->field_image->entity) {
      $style = \Drupal::entityTypeManager()->getStorage('image_style')->load('medium');
      $variables['image'] = $style->buildUrl($variables['elements']['node']->field_image->entity->getFileUri());
    }
  }
}

```

Then, in Twig:

```
{{ image }} // prints https://mysite.com/sites/default/files/styles/medium/public/image.jpg

```

Source: https://stefvanlooveren.me/blog/get-url-image-drupal-9-10-image-style-twig

# Answer
> -2 votes
I've had some success using the Background Image Module when the use case allows for it. I use one of these code options when I need a customized DOM structure.

---
Tags: 8, files
---


# Question
Title: How to send email verification link with webform?
I am using a webform for anonymous users (logging in is not an option). Once a webform is submitted, I want to send out an email asking to click on a confirmation link. Only once this link is clicked, I want to take further actions (i.e. trigger an email handler or change the status of the webform).

How can I achieve this or something similar?

# Answer
Afaik this is not yet implemented in webform. Not sure, if it will at all. There is a module in dev that tries to solve the issue, but it requires some effort to make it work: Email Confirmer.

Another option is to build this with the Rules module. Here's something similar for inspiration: Send email notification when a new comment is posted
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: Where is "click sortable" set for a field?
I am trying to properly fix a bug in D8/9 core which removes the ability for link fields to be "click sortable" in a Views table.

I know I can do a views\_data\_alter hook to set the field as "click sortable" but I am guessing there is a schema or annotation change I can make to fix this? Anyone have any hints?

Thanks.

# Answer
I went ahead and used hook\_field\_views\_data\_alter and created this patch for core: https://www.drupal.org/project/drupal/issues/3239705.
> 3 votes

---
Tags: views, 9
---


# Question
Title: How can I get a list of content types with drush?
How can I get the existing content type list with drush? This will allow me to quickly produce a list.

I've tried with:

```
$ drush @d6 @sites genc --types

```

But I need the `devel_generates` module enabled for this.

> Command genc needs the following module(s) enabled to run: devel\_generate.

# Answer
> 15 votes
Try the following commands.

### Drupal 7 & 8

```
drush ev "print_r(array_keys(node_type_get_types()));"

```

### Drupal 5 & 6

```
drush ev "print_r(array_keys(node_get_types()));"

```

# Answer
> 13 votes
List of names:

`drush sqlq "SELECT name FROM node_type;"`

List of machine names:

`drush sqlq "SELECT type FROM node_type;"`

This works in D6 and D7.

The first line of the command's output will be `name` or `type`, respectively. Pipe `|tail -n +2` if you want to drop that first line.

# Answer
> 5 votes
If you know how to do it in Drupal, you just need to use `drush eval`:

Drupal 6:

```
drush eval '$types = node_get_types(); foreach($types as $type => $object) { print $type . "\n"; }'

```

Drupal 7:

```
drush eval '$types = node_type_get_types(); foreach($types as $type => $object) { print $type . "\n"; }'

```

See this list of drush commands for other useful examples using `eval`.

# Answer
> 5 votes
You can create a drush command named `content-type-list`. Create a module named `drush_content_types`, inside the `drush_content_types.drush.inc` file put this code:

```
<?php
/**
 * @file
 * Drush commands related to Content Types.
 */

/**
* Implements hook_drush_command().
*/
function drush_content_types_drush_command() {
  $items['content-type-list'] = array(
    'description' => dt("Show a list of available content types."),
    'aliases' => array('ctl'),
  );
  return $items;
}

/**
 * Callback for the content-type-list command.
 */
function drush_drush_content_types_content_type_list() {
  $content_types = array_keys(node_type_get_types());
  sort($content_types);

  drush_print(dt("Machine name"));
  drush_print(implode("\r\n", $content_types));
}

```

Install the module, run `drush cc drush` to clear the drush cache and use the command like this:

```
drush ctl

```

or

```
drush content-type-list

```

If you want add another alias to the command add elements to the aliases array like this:

```
'aliases' => array('ctl', 'all-content-types', 'act'),

```

And you can use this commands:

```
drush act
drush all-content-types
drush ctl
drush content-type-list

```

Always the output will be:

```
Machine name:
content 1
content 2
content...
content n

```

# Answer
> 4 votes
**Drupal 9**

```
drush ev "print_r(array_keys(\Drupal\node\Entity\NodeType::loadMultiple()));"

```

# Answer
> 0 votes
For a more rich, complete, report, you can use site\_audit, which will give you content types, fields, and a ton of extra information

https://www.drupal.org/project/site\_audit

Drutiny is as well a good tool, not necessarily for content types, but in order to get a ton of extra information from your site

https://drutiny.github.io/2.3.x/getting-started/

---
Tags: drush
---


title: Easy way for user to resubmit a webform

text:
# Question
Title: Easy way for user to resubmit a webform
My users are clicking on an emailed link from CiviCRM to complete a webform, which when completed and submitted adds contacts to CiviCRM. I'd like them to be able to have an easy way of submitting the webform again without having to go back to the email, find the link and start over. This is because they are submitting details of one household per webform, and may have (say) 6 household they want to submit. I'm thinking that after submission they simply go back to the start of the webform - the problem is that to do that I'd need the url they clicked on, which has a couple of contact parameters in it. I can't find that in the tokens that are available, unfortunately. (question moved to civicrm.stackexchange.com)

# Answer
(Answer will probably be fleshed out when it is moved to the civicrm channel)

If you are using a checksum from civimail, then you can 'daisy-chain' forms by enabling the checksum field and contact ID on form 1, and then use those as tokens in the path used after the submission so that info is passed through to form2 etc
> 0 votes

---
Tags: webforms, civicrm
---


# Question
Title: The commerce_product.field_produit_labels field needs to be updated
almost every time I delete a field in my product types I get this message popping up in my dashboard :

> ENTITY/FIELD DEFINITIONS Mismatched entity and/or field definitions The following changes were detected in the entity type and field definitions. Product The commerce\_product.field\_produit\_labels field needs to be updated.

It has not been possible to update entities with "Drush" for some time.

Why do I have these problems regularly ? This is only with the Commerce module.

How can I correct this? Without breaking my site.

```
ubuntu@ov-b2b650 ~/www-example-com $ drush entup

In UpdateDBCommands.php line 110:

  Drupal removed its automatic entity-updates API in 8.7. See https://www.drupal.org/node/3034742.

entity:updates [--cache-clear [CACHE-CLEAR]] [--no-cache-clear] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-d|--debug] [-y|--yes] [--no] [--remote-host REMOTE-HOST] [--remote-user REMOTE-USER] [-r|--root ROOT] [-l|--uri URI] [--simulate] [--pipe] [-D|--define DEFINE] [--druplicon] [--xh-link XH-LINK] [--notify] [--] <command>

```

# Answer
You can quick-fix it by adding module devel\_entity\_updates https://www.drupal.org/project/devel\_entity\_updates and run the command drush entup. Don't forget to export configurations after that.

Also, you can fix it by manually creating an update hook - follow https://www.drupal.org/node/3034742#comment-13097250
> 1 votes

# Answer
You need to enable or install the devel entity updates first before running `drush entup` command.

**Install Devel Entity Updates Module with composer** (Source: https://www.drupal.org/project/devel\_entity\_updates)

`composer require 'drupal/devel_entity_updates:^3.0'` (or `composer require drupal/devel_entity_updates`to automatically get the latest version)

**Enable Devel Entity Updates Module**

`drush en devel_entity_updates`

Hope this will work for you.
> 0 votes

---
Tags: 8, entities, commerce, drush, updating
---


# Question
Title: How to get searched item value in search form?
How do I get the value of searched item value, if I searched for "cat" in a search box then it also displays on a search page?

# Answer
You can catch your entity in the preprocess and put data into drupal\_static. After that you can display it where you want.
> 0 votes

# Answer
This way sometimes works, in a hook\_alter function:

```
if ($form_id == 'search_form'){
  // gives you the value
  $save_value = $form['basic']['keys']["#default_value"];
}

```

But this way seems to work even better:

```
\Drupal::request()->query->get('keys')

```

There should technically also be a way of making a custom module, add a custom submit handler to the search form, and getting the value in there, but I couldn't get it working that way.
> 0 votes

# Answer
Though I am seriously late to the party, you can also grab the query thusly if you use the Search API module. After you created a View associated to your search index, you can use:

```
/**
 * Implements hook_preprocess_views_view()
 * @param $variables
 */
function YOUR_THEME_NAME_preprocess_views_view(&$variables) {
  if ($variables['view']->id() == 'search') {
        $variables['search_keywords'] = \Drupal::request()->query->get('search_api_fulltext');
  }
}

```

In this case, my view is named "search" and the query key I am looking for (after the ?) is "search\_api\_fulltext" (id of my input search field).

$variables\['search\_keywords'\] will now contain the keywords after the "=", for instance from /search?search\_api\_fulltext=searched+term
> 0 votes

---
Tags: 7, search
---


title: Disable front-end access

text:
# Question
Title: Disable front-end access
I want to disable the front-end access of my headless Drupal site, that is just a REST API for a Vue site.

Except for the login page, there is no need to access any node, taxonomy or view directly as everything is delivered via REST.

How can I achieve this?

# Answer
Based on your responses in the comments, it sounds like you want anonymous users to be sent to the login page on any access and for authenticated users to be able to access the site as normal. You can achieve this with a custom module that checks for logged-in status and redirect to the login page, or via the Require Login Module which does essentially the same thing.
> 1 votes

# Answer
You can use the following module.

Anonymous login

Use-case examples

1) You want to restrict your entire site to authenticated users. Simply enter "\*" as the only path to redirect and all anonymous traffic will be redirected to the login page.

2) Your website sends out emails that contain links that only authenticated users can reach (edit your account, edit a node, view a private message, etc). If the user clicks the link from the email and they are not currently logged in they will reach an "Access denied" page; which is horrible for usability. With this module enabled and configured to act on node/\*/edit paths, if a user clicks a link to site.com/node/123/edit, they will be redirected to site.com/user/login?destination=node/123/edit, so they can log in, then be brought to the page originally requested.
> 1 votes

# Answer
I just created a new module called "Disable UI" to handle this for a headless Drupal site we maintain. It should work for Drupal 8.x and Drupal 9.x:

https://www.drupal.org/project/disable\_ui
> 1 votes

---
Tags: users
---


# Question
Title: How can an event subscriber have access to the entity type?
I'm using entity\_print for PDF generation on two node types. I'd like each to have its own orientation configuration (or just have one override the default). There is an event in entity\_print where configuration can be set at run-time, so I have a simple event subscriber, with a method to override the orientation, but I can't seem to get the last piece, which is the entity (bundle label) to switch on.

How can an event subscriber have access to the entity type?

# Answer
The event should have the entities its acting on. Have you tried the following?

```
$entities = $event->getEntities();

```

To get the bundle:

```
$bundle = $event->getEntities()[0]->bundle();

```
> 0 votes

---
Tags: 8, event-subscribers
---


# Question
Title: Display price in add to cart form BEFORE add to cart button
the logical flow of choosing attributes is seeing price adjustments based on the attributes chosen before the buy button ... how can i display the price in the form itself so it appears BEFORE the add to cart button?

here is an example of what i am talking about ... you have attributes, then you have price calculations based on attributes selected and very last thing is the buy button ... this is logical and i can't figure it out.

i did try using jquery to append the price to a div inside the form .. but that is a mess. all sorts of problems with ajax etc and not the correct approach anyway.

# Answer
I also believe the default UX (price above variations, or below add to cart), is a mess.

There's an issue about Moving price before/above add-to-cart button, where I posted a workaround :

```
/**
 * Implements hook_form_FORM_ID_alter.
 */
function my_theme_form_commerce_order_item_add_to_cart_form_alter(
  array &$form,
  FormStateInterface $form_state
) {
  $form_data = $form_state->getStorage();

  if (!empty($form_data['selected_variation'])) {
    $selectedVariation = ProductVariation::load(
      $form_data['selected_variation']
    );
    $footer_price = $selectedVariation->price->view();
  }
  else {
    $parameter = \Drupal::routeMatch()->getParameter('commerce_product');
    $product = \Drupal\commerce_product\Entity\Product::load(
      (int) $parameter->id()
    );

    $entity_manager = \Drupal::entityTypeManager();

    $product_variation = $entity_manager->getStorage(
      'commerce_product_variation'
    )->load((int) $product->getVariationIds()[0]);

    $footer_price = $product_variation->get('price')->view();
  }

  $form['footer']['price'] = $footer_price;
}

```

So far it works, even if I think there might be a slimmer solution. Credits to Alen Simonyan.
> 1 votes

# Answer
I spent weeks on trying to find a clean solution using the commerce-product.html.twig template but to no avail. The problem is the fact that the variation fields and add-to-cart button are packed together into one component (product.variations) in a way that is difficult to decompose. I cannot think of a way to insert the price in there somewhere. Someone should create an issue about this.

Here is a hacky CSS-workaround.

First, create some space above the add-to-cart button:

```
.commerce-order-item-add-to-cart-form .form-actions {
   margin-top: 4em;
}

```

Now place the price div into the created space:

```
article .field--type-commerce-price {
   position: absolute;
   bottom: 2.5em;
}

```

This also works when the price is updated.

Still looking for a cleaner solution.
> 0 votes

# Answer
@kojo thanks for your answer. I just had to change it so it would also read my custom PriceResolver. I added 'default' as displayOption for the view so it's now using my calculated formatter.

```
 /**
 * Implements hook_form_FORM_ID_alter.
 * Show price in add to cart form
 */
function template_form_commerce_order_item_add_to_cart_form_alter(array &$form, FormStateInterface $form_state) {
  $form_data = $form_state->getStorage();
  if (!empty($form_data['selected_variation'])) {
    $selectedVariation = ProductVariation::load($form_data['selected_variation']);
  }
  else {
    /** @var \Drupal\commerce_product\Entity\Product $product */
    $product = \Drupal::routeMatch()->getParameter('commerce_product');
    $selectedVariation = $product->getDefaultVariation();
  }
  $form['footer']['price'] = $selectedVariation->price->view('default');
}

```
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: Using a rest plugin or a service how can one tell the token module the response is not cachable
I have a rest plugin which returns an array and sends a mail. When commenting the Token::replace all works fine, the token replace function creates a BubbleableMetadata object (from what I understand of it) and than a exception is thrown:

```
LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early.

```

# Answer
See https://www.drupal.org/node/2513810.

Also, whenever you encounter an exception, put a breakpoint on the line of code that throws that exception. You'll always find more helpful information there. In this case, that's in `\Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber`.

---

Better yet, an issue with this same exact problem (when using a REST resource) on d.o, including the concrete answer with a solution: https://www.drupal.org/node/2568423

(But the above is still valid, it's the general answer.)
> 0 votes

# Answer
This is part which rendering happen on replace function

```
 // If a local $bubbleable_metadata object was created, apply the metadata
  // it collected to the renderer's currently active render context.
  if (!$bubbleable_metadata_is_passed_in && $this->renderer
    ->hasRenderContext()) {
    $build = [];
    $bubbleable_metadata
      ->applyTo($build);
    $this->renderer
      ->render($build);
  }

```

based on the documentation https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Utility%21Token.php/function/Token%3A%3Areplace/9.2.x you can make this condition false and prevent running bypassing a bubbleable\_metadata to it.

I would suggest `new BubbleableMetadata()`

```
$token->replace($meta_tag, ['node' => $entity],  ['clear' => TRUE], new BubbleableMetadata());

```
> 0 votes

---
Tags: tokens, 8
---


# Question
Title: EventSubscriber to add cache context for specific path
I am working with Mobile Detect module and from what I understand, we need to manually add the cache context `mobile_detect_is_mobile` in order to have the page cached differently based on the user device type. I was able to make it work by applying the cache context using a preprocess on my paragraph like so :

```
function hook_preprocess_paragraph(&$variables){
    $variables['#cache']['contexts'][] = 'mobile_detect_is_mobile';
}

```

Although, I don't like the idea of adding the context at the preprocess level and I was looking to have a more global solution by using an EventSubscriber that checks the path and apply the cache context for specific paths. It seems like the cache context is not taken in consideration. Here my EventSubscriber :

```
class MobileDetectSubscriber implements EventSubscriberInterface {

    /**
     * @var \Symfony\Component\HttpFoundation\Request
     */
    protected $request;

    /**
     * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
     */
    public function __construct(RequestStack $request_stack) {
    $this->request = $request_stack->getCurrentRequest();;
    }

    /**
     * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
     *   The event to process.
     */
    public function onRespond(FilterResponseEvent $event) {
        if (!$event
            ->isMasterRequest()) {
            return;
        }
        $response = $event
            ->getResponse();
        if (!$response instanceof CacheableResponseInterface) {
            return;
        }

        if($this->request->getRequestUri() == "/"){
            $mobile_detect = new CacheableMetadata();
            $mobile_detect->setCacheContexts(['mobile_detect_is_mobile']);
            $response->addCacheableDependency($mobile_detect);
        }
    }

    /**
     * @return array
     *   An array of event listener definitions.
     */
    public static function getSubscribedEvents() {
        // Priority 5, so that it runs before FinishResponseSubscriber, but after
        // event subscribers that add the associated cacheability metadata (which
        // have priority 10). This one is conditional, so must run after those.
        $events[KernelEvents::RESPONSE][] = ['onRespond', 5];
        return $events;
    }
}

```

What am I missing ?

# Answer
Adding the cache context to the response is not more global. It's quite the opposite. Only if you put the cache context in the same render element which depends on this context it can be merged into all caching levels affected. In this example the context of the paragraph will be merged with the parent node and then with the page. The paragraph and node could also be in a block or a view. All these elements need that cache context.

Adding the cache context in a preprocess hook is indeed the last resort in the process of rendering a template. There is extra code in Drupal checking the top of $variables of a preprocess hook and merging the cache metadata into the template.

However, the idea behind cache metadata is to add it directly to the build array when generating content in code, so that it can bubble up to all templates involved. This works then also when refactoring the code to a function used in different places. For example a Twig function:

```
$build = [];
// build content
$build['#cache']['contexts'][] = 'mobile_detect_is_mobile';
// either return the build array to be rendered in {{ }}
return $build;
// or if your Twig function doesn't return $build bubble up at least the metadata
// by rendering it inside of the Twig function
\Drupal::service('renderer')->render($build);

```
> 2 votes

---
Tags: caching, event-subscribers
---


# Question
Title: What is a good way to send out email notifications on creation of a new entity?
I was trying to see what is the best way to handle customized notifications around the Website Feedback module. The module creates a new entity of type WebsiteFeedback (a custom entity defined by the module) whenever a user submits feedback using the module

I see Entity Notifications module but that does not seem to have a Drupal 9 release.

Is there something ready for Drupal 9?

# Answer
If you want to code it yourself, here's a simple example for emailing a notification every time a **Comment** entity is posted (taken from an actual site with minor cleanup, but I might have broken something pulling out the site-specific code):

```
function mymodule_comment_insert(Comment $entity) {
  mymodule__mail_notify_admin('new_comment', $entity, '', 'insert');
}

function mymodule_mail_notify_admin($key, $entity, $title, $moderation_state) {
  $mailManager = \Drupal::service('plugin.manager.mail');
  $module = 'mymodule';
  $to_email = 'myemail@example.com';
  $path = $entity->toUrl('canonical', ['absolute' => TRUE])->toString();
  $params['message'] = $path;
  $params['title'] = $title;
  $params['moderation_state'] = $moderation_state;
  $langcode = \Drupal::currentUser()->getPreferredLangcode();

  $result = $mailManager->mail($module, $key, $to_email, $langcode, $params);
  if ($result['result'] !== TRUE) {
    $message = t('Error sending email notification to @email.', ['@email' => $to_email]);
    \Drupal::logger('mymodule')->error($message);
    return;
  }
  else {
    $message = t('Email notification sent to @email', ['@email' => $to_email]);
    \Drupal::logger('mymodule')->notice($message);
  }
}

/*
 * For reference:
 * http://valuebound.com/resources/blog/how-to-send-mail-programmatically-drupal-8
 */
function mymodule_mail($key, &$message, $params) {
  $message['from'] = \Drupal::config('system.site')->get('mail');

  switch ($key) {
    case 'new_comment':
      // https://www.drupal.org/project/simple_comment_email_notification
      $message['subject'] = t('New comment');
      $message['body'][] = t('You can check the page at :unapprovedCommentsUrl for unapproved comments and :publishedCommentsUrl for published comments.', [
        ':unapprovedCommentsUrl' => \Drupal::request()->getSchemeAndHttpHost() . '/admin/content/comment/approval',
        ':publishedCommentsUrl'  => \Drupal::request()->getSchemeAndHttpHost() . '/admin/content/comment',
      ]);
      break;

    default:
      $options = [
        'langcode' => $message['langcode'],
      ];
      // @todo Fix HTML escaping.
      // $message['body'][] = Html::escape($params['message']);.
      $message['body'][] = $params['message'];
      $message['subject'] = t('@title @ms on my site',
        [
          '@ms' => $params['moderation_state'],
          '@title' => $params['title'],
        ],
        $options);
      break;
  }
}

```
> 1 votes

---
Tags: emails, 9, notifications
---


# Question
Title: How to prevent proxy URLs in link field from being encoded?
Others appear to have similar issues to Drupal 8/9 encoding URLs in the link field though I see no solutions.

We're a library site and have many links for our patrons to external database websites that we link to with proxy URLs such as:

https://somewebsite.com/login?auth=password&url=https://link.gale.com/apps/doc/K1606004825/BIC?u=schools&sid=BIC&xid=2aefeae4

However, Drupal encodes the URL after the second https so it looks like:

https://somewebsite.com/login?auth=password&url=https%3A//link.gale.com/apps/doc/K1606004825/BIC%3Fu%3Dschools&sid=BIC&xid=2aefeae4

which returns an error.

Is there a way to turn off this function or disable URL encoding for the link field?

# Answer
> 0 votes
I work for Denver Public Library and we ran into the same issue when we tried to post Ebsco permalinks on a Drupal 8 site.

As a workaround we are able to pass the URLs through a URL shortener and post that shortened URL.

A colleague of mine also remembered that they used to have to change permalinks before posting back on D6. They demonstrated that if you change a link from

https://ezproxy.yourlibrary.org/login?url=https://search.ebscohost.com/login.aspx?direct=true&db=aph&AN=100123456&scope=site

to:

https://search.ebscohost.com.ezproxy.yourlibrary.org/login.aspx?direct=true&db=aph&AN=100123456&scope=site

the second link would work with a D8 and above URL field while the first would encounter the encoding issue.

I have shared this information with Ebsco and am creating a ticket for ProQuest. However, if nothing changes with the way they create their permalinks the URL shortener workaround has been effective for us.

# Answer
> 0 votes
In EBSCOadmin, there is a feature to create a proxy mask for Permalinks.

See the FAQ on EBSCO Connect site. https://connect.ebsco.com/s/article/How-do-I-add-a-Proxy-Server-in-EBSCOadmin-and-embed-it-in-my-EBSCOhost-URL?language=en\_US

The proxy mask should be like the following: https://{targetURLDomain}.ezproxy.yourlibrary.org/{targetURLRemainder}

The above proxy mask would construct a URL like the below, which would work from Drupal. https://search.ebscohost.com.ezproxy.yourlibrary.org/login.aspx?direct=true&db=aph&AN=100123456&scope=site

---
Tags: uri
---


# Question
Title: How to configure a custom POST api to accept a request with Content-Type as "application/x-www-form-urlencoded" in the header?
I created a controller in a custom module that accepts a `POST` request.
I have a setup such that I get a `POST` request from a third-party application server to this API. But the `POST` request has a `Content-Type: "application/x-www-form-urlencoded"` in the header.
And because of this I get the following error in the recent log messages:

> Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException: No route found that matches "Content-Type: application/x-www-form-urlencoded" in Drupal\Core\Routing\ContentTypeHeaderMatcher-\>filter() (line 49 of /var/www/html/web/core/lib/Drupal/Core/Routing/ContentTypeHeaderMatcher.php).\`\`\`

When I test the API using postman:

1. if I use the `Content-Type: "application/json"` in the header, the code inside the API is executed, and I get the correct response.
2. if I use the `Content-Type: "application/x-www-form-urlencoded"`, I get the same error.

I cannot configure the third party application server to change the `Content-Type`. So the only option for me is to configure the API to accept the `POST` request with the `Content-Type: "application/x-www-form-urlencoded"`. How can I do that?

Edited: My class extends the class ResourceBase. Route definition of the controller. Also I am using drupal 8.

```
 * @RestResource(
 *   id = "test_abc_callback",
 *   label = @Translation("Custom API for Test"),
 *   uri_paths = {
 *     "create" = "/api/v1/test_callback",
 *   }
 * )

```

# Answer
This is not a custom controller. For the original question you would need to define the method POST in a custom route. See https://www.drupal.org/docs/drupal-apis/routing-system/structure-of-routes

But you don't necessarily need a custom controller. You can add serializers to REST API for formats already defined in the Symfony request object:

Request::initializeFormats

```
protected static function initializeFormats()
{
    static::$formats = [
        'html' => ['text/html', 'application/xhtml+xml'],
        'txt' => ['text/plain'],
        'js' => ['application/javascript', 'application/x-javascript', 'text/javascript'],
        'css' => ['text/css'],
        'json' => ['application/json', 'application/x-json'],
        'jsonld' => ['application/ld+json'],
        'xml' => ['text/xml', 'application/xml', 'application/x-xml'],
        'rdf' => ['application/rdf+xml'],
        'atom' => ['application/atom+xml'],
        'rss' => ['application/rss+xml'],
        'form' => ['application/x-www-form-urlencoded'],
    ];
}

```

See https://www.drupal.org/docs/drupal-apis/serialization-api/adding-new-formats and How can I POST x-www-form-urlencoded data from REST API plugin?
> 0 votes

---
Tags: ajax, 9, page-controller
---


# Question
Title: How to enable a site to be in an iframe?
How can I enable a Drupal site to be in an iframe and place it in basic html page.

If I try this:

`<iframe src="drupal-site.com"></iframe>`

then it doesn't show any result.

Any suggestions?

# Answer
Since Drupal 7.50, core is now protected against clickjacking by default (X-Frame-Options: SAMEORIGIN).

So by default, your Drupal site can only be embedded into a site on the same domain.

To change those settings, assuming of course you understand the associated risks, follow the advice in the change record:

> 1. If you are using a module such as Security Kit that already writes the X-Frame-Options header on its own, that setting will be automatically respected (pending the patch at #2661644: Integrate with Drupal core clickjacking defense) and Drupal core will not overwrite it. The Security Kit module provides an administrative interface for setting this header, so it's a good choice if you need to override the default Drupal core behavior and aren't sure exactly how to do it.
> 2. Alternatively, set the 'x\_frame\_options' variable via any standard method, for example in settings.php:
>
> ```
> // Turn off the X-Frame-Options header entirely, to restore the previous
> // behavior of allowing the site to be embedded in a frame on another site.
> $conf['x_frame_options'] = '';
>
> ```
>
> or
>
> ```
> // Set the "DENY" option to prevent the site from ever being embedded in a
> // frame at all, even on this site itself.
> $conf['x_frame_options'] = 'DENY';
>
> ```
>
> See https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options for more information on the various options this header can take.
>
> *Removing the header (as shown in the first example code snippet above) should not be done lightly, or else your Drupal site could be embedded on other sites and then the user tricked into doing actions they don't want.*
> 3. If you want to remove the X-Frame-Options header in hook\_page\_alter() or theme preprocess functions that run later you can remove the header like this (requires PHP \>= 5.3):
>
> ```
> header_remove('X-Frame-Options');
>
> ```
> 19 votes

# Answer
When on Drupal 8, you have the https://www.drupal.org/project/allow\_iframed\_site module perfectly doing the job. The module has an easy setup page for limiting iframing by path.

> Drupal 8+ has a feature built into core that stops the site from being rendered within an iframe, there are good reasons for this - https://www.drupal.org/node/2514136 But sometimes you want your site in an iframe, so that's what this module does.
> 2 votes

# Answer
You just need to write:

`$conf['x_frame_options'] = '';`

Drupal site is enabled in iframe
> 0 votes

# Answer
It's also worth checking if your parent site is using https then the iframe link attribute also needs https.
> 0 votes

# Answer
For anyone still maintaining an Drupal 7 site, I found a solution after some trial and error:

```
drupal_add_http_header('X-Frame-Options', FALSE);

```

This solution is good if you want a particular page to be embedded in an iframe, rather than the whole site (setting at the config level)

The method in drupal 7 core that automatically adds this header looks to see if the header exists at all and adds a "SAMEORIGIN" value if it does not exist. You just need to make sure to put something there so it skips over and doesn't add this pesky header.
> 0 votes

---
Tags: security
---


title: Status messages with AJAX

text:
# Question
Title: Status messages with AJAX
I'm making an AJAX call in drupal 7 via the standard AJAX Framework. My problem is that when a status message is set by the AJAX callback, it is simply lost (or displayed at the next reload of the page). How can I display the status messages right after the AJAX callback has finished running, without reloading the page? Is there a module for that?

# Answer
You can render the status messages and send them as anohter AJAX command.

For example:

```
$commands = array();

// Add other commands

$commands[] = ajax_command_prepend('div#ajax-status-messages-wrapper', theme('status_messages'));

return array('#type' => 'ajax', '#commands' => $commands);

```

At least this is the way I solved this problem when I faced it.
> 15 votes

# Answer
For Drupal 8 it's

```
$response = new AjaxResponse();
$status_messages = array('#type' => 'status_messages');
$messages = \Drupal::service('renderer')->renderRoot($status_messages);
if (!empty($messages)) {
  $response->addCommand(new PrependCommand('.your_selector', $messages));
}

return $response;

```
> 10 votes

# Answer
For Drupal 8 form with AJAX, answer by Tim Bozeman worked, but messages were showed up with no styling. This is what worked for me:

```
$response = new AjaxResponse();
drupal_set_message($action);
$form['messages']['status'] = [
  '#type' => 'status_messages',
];
$response->addCommand(new InsertCommand(null, $form['messages']));

return $response;

```
> 4 votes

# Answer
for me

```
$commands[] = ajax_command_remove('div.messages');
$commands[] = ajax_command_after('#main-content', theme('status_messages'));

```

worked. where #main-content is standard, and maybe needs to be customized for your theme's acutal messages position. (maybe you have to change the second method to **ajax\_command\_append()** or another)
> 0 votes

# Answer
I had this originally:

```
\Drupal::messenger()->addMessage($this->t('Form Submitted Successfully'), 'status', TRUE);
$allMessages = \Drupal::messenger()->all();
$html = \Drupal::service('renderer')->renderRoot($allMessages);
$response->addCommand(new AfterCommand('div[data-drupal-messages-fallback]', $html));

```

But $html was always "". After reading answer from Tim, I added this:

```
$allMessages['#type'] = 'status_messages';

```

after retrieving all the messages.. and it worked. Odd that -\>all() wouldn't include that.
> 0 votes

# Answer
it's now much more easier :

```
$response = new AjaxResponse();
$response->addCommand(new MessageCommand('Example of status message.'));

```

Get all information on this article: https://www.drupal.org/node/3086403
> 0 votes

# Answer
If you're here because in Drupal 8 / 9 you're trying to clear validation error messages upon successful form submission, here's what worked for me (with thanks to rémy for the Drupal 7 inspiration):

```
// Remove any validation errors from previous submission.
$response = new AjaxResponse();
$selector = '.messages--error';
$response->addCommand(new RemoveCommand($selector));

return $response;

```
> 0 votes

---
Tags: ajax, status-messages
---


# Question
Title: How do I add a link to a table row in a custom module?
I am making a sortable table in a custom module. If I put the whole link as part of the row information, the URL does not come out right.

I tried the following code.

```
  array(
    'data'=>array(
      '#title' => $entry['name'],
      '#type' => 'link',
      '#url' => $entry['link_url'],
    )
  )

```

I also tried what suggested on https://www.drupal.org/node/745272, which describes how to do it for Drupal 7.

I also tried this code.

```
 $rows[] = array(
   array(
     'data' => array(
       'name' => new FormattableMarkup('<a href=":link">@name</a>', [':link' => $entry['link_url'], '@name' => $entry['name']])
     )
   )
 );

```

Neither displays anything.

How do I achieve this for Drupal 8?

# Answer
> 4 votes
This worked for me

```
use Drupal\Component\Render\FormattableMarkup;
  $rows[] = array(

      array('data' => new FormattableMarkup('<a href=":link">@name</a>',
        [':link' => $entry['link_url'],
        '@name' => $entry['name']])
      ),

```

# Answer
> 2 votes
according to the link docs you should try this Structure, you need to create the route on your custom module.

```
$rows[] = [
  'data' => [
    'label' => [
      'data' => [
        'link' => [
          '#type' => 'link',
          '#title' => 'link text',
          '#url' => Url::fromRoute('custom_module.route'),
        ],
      ],
    ],
  ],
];

```

# Answer
> 0 votes
Take a look at the core Url class. Include it in your custom class:

```
use Drupal\Core\Url;

```

And then use something like this for your table data link:

```
'#url' => Url::fromUri($entry['link_url']),

```

There are a number of options for fromUrl() you may want to look at, and depending on the nature of your link\_url values, there are other Url class methods that may be more appropriate.

# Answer
> -1 votes
This did the trick for me:

```
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Core\Render\Markup;

$url = Url::fromRoute('entity.node.edit_form', array('node' => NID));
$project_link = Link::fromTextAndUrl(t('Open Project'), $url);
$project_link = $project_link->toRenderable()->toString();

$header = [
  'title' => t('title'),
  'data' => Markup::create($project_link)
];

```

---
Tags: 8
---


# Question
Title: A theme in a custom distribution isn't found
For our Drupal sites we develop our own distribution. In the distribution are two themes (administration theme and custom base theme). The administration theme works, but the custom base theme cannot be found. When I try to install the theme with `drush theme:enable our_base_theme -y`, I get this error.

> In ThemeInstaller.php line 136: Unknown themes: our\_base\_theme.

In admin/appearance, under the custom theme, which depends on the base custom theme, I see:

> Requires: our\_base\_theme (missing)
>
> This theme requires the listed modules to operate correctly.

With `$themeHandler->getTheme('our_base_theme');` in Drupal Shell, I get:

> Drupal\Core\Extension\Exception\UnknownExtensionException with message 'The theme our\_base\_theme does not exist.'

The themes are located at:

* web/profiles/custom/our\_profile/themes
    + our\_admin\_theme
    + our\_base\_theme

When I move the theme to *web/themes/custom/our\_base\_theme*, the theme can be found and works correctly.

I have already tried:

* Clearing the cache

```
drush cr

```
* Reinstalling the Drupal files

```
rm composer.lock
composer install
# or composer update

```
* Setting file and folder permissions to avoid issues

```
chmod -R 777 web/profiles/custom/our_profile/themes

```
* Refreshing the theme data

```
$themeHandler = \Drupal::service('theme_handler');
$themeHandler->reset();
$themeHandler->rebuildThemeData();
$themeHandler->refreshInfo();

```
* Changing the path in

```
SELECT * FROM `key_value` WHERE `collection`='state' AND `name`='system.theme.files';

```

There is a similar issue, where the solution is to delete the `hook_install()` implementation, but we don't use that hook in our distribution.

I have found also a troubleshooting article, but none of the suggestions solved the issue.

# Answer
> 1 votes
This issue has been created during the migration of the old site (without the distribution) to the new site (with the distribution). Because of a lot of dependencies in the configurations, the migration has been divided in two stages. In the first stage (in old git repository) all new distribution modules and themes have been enabled, but without any configurations (the modules and themes in the old repository have only info files). In the second phase of the migration (in new git repository) have been the configurations imported.

The path to the installation profile in the old repository was: "web/profiles/our\_profile", in the new repository: "web/profiles/**custom**/our\_profile". After changing the path in the old repository to : "web/profiles/custom/our\_profile", the theme works and can be found also after the migration.

I do not understand, why the issue effected only one theme and none of the modules.

---
Tags: 9
---


title: Entity Reference to fields

text:
# Question
Title: Entity Reference to fields
I'm using the Entity Reference module to relate different unique, particular pieces of equipment (identified by unique serial numbers) to different orders. Equipment and orders are content types. On the Order content type, I have an entity reference field with an inline entity form widget (autocomplete) for the user to scan in the serial number and form the relationship.

The problem is, the serial numbers could be in Hexidecimal or Decimal format, and the users should be able to use both interchangeably. Thus, if a user is creating an order and scans in the decimal serial number, the system should be smart enough to associate that with the correct piece of equipment, even if that serial number was entered in hex.

Entity Reference seems to have a limitation here, in that all of the widgets I've found seem to only reference the "title" attribute of an entity. Is there a way to make this attribute support multiple values, or to have Entity Reference reference nodes using multiple uniquely-valued fields (or maybe a single field with multiple globally-unique values)?

# Answer
The way I would do it is add a hexadecimal number and normal number field to the entity, and use a views entity reference. Then you can attach both fields to the view, and when you enter either value it will locate the entity.

My organization does very similar for a library system we are developing in where the user can enter a book id, a book title, or a unique catalog number into a field and it will return a referenced entity if it locates one.
> 1 votes

# Answer
Ok, I've thought of a solution that somewhat inelegant, but it works

On the Equipment content type, a hex/dec signifier field is added--some sort of a select box (maybe a taxonomy selection box) where the user will select if the serial number in hex or dec.

When the form is submitted, a custom rule will check for the presence of the select box, convert the value in the "title" to the other numbering format, and then append that value to the original value in the title field, so that the title field will contain both formats of the number. After everything is said and done, the Equipment titles will all look like "1234567, 12D687".

Now, when the user creates an order and searches for existing serial numbers using the Inline Entity Form, as long as you have it set to "autocomplete", it will find the correct piece of equipment and associate it with the order.

Still, it would be nice if Entity Reference auto-complete would work with fields from those entities and not just their titles. And, I'm still in needs of some sort of module that will add a hex converter to Rules.

Let me know if anyone finds better solutions!
> 0 votes

---
Tags: entities
---


# Question
Title: How do I get the entity ID from a view row and pass it along to the item list template?
I have a view which returns rows of entities. Each entity has several multi-value fields.

The structure is kinda like this:

* Field 1:

+ Item A
    + Item B
    + Item C
    + ...
    + Item H
* Field 2:

+ Item A
    + Item B
    + Item C

Field 2 holds values that are related to Field 1 Item B. When displaying Field 1 in the view results I'd like to be able to display them like:

Field 1: Item A, Item B (Field 2 Item A, Field 2 Item B), Item C, Item D

Because its a multi value field Views is using the item\_list template. My plan was that I would adds some conditionals to this template so that if Field 1 Item B was to be shown, I would use Twig Tweak to add the values from Field 2 inline to it. The only problem is that to do that I need the row's entity ID. For the life of me, I can't figure out how to pass this information into the item\_list template. This template seems completely removed from the view and doesn't have a way to reference it.

I've been trying various functions in my theme file to get the result row NID and pass it along as a variable into the list\_item template, but have had nothing but failure. I've figured out how to get a custom variable into the item\_list template preprocess\_item\_list, but I can't figure out how to get the row NID into this function.

Any help would be appreciated.

# Answer
> 0 votes
Add the node id as a hidden field to the view, then inside the templates {% for item in items %} you should be able to reference it as item.content\['#node'\].0.nid|raw but you may need to kint item.content to find out the actual value.

---
Tags: 8, views, theming
---


# Question
Title: After webform submission restrict/greyout certain fields when user goes back in to edit
On my Drupal 7 instance I am letting anonymous users "edit own webform content" or "access own webform results." The thing is, I want one or two of the fields to become un-editable after the initial submission. Once they click through the link in their confirmation email to edit their submission, I want the email and company name fields to be greyed out but all other fields to be editable. What is my path of least resistance?

# Answer
> 0 votes
I solved this by attaching some javascript to my module...

```
$form['#attached']['js'][] = array(
  'data' => drupal_get_path('module', 'my_module') . '/my_javascript.js',
  'type' => 'file',
);

```

Then, within that attached javascript file, I used...

```
document.getElementById("edit-submitted-name-of-organisation").disabled = true;

```

The reason why I couldn't do it in the hook\_form\_alter is because it was somehow preventing those fields from being editable from the beginning, even prior to the initial submission.

# Answer
> 1 votes
From Programmatically modifying a webform with hook\_form\_alter():

```
function mymodule_form_alter( &$form, &$form_state,$form_id ){
  global $user;
  if (!$user->uid && $form_id == 'MY_WEBFORM_ID') {
    $form['submitted']['MY_FORM_COMPONENT']['#disabled'] = TRUE;
  }
}

```

---
Tags: hooks, webforms
---


# Question
Title: How to open a form in modal from controller while redirect
I can open a form in modal when click on a link (and there are lot of examples in the net as well).

What I like to do: When some one go to a url in browser or redirect to a url, it will open a dialog/modal form.

-I have defined a controller for a url -In the controller function I placed the code like this:

```
  $response = new AjaxResponse();
  $title = $this->t('Confirmation');
  $form = $this->formBuilder->getForm('Drupal\example\Form\MyModalForm', $entity);
  $response->addCommand(new OpenModalDialogCommand($title, $form, ['width' => '800']));

```

But its not opening the Modal Form, rather showing json code in a textarea. Surely dialog box library might be missing. So I added the library:

```
    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';

```

in the form, in the page preprocess, etc. But none is working.

It is showing json code like this (example)

```
[{"command":"openDialog","selector":"#drupal-modal","settings":null,"data":"Something to show","dialogOptions":{"width":"800","modal":true,"title":"Confirmation"}}]

```

Can anyone help me, on how to open the dialog/modal when visiting the url?

# Answer
> 0 votes
The approach suggested by @4k4 might be correct, I did not test How do I display a modal dialog on page load, with working title and dialog options, using OpenModalDialogCommand?

What I did: Displayed a link and using JavaScript on load trigger the link, which eventually open the modal dialog.

This is not a good solution for me.

---
Tags: forms, ajax, redirection, modal-dialogs
---


# Question
Title: How do I store a custom field type settings for checkboxes?
I have already created my field\_type,field\_widget, field\_formatter using Drupal console and also a set of checkboxes options to appear in field settings, I get this all working but when I select few options and save the settings it isn't storing those values , so when I go back again to field\_settings I see the previously checked options are empty.

```
 public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
$elements = [];

$elements['cars'] = array(
  '#type' => 'checkboxes',
  '#title' => t('Types of cars?'),
  '#options' => array('ferari' => t('Ferari'), 'prius' => t('Prius'), 'jaguar' => t('Jaguar'), 'lamborghini' => t('Lamborghini')),
  '#default_value' => $this->getSetting('cars'),
);
return $elements;}

```

This is a sample piece of code of mine, I need a way of storing the values that I check on the options.

# Answer
You need to implement `defaultFieldSettings()` method in your class:

```
public static function defaultFieldSettings() {
    return [
        'cars' => [],
      ] + parent::defaultFieldSettings();
  }

```
> 0 votes

---
Tags: entities, 8
---


# Question
Title: What's the best way to migrate from manual upgrades to composer updates?
I have an 8.9.19 installation that I would like to move over to use composer.

What's the best way to migrate the installation to use composer upgrades? Manual installations are becoming a real pain.

# Answer
> 2 votes
The most common way to 'flip' a project from not having Composer managed dependencies to being managed by Composer is to use the Composerize project: https://github.com/grasmash/composerize-drupal

# Answer
> 1 votes
I wouldn't say there is a most common way. Drupal is by default now composer ready since it introduced two project templates of its own. The answer depends on the specific requirements. If you want to switch between different composer templates it's also no problem to start a new composer project, require the packages of the installed modules and then move database and files directory from the old to the new installation.

See https://www.drupal.org/docs/develop/using-composer/starting-a-site-using-drupal-composer-project-templates

---
Tags: 8, composer
---


# Question
Title: List all the nodes with the same menu parent ID
I have the following menu in my system.

>

The parent *menu-link* connects to a node whose ID is 58. All the sub menu-links have a parent ID equal to 58.

I need to find the main and the sub-menus using 58, but I have been unsuccessful at locating the a table that contains that information.

How can I list the nodes that share a particular menu ID?

# Answer
The `menu_link_content` entity definition contains information related to your question; namely, the database table that contain the parent-child relation would be `menu_link_content_data`.

Below is a code sample that would deliver an array of node ids given a parent node, provided that there is a menu link attached to the node. This code uses Drupal's APIs instead of SQL queries.

```
<?php

// Get the root based on a given node, e.g. node 58.
$menu_link_root_entities = \Drupal::entityTypeManager()
  ->getStorage('menu_link_content')
  ->loadByProperties([
      'link'  => [
        'uri' => 'entity:node/58'
      ],
    ],
);
$menu_link_root = reset($menu_link_root_entities);

// Need to call this in order to instantiate the tree_storage service.
$menu_tree = \Drupal::menuTree();
// Get menu link content entities based on their parent property.
$menu_links = \Drupal::service('menu.tree_storage')->loadByProperties([
    // Need a filter value like menu_link_content:8031d182-7a0b-4798-839a-6c66bdd1f27b
    'parent' => 'menu_link_content:' . $menu_link_root->uuid(),
]) ?: [];

$node_ids = array_map(function($v){
    return $v['route_parameters']['node'];
}, $menu_links);

```

Hope this helps, good luck!
> 1 votes

---
Tags: database, navigation, 9
---


title: How is the theme folder to use decided?

text:
# Question
Title: How is the theme folder to use decided?
Under /sites/all/themes there are two folders called atlas and atlas.backup. Drupal 7 is pointing to atlas.backup and I don't understand how Drupal knows which theme folder to use.

I want Drupal to use the *atlas* folder, rather than the *atlas.backup* one.

# Answer
> 3 votes
You should never, ever keep a duplicate/backup copy of any theme or module anywhere under /sites/all. You can't control which copy Drupal will find first, and you may actually be using parts of both.

You must move the backup copy outside of Drupal root. You will need to clear your caches and perhaps rebuild your registry after you do that.

---
Tags: 7
---


# Question
Title: How get the info of a element in webform email twig?
I'm on D9, theming a webform email.

I'm currently overriding the twig file, instead of using the configuration of the body in the email hanlder, because there are various conditional logic I've to check - e.g. if interface language is *en* print *element a* otherwise *element b*.

To create the required markup, I need to get the info of the elements: for example, for select elements, I need the *label* and the text of the option selected, not the raw value.

However, I can't find them using the webform\_submission, as it seems to contain only the raw data put by the user.

For now, I've find this way to get the info I need, but I'd like to know if there's a more direct\better way to get them:

`webform-email-message-html--webform-id.html.twig`:

```
{% set submission_data =webform_submission.getData %}
{% set webform = handler.getWebform %}
{% set my_element_test = webform.getElementDecoded('element_id') %}
{% set option_label_test = my_element['#options']['options_id'] %}

{# todo print the markup for all elements #}

```

# Answer
For anyone needing this, doing this in the twig works:

```

{% set webform = webform_submission.getWebform %}
{% set webform_element = webform.getElement(key) %}
{% set submission_data =webform_submission.getData %}

//value = value of the specific element inside submission_data
{% if webform_element['#options'] is defined %}
  {{ webform_element['#options'][value] }}
{% else %}
  {{ value }}
{% endif %}

```

Doing a bit of code-diving, I've seen that `WebformOptionsHelper::getOptionText()` \- called at some point by the code ran by Webform tokens' function - does a bit more complex logic to get the values, but at least for my case the above is sufficient.
> 0 votes

---
Tags: theming, webforms, 9
---


title: admin/reports/updates page not found

text:
# Question
Title: admin/reports/updates page not found
On a Drupal 8 project, the *admin/reports/updates* is not accessible. It just returns a 404 error without any issue.

# Answer
> 1 votes
The Update Manager module is a Drupal core module, but it's not installed from the Standard profile, which is the default installation profile used from Drupal.
Before installing the *Update Manager* module, none of its routes is available. You won't get any issue, except a 404 error when you try to access them.

---
Tags: 8
---