# Question
Title: Is a php filter available for Drupal 10.1.2?
Its been a few years since I've used Drupal (pretty much missing version 9), but I'm coming back to it with 10.1.2. I'm hoping to get a PHP filter installed for content, as I historically like to use PHP to include dynamic contents from non-Drupal sources.

Unfortunately, chasing down how to do this has been leading me in circles most of the morning, from the original filter in the 6/7 timeframe to apparently an optional core model in the 8/9 timeframe, but I've yet to find something for version 10 specifically, and Google searches using the version number happily pulls up earlier documentation.

Can someone provide a pointer to this functionality, if it exists, for 10.1.2?

# Answer
> 1 votes
No. At the time I write this the PHP module is not yet ported to Drupal 10.

# Answer
> 1 votes
Running PHP code via the PHP input filter has been considered a source of security issues; that is why the PHP input filter has been removed from Drupal core.
It has been moved to a contributed module, in the PHP project, but it has been created to help people migrate away from the PHP input filter. That is why the *PHP* project is not covered by security advisory policy, and the existing releases have been marked insecure.
It would not probably get a Drupal 10 release too.

Instead of using the PHP input filter, you need to create a module that implement the necessary hooks, services, controllers, or forms. A module can do everything the code handled by the PHP input filter can do, and much more.

# Answer
> 0 votes
The Drupal 9 version appears to install fine also on Drupal 10, on what I have tested, does not need any special porting. However I haven't tested it thoroughly but works fine in Views and Blocks at least. Caching etc likely does not work but nevertheless running it on a couple of sites. But as mentioned earlier in the previous replies, this is not recommended so do it only on your own risk and only if you are sure of what you are doing.

The way to get this running on drupal 10 is to edit the configuration php.info.yml to allow installation on Drupal 10, aka "core\_version\_requirement: ^8 || ^9 || ^10".

---
Tags: installation, 10
---


# Question
Title: Is the DRUPAL_DATABASE_HOST value stored somewhere in the database?
I want to see what the value is for the database host, the value that you enter when installing for the first time.

Is there a way to see and edit this value after installation? Is it stored in a table somewhere?

This is for Drupal 9

# Answer
> 2 votes
There is nothing named `DRUPAL_DATABASE_HOST` in the code or the database.

The database connection details, which include the host, are written to the settings.php file during installation, and can be found in there.

If you're debugging a connection to an unexpected database, make sure you check all the files that are included from settings.php, as they can contain overrides of the original `$databases` array.

---
Tags: database, 9
---


# Question
Title: Create input name from array like #parent
I'm just wondering if there is a Drupal way / helper function to build input\[name\] string from array.

So I have an array '#parents' = \["info","variation-555-1","example","example"\];

and I want the string to go in the input \[name=`info[variation-555-1][example][example]`\]

# Answer
> 0 votes
I found the same code in many places by searching `implode(']['` which seems to be way drupal does it, so the answer is `no`, there is no helper function, but it's only a few lines.

```
$selector = $root = array_shift($parents);
if ($parents) {
    $selector = $root . '[' . implode('][', $parents) . ']';
}

```

---
Tags: forms
---


# Question
Title: Multiple URL aliases on the same node/product
Create an alias for a node/product.

/admin/config/search/path/add

Create another alias pointing to the same node; /node/123 for example.

The first alias created is now 301'd to the last one defined.

How do we work around this? The use case is a product catalogue where the same product can be reached from different taxonomy terms. The URL is needed to maintain the breadcrumb trail.

Is it possible to achieve the approach with the current version of Drupal (10.2.3)?

# Answer
I ended up abandoning the idea of having multiple URL's for the same Product Node. Instead - I construct a URL parameter value on the parent taxonomy page (using views and URL rewriting) - such that when the user clicks onto the PDP - they have a context from which we can then derive the breadcrumb.
> 0 votes

---
Tags: commerce, path-aliases, 10
---


# Question
Title: Custom module for adding CSS file in admin section
How do I include `admin.css` in my theme so that it's loaded in the admin section (and preferably only the admin section)?

Right now when I add admin.css via the `x.libraries.yml` file, it's only loaded on the front-end.

**Update:**

So... based on your comments/answers I've created a module `admin-css`. But nothing happens. The file isn't loaded. What am I doing wrong?

Inside `admin_css.info.yml` :

```
name: Admin CSS
description: Alters the Admin CSS for better usability.
package: Custom

type: module
core: 8.x

```

Inside `admin_css.libraries.yml` :

```
admin-css:
  version: 1.x
  css:
    theme:
      css/admin.css: {}

```

Inside `admin_css.module` :

```
<?php

function admin_css_attachments(array &$attachments) {
    $is_admin = \Drupal::service('router.admin_context')->isAdminRoute();
    if ($is_admin) {
      $attachments['#attached']['library'][] = 'admin_css/admin-css';
      return;
    }

}

```

# Answer
> 3 votes
Unless you use the same theme for front and backend, that's not the right approach.

If something transcends the theme layer, e.g. you have functionality that you need to apply to two separate themes, it belongs in a module.

See Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module for instructions to actually accomplish that, specifically the section on *Attaching a library to all (or a subset of) pages* which contains a contrived code example:

```
function contextual_page_attachments(array &$attachments) {
  if (!\Drupal::currentUser()->hasPermission('access contextual links')) {
    return;
  }

  $attachments['#attached']['library'][] = 'contextual/drupal.contextual-links';
}

```

# Answer
> 3 votes
The hook is called "hook\_page\_attachments" so you have to rename your function from

```
function admin_css_attachments(array &$attachments) {

```

to

```
function admin_css_page_attachments(array &$attachments) {

```

# Answer
> 0 votes
You can also use the Asset Injector module to add css to your admin theme: https://www.drupal.org/project/asset\_injector

---
Tags: theming, 8
---


# Question
Title: List (distinct) users in order of their most recently published node
I'm trying to list 8 users (name and profile image) starting with the one who created the newest node and follow with the rest of users in (descending) order of their last created node.

I got to achieve it\* by:

1. adding fields and filters
2. adding a Relationship (advanced) with Content authored
3. adding Sort criteria as Content: date (descendant)

It 'works' but I get **duplicated users**. If a user created the 3 newest nodes, then it appears in positions #1, #2 and #3. I can't get it to get only distinct (unique) users in the list. Aggregation did not work.

SQL query (where I get users in the right order but with repeated ones) added:

```
SELECT DISTINCT "users_field_data"."created" AS "users_field_data_created", "users_field_data"."uid" AS "uid", "node_field_data_users_field_data"."nid" AS "node_field_data_users_field_data_nid", DATE_FORMAT((DATE_ADD('19700101', INTERVAL node_field_data_users_field_data.created SECOND) + INTERVAL 3600 SECOND), '%Y%m%d%H') AS "node_field_data_users_field_data_created_hour"
FROM
{users_field_data} "users_field_data"
INNER JOIN {node_field_data} "node_field_data_users_field_data" ON users_field_data.uid = node_field_data_users_field_data.uid
LEFT JOIN {user__roles} "user__roles_value_0" ON users_field_data.uid = user__roles_value_0.entity_id AND user__roles_value_0.roles_target_id = 'content_editor'
WHERE ("users_field_data"."status" = '1') AND ("user__roles_value_0"."roles_target_id" = 'content_editor')
ORDER BY "node_field_data_users_field_data_created_hour" DESC, "users_field_data_created" DESC
LIMIT 10 OFFSET 0

```

Any clues? Ty

# Answer
SOLVED. Taking a different approach.

1. Adding fields and filters (as above)
2. I've set the Relationship to Representative Node (instead of Content Authored)
3. Within that relationship, Order Criteria was set to (Content) Date - descendant
4. (Main) Order Criteria was set to (Content) Date (node representative) - descendant

and voilà. Solved! The 'Representative Node' did the bit to get a distinct / unique / only one single user even if they had (and they have) several nodes published.

This way we have a list of users ordered by the date of their last published node starting from the most recent ones.

Ty @Jaypan for your interest and suggestions. They helped.
> 0 votes

---
Tags: views, users
---


title: Is there an API to read file content?

text:
# Question
Title: Is there an API to read file content?
Most references seem to read files using PHP functions like `file_get_contents()`, `fgets()`, `fread()`, or `readfile()`.

Is there is any Drupal API that allows to read uploaded files independent of underlying storage?

We are using AWS S3 as our file field storage. Our ec2 instance is in a private subnet with an interface to S3 services. Say the URI is s3://bucketname/object.csv. I need a Drupal API that does an s3 getObject() SDK call under the hood that way I don't get blocked on network level instead request goes through the S3 network interface.

# Answer
Drupal implements access to managed files through stream wrappers. So you can access files using native PHP functions as follows.

```
file_get_contents('public://some/public/file.txt');
file_get_contents('private://some/private/file.txt');
file_get_contents('temporary://some/temporary/file.txt');

```
> 1 votes

---
Tags: files, 10
---


# Question
Title: Get image url with https instead of http
When I use file\_create\_url it return url with http instead of https.

Code Snippet:

```
$desimg = file_create_url($node->field_image->entity->getFileUri());

```

Due to which i m getting warning like below

Mixed Content: The page at 'https://www.example.com/' was loaded over HTTPS, but requested an insecure image 'http://www.example.com/sites/default/files/test/test\_M\_01.jpg'. This content should also be served over HTTPS.

I'm missing something?

# Answer
> 0 votes
It could be an issue of reverse proxy, read the below article this may solve your problem

https://www.drupal.org/project/metatag/issues/2842049

---
Tags: 8, media, uri
---


# Question
Title: How to run Drupal console command from code?
I have found a lot of documentation on how to run Drush commands from code, but I'm specifically looking on how to run a Drupal Console command from code.

I have some experience in Symfony and I know how to run a Symfony command from code. Since a Drupal console command extends on Symfony command, I thought this should be rather easy. Simply following this tutorial doesn't amount to anything though.

I am trying to run a command in a `hook_cron()` implementation in a custom module.

# Answer
Try using the PHP functions exec() or shell\_exec().
> 3 votes

# Answer
Run shell commands via the `Process` class available in the Symfony framework.

From the Symfony docs:

```
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;

$process = new Process('ls -lsa');
$process->run();

// executes after the command finishes
if (!$process->isSuccessful()) {
    throw new ProcessFailedException($process);
}

echo $process->getOutput();

```

> The component takes care of the subtle differences between the different platforms when executing the command.

Replace the `ls -lsa` command in the `Process()` constructor with your Drupal console command.
> 8 votes

# Answer
In D10 at least you can now run e.g.:

```
  $modules = ['redis'];
  \Drupal::service('module_installer')->install($modules, TRUE);

```

So many things you would want to do with Drush now can be called directly through Drupal services.
> 0 votes

---
Tags: 8, console
---


# Question
Title: submitForm not being called when put inside a Custom Block
I have been trying to find a fix for this but I haven't been able to. I have tried to put a form inside a custom block to render the form as a component. When the form is submitted it renders the component again but it doesn't invoke the submitForm function. Please review the code and let me know if you guys understand what the problem is.

**NewsletterForm.php**

```
<?php
/**
 * @file
 * Contains \Drupal\newsletter_block\Form\WorkForm.
 */

namespace Drupal\newsletter_block\Form;

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

class newsletterForm extends FormBase {
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'newsletter_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['newsletter_email_id'] = array(
      '#type' => 'email',
      '#title' => t('E-MAIL'),
      '#required' => TRUE,
    );

    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('SUBSCRIBE'),
    );

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {

   /**
   * {@inheritdoc}
   */

    $obj = array(
        'newsletter_email_id' => $form_state->getValue('newsletter_email_id'),
    );

    $url = 'http://demo7220892.mockable.io/newsletterblock';

    $options = array(
        http => array(
            'header' => "Content-type: application/www-form-urlencoded",
            'method' => 'POST',
            'content' => http_build_query($obj),
        )
        );
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    if ($result === FALSE) {
        drupal_set_message(t('Error in sending data to the server. Please try again later!'), 'error');
    }
    else {
        drupal_set_message(t('Thank you for subscribing to our newsletter. We will keep you updated on our latest developments.'));
    }

    var_dump($result);
  }
}

```

**NewsletterBlock.php**

```
<?php
/**
 * @file
 * Contains \Drupal\newsletter_block\Plugin\Block\NewsletterBlock.
 */

namespace Drupal\newsletter_block\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides a 'NewsletterBlock' for the Footer.
 *
 * @Block(
 *   id = "newsletter_block",
 *   admin_label = @Translation("Newsletter Block"),
 * )
 *
 */

 class NewsletterBlock extends BlockBase {

   /**
   * {@inheritdoc}
   */

  public function build() {

    $form = \Drupal::formBuilder()->getForm('Drupal\newsletter_block\Form\NewsletterForm');

    return $form;
  }

}

```

**newsletter-block.html.twig**

```
<div class="newsletterBlock" id="newsletter_block">
    <h4 class="newsletterTitle fw-normal">Newsletter</h4>
    <form>
        <div class="form-group">
            <input class="newsletterEmail fw-normal" name="newsletter_email_id" id="newsletterEmailAddress" aria-describedby="emailHelp" placeholder="E-MAIL"><input type="submit" name="subscribe_button" id="subscribeButton" value="SUBSCRIBE"/>
        </div>
    </form>
</div>

{{ attach_library("newsletter_block/newsletter-block") }}

{{ form.form_build_id }}
{# required #}
{{ form.form_id }}
{# required #}
{{ form.form_token }}
{# required #}

```

**newsletter\_block.module**

```
<?php

/**
 * Implements hook_theme().
 */
function newsletter_block_theme($existing, $type, $theme, $path) {
  return [
    'newsletter_block' => [
      'template' => 'newsletter-block',
      'render element' => 'form',
      ],
    ];
}

function newsletter_block_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id == 'newsletter_form') {
    $form['#theme'] = 'newsletter_block';
  }
}

```

The form is being rendered properly but clicking the SUBSCRIBE button does not invoke the submitForm function. I know this because I tried using breakpoints through XDebug. Please help me out with this.

Thank you in advance!

# Answer
You don't need a form alter hook, you can define the form template

```
$form['#theme'] = 'newsletter_block';

```

in buildForm() of the form class.

## Getting the form submitted

The form template needs to render the form elements of the form build provided in the variable `form` and at the end you can render the rest of `form` so you don't need to specify all the required internal stuff:

*newsletter-block.html.twig*

```
{{ form.newsletter_email_id }}
{{ form.submit }}

{{ form|without('newsletter_email_id', 'submit') }}

```

## Styling form elements

When form elements need specific attributes add them already in buildForm():

```
$form['newsletter_email_id'] = [
  '#type' => 'email',
  '#title' => t('E-MAIL'),
  '#required' => TRUE,
  '#attributes' => [
    'class' => [
      'newsletterEmail',
      'fw-normal',
    ],
    'aria-describedby' => 'emailHelp',
  ],
];

```
> 1 votes

# Answer
Figured out with the $form\['actions'\] set as:

```
$form['actions']['#type'] = 'actions';
  $form['actions']['submit'] = [
     #type' => 'submit',
    '#value' => $this->t('Save'),
    '#button_type' => 'primary',
  ];

```

Find documentation and full example at https://www.drupal.org/docs/drupal-apis/form-api/introduction-to-form-api
> 0 votes

---
Tags: forms, blocks
---


# Question
Title: How to add a "no index" tag on every page
I need help in adding a "no index" tag on several pages. Please help me with this.

# Answer
> 1 votes
This is a primary use-case of the Metatag module, and it has many other useful features.

---
Tags: 9
---


# Question
Title: How do I override a core constraint on an entity?
I want to replace one of core's constraints, `UserMailUnique`, with a custom validator. How can I do that?

# Answer
> 2 votes
You can use hook\_validation\_constraint\_alter().

Use the `id` in the annotation of the Constraint you are trying to override:

```
function MYMODULE_validation_constraint_alter(array &$definitions) {
  $definitions['UserMailUnique']['class'] = '\\Drupal\\MYMODULE\\Plugin\\Validation\\Constraints\\MyClass';
}

```

---
Tags: hooks
---


# Question
Title: How can I change datetime field to date field?
I have a Drupal site successfully migrated from Drupal 6 to Drupal 10. Some date content type fields were changed during migration from date format to datetime format by mistake. Drupal's admin \> manage fields doesn't allow me to change the field format, because there is node data stored in the field. Is there any way to convert them back to date forma without losing the stored data?

# Answer
One way to change a field format is to backup content of database tables `node__field_[your_field_name]` and `node_revision__field_[your_field_name]` and flush them. This step will allow admin user(s) to change the field format, or to remove the field completely and create it again with the same system name. Then you can import the tables back to the database.
> 0 votes

---
Tags: migrations, datetime
---


title: How do I hide the wizard page title?

text:
# Question
Title: How do I hide the wizard page title?
Webform Version: 6.2.2

I need to hide the wizard page title, but I can not, how it can be done?

I have:

```
identify_01:
  '#type': wizard_page
  '#title': 'Recognise 01'
  '#open': true

```

So I need to hide the "Recognise 01"

I have tried unsuccessfully some combinations like

```
'#title': hidden
'#wizard_page_title': hidden
'#title': hide
'#wizard_page_title': hide

```

and some others

# Answer
> 0 votes
Since you're already editing the *YAML* file, why not try `'#title': ''`

This should work

# Answer
> 0 votes
Webform wizard page uses the `webform-progress-tracker.html.twig template`. I'd recommend you to copy this file in your theme so that you can alter it in a way that fits your needs.

For instance, you could choose to remove any use of `{{ page.title }}` which is the variable containing the wizard page title.

# Answer
> 0 votes
Thanks @misterdidi, you gave a good clue. @NKP, if I do that I would lose a reference, my webform is about a 1000 lines in YAML...

I have inspected the css elements, then I went to the webform "settings \> CSS/JS" and over there I have added the following CSS code:

```
li.progress-step:nth-child(n) > div:nth-child(n) > div:nth-child(n) {
       display: none;
}

```

---
Tags: webforms
---


# Question
Title: How do I re-run updates (change module schema version)?
I'm working on a module, and I changed a couple field types in the schema. I didn't take a backup before testing it and messed up the DB (it's just a dev site). Anyway, I reinstalled everything, and the schema version is set to that of the highest update. However, I actually do need to run the update; a View I have wouldn't install if I had the updated schema in the module code, so I figured this would be a good way to test that update.

How do I reset the schema version of my module to a particular version? In Drupal 7, I would have done this:

`drush sqlq "UPDATE system SET schema_version=8102 WHERE name='flllpdf' AND type='module'"`

# Answer
While accessing state directly works, you can also just use the API: drupal\_set\_installed\_schema\_version(), which has existed since 4.7, as visible on the linked documentation page. This function is deprecated in Drupal 9.3.0 and removed in 10.0.0, where you should use \Drupal\Core\Update\UpdateHookRegistry::setInstalledVersion() instead.

To set it from drush:

```
drush ev "drupal_set_installed_schema_version('fillpdf', 8012)"

```

Note: In Drupal 7 you need to add extra `include 'includes/install.inc';`.

or (Drupal \>= 9.3):

```
drush ev "\Drupal::service('update.update_hook_registry')->setInstalledVersion('fillpdf', 8012);"

```
> 88 votes

# Answer
Drupal 8 now uses the `keyvalue` service to store information about the schema version. This is the same API the State API itself uses.

Value information is serialized when stored in the database, so using a direct SQL query is sub-optimal. Instead, use `drush php-eval` (or a script that bootstraps Drupal, if you don't have Drush) to execute the following:

```
<?php
  \Drupal::keyValue('system.schema')->set('fillpdf', (int) 8102);
?>

```

Change `fillpdf` and `8102` to your module name and desired schema version, respectively.

The Drush form of this command is:

`drush ev "\Drupal::keyValue('system.schema')->set('fillpdf', (int) 8102)";`
> 25 votes

# Answer
To SET and GET module updates via code (without Drush). Below is the code

```
GET  = drupal_get_installed_schema_version('moduleName');

SET = drupal_set_installed_schema_version("moduleName", "8000");

```
> 0 votes

# Answer
Can also go update it directly in the database. If you're using something like Sequel Pro (mac) or whatever database UI tool windows/linux has it's really easy. Arguably not the best idea, and would not advise doing this against a production level database, but it'll get the job done!

Table = key\_value

collection = system.schema
name = fillpdf (your\_module)
value = update to i:8102;
> 0 votes

# Answer
In Drupal 10, the service `update.update_hook_registry` provides two wrapper functions to get and set the module installed version:

GET:

```
drush ev "echo \Drupal::service('update.update_hook_registry')->getInstalledVersion('mymodule')"

```

SET:

```
drush ev "\Drupal::service('update.update_hook_registry')->setInstalledVersion('mymodule', 8105)"

```
> 0 votes

---
Tags: 8
---


title: Render menu in twig template

text:
# Question
Title: Render menu in twig template
In `admin/structure/menu` I created a menu. Is it possible to render this menu (with machinename: `my_menu`) in a twig template? Somehow like:

```
{{ my_menu }}

```

# Answer
Simplify Menu sounds like what you'd want.

> The simplify\_menu module uses a TwigExtension to gain access to Drupal's main menu's (or any other menu for that matter), render array so it can be accessed from a twig template. Among the many advantages of having full control of the menu's render array in a twig template is the ability to customize the markup for your menus to ensure they are accessible and comply with standards.

```
// Get menu items
{% set items = simplify_menu('main') %}

// Iterate menu tree
<ul>
  {% for menu_item in items.menu_tree %}
    <li class="{{ item_class }} navigation__item">
      <a href="{{ menu_item.url }}" class="{{ link_class }}">{{ menu_item.text }}</a>
    </li>
  {% endfor %}
</ul>

```

Otherwise, there are a handful of `menu-*` twig templates to use when rendering a menu from a block. Turn on your Twig debugging settings in Drupal to see what the suggestions are.

However, you need to have pretty good knowledge of menu theming to get it exactly right (like handling child items and not flat menu structure as the example above displays) - that said, I would stick to letting a block render out the menu in a given region. Then, inspect `menu.html.twig` from your base theme (either classy or stable) to get an idea of what your options are if you want to modify markup.

Be sure to use a decent twig template suggestion and not just `menu.html.twig` \- as that will affect every menu that gets rendered by Drupal... it is the default template.

I would also suggest to install Menu Block as that will grant extra flexibility in theming and twig file suggestions. It also makes rendering trees of a menu (like section based navigation in a sidebar) a breeze.
> 13 votes

# Answer
For those who are still looking for an alternative approach, I suggest using Twig Tweak module as a more stable and more global use case, check out its cheat sheet

For rendering the menu via twig tweak, you can just do the following:

```
{# Expand menu items to display the entire menu tree. #}
{{ drupal_menu('menu_machine_name') }}

{# Specify menu level and depth. #}
{{ drupal_menu('admin', 2, 3) }}

```
> 10 votes

# Answer
Enable the simplify\_menu module, then add the code below to your page.html.twig or other twig template where you would like to render your menu:

```
<nav class="navigation__main" role="navigation">
  {% set item_class = 'navigation__item' %}
  {% set link_class = 'navigation__link' %}
  <ul class="navigation__items">
    {% set items = simplify_menu('main') %}
      {% for menu_item in items.menu_tree %}
          <li class="{{ item_class }}"><a href="{{ menu_item.url }}" class="{{ link_class }}">{{ menu_item.text }}</a></li>
      {% endfor %}
  </ul>
</nav>

```

the `'main'` is the menu id which you can find by hovering over the menu's edit button in the menus page and looking at the url displayed at the bottom of the browser.
> 4 votes

# Answer
If you are sick of installing modules for basic things, call this function in a preprocess and add the return value into variables and you can then use it in twig:

```
 /**
 * Helper function to get menu items as array for a given menu id/name
 *
 * @param String $menu_id
 *
 * @return Array menu items array with url, title properties
 */
function getArrayFromMenu($menu_id) {
   // Load menu as array to render in twig file
   $tree = \Drupal::menuTree()->load($menu_id, new MenuTreeParameters());
   $menu_array = [];

   if (!$tree) {
      return $menu_array;
   }

   // Sort according to the weight. @see https://www.drupal.org/project/drupal/issues/3019572
   $menu_tree = \Drupal::service('menu.link_tree');
   $manipulators = array(
      array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
   );

   $tree = $menu_tree->transform($tree, $manipulators);
   foreach ($tree as $item) {
      $title = $item->link->getTitle();
      /** @var \Drupal\Core\Url */
      $url_obj = $item->link->getUrlObject();
      $menu_array[] = array(
         'title' => $title,
         'url' => $url_obj->toString()
      );
   }

   return $menu_array;
}

```

It will just do the complex work, you just need to pass the menu id. In my case, menu id was mapped with a field of custom block type.
> 0 votes

---
Tags: theming, 8, hooks, navigation
---


# Question
Title: How can I add a title to a field in the checkout page?
I am wondering if there is a simple way (dropdown option or checkbox) to add a title to a field in the Drupal Commerce checkout page. Specifically, I want the second field for Street Address to have the label: Address line 2.

>

I was unable to find this field in *Admin \> Structure \> View* that allows the option to "Manage Display" or "Manage Form Display" and make a label for a field "Hidden" or otherwise.

I also looked in the Commerce sections to no avail.

Next step is to find out if there is a *Billing Information \> "Manage Form Display* menu somewhere.

Not in Home \> Administration \> Configuration \> People \> Profiles \> Profile types \> Edit Customer \> Manage fields either.

# Answer
Not possible in User Interface (via link or menu or whatever). But if you use the following code in a module, you can add a title to your form element:

```
<?php
function CUSTOM_form_alter($form, $form_state, $form_id) {
  // You should probably check for a form_id in here, as this runs on every form.
  // Below you will need to find the part of the $form array that has the billing address.
  $form['[see note above]']['widget'][0]['address']['address_line2']['#title'] = t('Address 2');
}

```
> 0 votes

# Answer
The second line of the address field has an invisible title. It's explicitly set by the Address module.

You can see that in action here: cgit.drupalcode.org/address/tree/src/Element/Address.php?h=272a7ce#n231

```
// Hide the label for the second address line.
if (isset($element['address_line2'])) {
  $element['address_line2']['#title_display'] = 'invisible';
}

```

You could use `hook_element_info_alter()` to define new process or after\_build callbacks.

```
function mytheme_element_info_alter(array &$types) {
  $types['address']['#process'][] = ['\Drupal\mytheme\Element\Address', 'processAddress'];
}

```

Overriding the element:

```
namespace Drupal\mytheme\Element;

use \Drupal\address\Element\Address as DefaultAddress;
use \Drupal\Core\Form\FormStateInterface;

/**
 * {@inheritdoc}
 */
class Address extends DefaultAddress {

  /**
   * {@inheritdoc}
   */
  public static function processAddress(array &$element, FormStateInterface $form_state, array &$complete_form) {
    $element = parent::processAddress($element, $form_state, $complete_form);
    unset($element['address_line2']['#title_display']);
    return $element;
  }

}

```
> 0 votes

# Answer
This answer is clumsy as it makes all form element labels visible, but ultimately gets the job done.

Using this theme and modifying specifically this template: DOrange\_form-element-label.html.twig with an additional conditional before the set classes statment:

```
{%- if title_display == 'invisible'-%}
  {%-
    set title_display = [
      'visible',
    ]
  -%}
{%- endif -%}

```
> 0 votes

# Answer
This is a solution that works on Commerce 2 and Drupal 10. We have to use a `process` because these are custom fields. In this example, I display a label for field `address_line2`, modify the `address_line1` label ans alter order of `family_name`

```
/**
 * Implementation of hook_element_info_alter
 */
function custom_module_element_info_alter(array &$types) {

  if (isset($types['address'])) {
    $types['address']['#process'][] = '_custom_module_add_adress_label';
  }
}

/**
 * Process callback for address element.
 */
function _custom_module_add_adress_label(array &$element, FormStateInterface $form_state, array &$complete_form) {
  $element['address_line1']['#title'] = t('Address');
  $element['address_line2']['#title_display'] = 'before';
  $element['address_line2']['#title'] = t('Building / Floor / Apt');
  $element['family_name']['#weight'] = -10;
  return $element;
}

```
> 0 votes

---
Tags: entities, commerce
---


# Question
Title: how to programtically capture authorized payments for orders during cron job for Drupal commerce
How to programatically capture authorized payments for orders during cron job for Drupal commerce .Payment gateway integrated is commerce stripe. Payment get authorized druing order placemnent and during cron job it need to be charged for all authorized payment for the orders. Drupal 10

# Answer
> 0 votes
Commerce payment extra module can be used here is the link https://www.drupal.org/project/commerce\_payment\_extra

---
Tags: commerce
---


# Question
Title: Views and contextual filter as user id from url
I want to create some views that shows the content created by the user, content flagged by the user and so on. I also need that when user a views user b then user a can see the content created by user b and so on. So i though i under Contextual filter i passed a default values as User Id from url. However when i visit the page i just see the view heading and no content.Please Help

Regards

# Answer
Create a new Views view with Format, Fields, and Filter criteria configured as needed.

Then do the following:

1. Under `Advanced`, add a new `Contextual filter` for `Content:
Author uid`.
2. Choose `Provide default value` and select `User ID
from URL`.
3. Under `Page settings`, set `Path` to `user/%/myview`.

Now when you navigate to `user/1/myview` you should see content from user 1.

For Flags you need to add a relationship for the flag and filter by it. I believe this answer would help with that.
> 4 votes

# Answer
Try the Entity Views Attachment (EVA) module: it lets you add user entity data into the view. Here is an excerpt about it from the module's project page:

> ... provides a Views display plugin that allows the output of a View to be attached to the content of any Drupal entity. The body of a node or comment, the profile of a user account, or the listing page for a Taxonomy term are all examples of entity content.
>
> The placement of the view in the entity's content can be reordered on the "Field Display" administration page for that entity, like other fields added using the Field UI module.
> 1 votes

# Answer
fields: Content: Title Content: Body

Path:/articles/%/page

Advanced: contextual filters Content: Authored by

author

this configuration will print all nodes created by user 1 : /articles/1/page
> 0 votes

---
Tags: 7, users, views
---


# Question
Title: How can I allow users to change their email addresses without a password via REST/JSON:API?
To change the password of a user account, Drupal requires the user to input their password.

I have a decoupled Drupal app using JSON:API.

The Nocurrent Pass module disables the password check when changing the email address, which is what I want, but it does so by means of `hook_form_alter()`, which means it doesn't remove the check for JSON:API/REST.

How can I disable this "password required" requirement to allow users to change their email address without inputting their password for JSON:API/REST (really, I want to disable it everywhere in all cases, including for JSON:API/REST)?

***Background***

This decoupled app doesn't even use passwords; users log in by a code sent to their email. There is a risk of accounts getting highjacked by an attacker changing the email address, but because the app is using the Alternative User Emails module, old email addresses can still be used to log in, so it is impossible to get locked out of the account. Thus the password requirement makes no sense in this case, and I want to disable it.

# Answer
Create a REST endpoint for this and in the post method get the user object and set the email like below -

```
$user->setEmail($mail);

```

Do not forget to get the current email id in a separate variable and save that in the field introduced by Alternative User Emails, i.e., `alternative_user_emails`

Something like this -

```
$current_email = $user->getEmail();
$existing_email_ids = $user->alternative_user_emails->getValue();
$existing_email_ids += $current_email;

$user->setEmail($new_email);
$user->save();

```
> 0 votes

# Answer
Since it seems this functionality doesn't exist, I decided to create the JSON-RPC Change Email No Password module. This adds a JSON-RPC endpoint for changing the email address without inputting the user's password.
> 0 votes

---
Tags: security, authentication-authorization
---


# Question
Title: How do I send webform submission data to a google sheet?
I have implemented the webform module on my Drupal 8.4 site. I have some forms that I would like to submit the data to a google spreadsheet, instead of the drupal database.

Can someone help me get started with this? Do I need to create a custom module to implement this functionality? What hooks do I need to use? Is there any documentation/tutorials out there on how to do this?

# Answer
Right now the only available solution is to use Zapier.

Ivan Zugec did a great screencast showing How to Create Forms using Webform and Contact in Drupal 8 and includes a demo showing how to push webform submissions into a Google Sheet using Zapier.

Hopefully, someone will port the Webform to Google Docs module from D7 to D8.
> 2 votes

# Answer
Zapier only allows a few 100 submissions per month on the free plan. Not worth it for us.

I’ve started using the google script editor to send webform data as a GET request through the webform remote post feature. Unlimited requests and offers better customization, at no cost.
I used How to Submit an HTML Form to Google Sheets…without Google Forms to implement the feature.
> 0 votes

# Answer
i have a better way and did myself.

Create google web form using google apps script and their provided code interface.

and then embed this form into any webpage or can also be used independently.
> 0 votes

# Answer
Apart from Zapier, theres a contrib module which do this. Webform GoogleSheets
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: How to disable cache in my custom contextual filter code?
I have created a custom module for authentication by using access\_token. The authentication is working fine. So, I thought to create a custom contextual filter and use that as a filter by access token. Please find my code below.

```
namespace Drupal\simple_auth\Plugin\views\argument_default;

use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;

use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\Core\Site\Settings;

/**
 * Default argument plugin for the current user's carts.
 *
 * @ViewsArgumentDefault(
 *   id = "uid_from_simple_auth_access_token",
 *   title = @Translation("User ID from Simple Auth Acess Token")
 * )
 */
class UserFilterByAccessToken extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {

 /**
   * {@inheritdoc}
   */
  public function getArgument() {
    return $this->extractUserIdFromAccessToken();
  }

  public function getCacheTags() {
    return [];
  }

  public function getCacheContexts(){
    return [];
  }

  public function getCacheMaxAge(){
    return 0;
  }

  /**
   * Extracts the user ID from the access token.
   */
  protected function extractUserIdFromAccessToken() {
    $request = \Drupal::request();
    $access_token = $request->headers->get('access-token');

    if (!$access_token) {
      return new JsonResponse([
          "error" => "Access token is required"
      ], 401);
    }

    $storedRefreshToken = hash('sha256', $access_token . Settings::get('simple_auth_access_secret_key'));

    $query = \Drupal::database()->select('simple_auth_access_tokens', 'sart');
    $query->fields('sart', ['uid', 'expiration_time']);
    $query->condition('sart.token', $storedRefreshToken);
    $result = $query->execute()->fetchAssoc();

    return $result['uid'];
  }
}

```

The above code have created my contextual filter in the view. But my exact issue here is, for example,

```
  public function getArgument() {
    return 1;
  }

```

This filters the userid 1, when I check the view in browser (rest export view), and if I update the code like this

```
  public function getArgument() {
    return 2;
  }

```

I am getting the same result till clearing the cache. So I need to disable cache for this operation. I have tried many solutions but not getting what I have needed. I have tried adding cache tags and I cleared it using .module file, but it is not working.

Kindly help on this and if you need more info please reply.

# Answer
I don't know the function `cacheTags()`, I assume you mean `getCacheTags()`.

And you are returning the same cache tag for all your requests. A cache tag is data dependent and therefore must vary by data. The typical Drupal schema for individual cache tag strings is `entity_type:primary_key`. So if your data varies by user, you'd need something like

```
<?php

use \Drupal\Core\Cache\CacheableDependencyInterface;

class UserFilterByAccessToken extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
  public function getCacheTags() {
    return ['user:' . $this->extractUserIdFromAccessToken()];
  }
}

```
> 1 votes

---
Tags: 8, views, caching
---


# Question
Title: How can I modify the nginx configuration in the Docker image?
I tried to use one of the two themes that came with Drupal - Olivero - and it is working in Maintenance mode, but once I switch maintenance mode off, I have a white page with a long list of menu item w/o any styling.

Initially, I installed drupal:10-fpm-alpine using Docker, which is now updated to drupal 10.2.4. It has nginx/1.22.1, PHP 8.2.12 and MySQL 8.0.35. When I saw a solution in this thread: Upgrade to Drupal 10.1.6, Theme Doesn't Load Outside Maintenance Mode, I got excited. However, being a newbie, I'm not sure how to apply the suggestion in this thread, because I only have these two nginx.conf files:

/var/lib/docker/overlay2/464cd198c9f1ece0e669690a0a61d353e1d3f8b457489ab24eee2f12c637aff3/merged/etc/nginx/nginx.conf /var/lib/docker/overlay2/ae457ff4ced0f9e2e384a51fc1fc502f299652899cf0bd5321b7777f2e7568c5/diff/etc/nginx/nginx.conf

and they don't have the following part that is referred in the solution above:

# Passes style generation to PHP.

location ~ ^/sites/.\*/files/styles/ { try\_files $uri @rewrite; }

or anything else PHP related. Could you give me advice?

# Answer
In the Drupal 10.1.0 release notes, there was an update to the recommended nginx config.

It should now be:

```
location ~ ^/sites/.*/files/(css|js|styles)/ {
  try_files $uri @rewrite;
}

```
> 0 votes

---
Tags: 10
---


# Question
Title: How can I get the image URL from a media entity in a node template?
Normally I am able to get an images URL by setting the display setting for that field to URL and then writing something similar to this in order to print the url

> {{ content.field\_image.0\['#markup'\] }}

However this is not possible in the display settings for a media entity, the only options are -

* Rendered entity
* Entity ID
* Thumbnail
* Label

So my question is how can I get the URL from the image, as I need to use the field as a background image so can't just render it out as normal?

# Answer
Here is a small example that I do in `hook_preprocess_node`:

```
  if ($variables['elements']['#view_mode'] == 'your_view_mode') {
    $node = $variables['elements']['#node'];

    if (!empty($variables['elements']['field_summary_image'])) {
      $entity = $node->get('field_summary_image')->getValue();

      if (!empty($entity)) {
        $media = Media::load($entity[0]['target_id']);

        $variables['background_image'] = ImageStyle::load('featured_news')
          ->buildUrl($media->image->entity->getFileUri());
      }
    }
  }

```

Don't forget the `use` statement at the top of the file for `Media` and `ImageStyle`.
> 2 votes

# Answer
With Twig Tweak module (2.4+) it can be done like this:

```
{{ node.field_media|file_url }}

```
> 7 votes

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

> {{ file\_url(content.field\_image\[0\]\['#media'\].field\_media\_image.entity.uri.value) }}
> 0 votes

# Answer
I have actually found a way to do this myself that doesn't involve writing custom code. It requires this module Image URL Formatter

This module adds a url formatter for image field. Then you can output image url directly.

1. Create a view mode for your media and.. I called mine Image URL
2. Go to your media type and edit the display settings, you will need to expand custom display setting to turn your new view mode on.
3. Now edit the display for this view mode by clicking on the new tab that should of appeared, and for your image field change the format to Image URL.
4. If you were using this media in a paragraph or a node you would go to the display settings for this and under your media field set the format to rendered entity and the View mode to 'Image URL' or what ever you called yours.
5. You will need to create a custom media template file for your field to remove the outer HTML.

I also needed to render my field as follows in my paragraph template file

> {{ content.field\_image|render|striptags|trim }}
> -1 votes

---
Tags: theming, media, uri
---


# Question
Title: The directory sites/default/files exists but is not writable and could not be made writable
We've recently had a few problems with our server, which seem to have been all patched up by myself, my host, and the cPanel team. However, since then we have been having problems with sites/default/files. The problems are happening on the active site running D6, and our dev site, running D7 in a subdirectory at the moment. I'm assuming the problems are related, so after I figure out how to fix one site, I'm sure it will be a similar fix for the other.

On the D7 site, when I save a piece of content, I get the message: **The specified file temporary://filetLWqk4 could not be copied, because the destination directory is not properly configured**

At admin/config/media/file-system, I'm seeing the error: **The directory sites/default/files exists but is not writable and could not be made writable.**

When clearing the cache, I get an error including: **Warning: unlink(mysite/sites/default/files/js/wysiwyg/wysiwyg\_tinymce\_VxxRIlcaFmzHlghU8SsOGCZd5TC\_PCxyhQAlqydMALE.js): Permission denied in drupal\_unlink() (line 2197 of mysite/dev/includes/file.inc)**

What I have read seems to indicate that this is the result of a permissions problem that people seem to have with some clean installs and server migrations. Neither of these cases apply to me, but I thought the solutions might. Most pages that I can find essentially recommend

`chown -R www-data:www-data sites/default/files`

and making sure that permissions are set to 755 or 775. I'm on centos, which uses `apache` instead of `www-data`, so I substituted it where appropriate, but I still have no luck.

I also just tried changing the permissions of `sites/default/files` to 777, and I'm still getting the error that it couldn't be written to.

Any ideas?

# Answer
RHEL and Fedora (among others) may have SELinux security enable. This will mask whatever the regular Unix permissions are showing. If this is enabled and there is not a "rw" in the context for the files/ directory it will not be writable no matter which group, user or unix permissions are granted. To see these "hidden" settings:

```
ls -laZ sites/default

drwxr-sr-x. apache www unconfined_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x. apache www unconfined_u:object_r:httpd_sys_content_t:s0 ..
-rwxr-sr-x. apache www unconfined_u:object_r:httpd_sys_content_t:s0         default.settings.php
drwxrwsr-x. apache www unconfined_u:object_r:httpd_sys_content_t:s0 files
-rwxr-sr-x. apache www unconfined_u:object_r:httpd_sys_rw_content_t:s0 settings.php

```

To change the settings on files/ so it is writable:

```
sudo chcon -R -t httpd_sys_rw_content_t files

```

When the install is done reset the context using the same command with the original "http\_sys\_content\_t" context.

fyi - This command will also be necessary to enable writes when installing themes under the "all" directory.
> 22 votes

# Answer
One way that may work for you is changing the group and make it group writable as below:

```
chgrp www-data sites/default/files
chmod g+w sites/default/files

```

> As per drupal docs the correct permission for all files is 644, and for directories is 755.

Also check this: What are the recommended directory permissions?
> 9 votes

# Answer
Guys the problem is very simple... whith XAMPP on Linux the "daemon" user is the owner of all process apache, SQL, etc... then just change the owner from the instalation folder "drupal" to daemon.. chown -R daemon:daemon folderdrupal

Regards from Chile ;)
> 2 votes

# Answer
I would also check the File System configuration and the paths being set there:

YOUR\_SITE\_URL/admin/config/media/file-system
> 0 votes

# Answer
How about we make this a bit more of a long-term solution? `su -l` to root, and run the following on your SElinux-enabled installation (these are from my Fedora box, sanitized for easier comprehension)

```
setsebool -P httpd_unified=0 httpd_enable_homedirs=1 httpd_read_user_content=1 \
httpd_can_network_connect_db=1 httpd_can_network_connect=1

# normal webstuff
semanage fcontext -a -t httpd_log_t "/home/USERNAME/dev/projects(/.*)/logs(/.*)?"
semanage fcontext -a -t httpd_user_content_t "/home/USERNAME/dev/projects(/.*)?"
#Drupal
semanage fcontext -a -t httpd_user_rw_content_t \
"/home/USERNAME/dev/projects(/.*)/www/sites/default/files(/.*)?"

restorecon -R -F -v /home/USERNAME/dev/projects/

```

done.
> 0 votes

# Answer
I was not able to make this work until I changed the owner and group of

/sites/default/files & /sites/default/settings.php

to apache:apache (CentOs 7) once I applied these settings everything worked perfectly
> 0 votes

# Answer
I ran into something similar upgrading packages on a development box from PHP 5.5 to 7.1. Possibly the new configuration overwrote what I had previously configured.

I have apache running with a different user group than what php-fpm was running with (`php-fpm`). I needed to change my php-fpm configuration to use a common group.
> 0 votes

# Answer
For CentOS/RockyLinux/RedHat/Fedora -

You need two commands, the `chown apache` not solely resolve the problem.

1. `chcon -R -t httpd_sys_rw_content_t sites/default/`
2. `chown -R apache:apache /var/www/html/demodrupal/sites/default/`
> 0 votes

# Answer
When addressing the issue where Drupal cannot write to files due to SELinux restrictions, the first step is to verify if SELinux is indeed active on your system. You can do this by executing the command `sestatus`.

If the output indicates that SELinux is enabled, you have the option to adjust the enforcement levels for specific domains without needing to disable SELinux system-wide.

For instance, if you discover that the SELinux policy is preventing your web server (such as Apache or Nginx, which commonly runs under the httpd\_t domain type) from writing to certain files required by Drupal, you can alter the SELinux policy for this domain to be permissive. This adjustment allows operations that would otherwise be blocked by SELinux, thus facilitating Drupal's file management tasks without fully compromising the security model.

To set the httpd\_t domain to permissive mode, use the command:

```
semanage permissive -a httpd_t

```

This command effectively instructs SELinux to log actions that would have been denied under enforcing mode for the httpd\_t domain, without actually denying them. It's a targeted approach that helps maintain the security benefits of SELinux for the rest of the system while accommodating specific requirements of your Drupal installation.

Please see https://access.redhat.com/documentation/en-us/red\_hat\_enterprise\_linux/7/html/selinux\_users\_and\_administrators\_guide/sect-security-enhanced\_linux-introduction-selinux\_modes
> -1 votes

---
Tags: files
---


# Question
Title: database query's columnCount() and getColumnMeta() missing from core
In Drupal 9 I could do:

```
$result = \Drupal::database()->query($query, $args);

```

then call

```
$result->columnCount()

```

also

```
$recs->getColumnMeta($c)

```

In Drupal 10 these functions: `columnCount()` and `getColumnMeta($c)` do not exist on the `\Drupal\Core\Database\StatementWrapperIterator` object returned (core/lib/Drupal/Core/Database/StatementWrapperIterator.php) - or elsewhere in core.

What is best way to get this data?

## Update

If I add to core/lib/Drupal/Core/Database/StatementWrapperIterator.php

```
  public function getColumnMeta($idx) {
    return $this->clientStatement->getColumnMeta($idx);
  }

  public function columnCount() {
    return $this->clientStatement->columnCount();
  }

```
* all seems fine. Not sure if this is correct approach so figured out using getClientStatement() to get PDO functions that are missing from Drupal's wrapper.

# Answer
It doesn't appear these were part of core in Drupal 9 either: https://api.drupal.org/api/drupal/9/search/getColumnMeta

These appear to be PHP PDO functions: https://www.php.net/manual/en/pdostatement.columncount.php https://www.php.net/manual/en/pdostatement.getcolumnmeta.php

And they still appear to exist.
> 3 votes

# Answer
I'm guessing you had a custom patch in your D9 site, because even the predecessor (`StatementWrapper`) didn't have the methods you mention.

You shouldn't patch the core class to combat this, instead you should retrieve the `PDOStatement` from the wrapper, and call the method(s) on that:

```
$result = \Drupal::database()->query($query, $args);
$column_count = $result->getClientStatement()->columnCount();

```
> 1 votes

---
Tags: database, 10
---


# Question
Title: Get translated field value with fallback
How can I get the translated value of a field in Drupal 8 and if no translation is given, fallback to the default node language? I tried this: https://drupal.stackexchange.com/a/145747/9586, but when no translation for a field if added, it just returns NULL.

Here is what I tried:

```
    $node = Node::load(2);
dsm(\Drupal::entityManager()->getTranslationFromContext($node)->field_my_awesome_field->value);

```

# Answer
You can try to provide the context for a fallback as 3rd parameter:

```
public EntityRepositoryInterface::getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array())

```

Here is the documentation, but it is not documented, what the content of the array is exactly:

getTranslationFromContext

I would code the fallback myself and take control, how this is handled exactly, if the node is not fully translated:

```
$val = \Drupal::service('entity.repository')->getTranslationFromContext($node)->field_my_awesome_field->value;
 if (empty($val)) {
    // $node has no translation with the default node language
    // get the default from somewhere else (domain, user ...) and try again
    $val = $node->getTranslation($defaultlanguage)->field_my_awesome_field->value;
}
if (empty($val)) {
   // someone needs to translate this node, in the meantime get the original value
   $val = $node->field_my_awesome_field->value;
}

```

You can adjust the code to your needs, you can add as many fallbacks as you like or go directly to the last if-statement to load the original field value.

One remark: If your multilingual site is setup correctly, this should not happen. The fallback is there, when something goes wrong. For example, if you configure a field as translatable, but when translating the node, you leave only this field blank. Then drupal does not know, is this intentionally, should it be blank or do you want to load the field from another language?
> 3 votes

# Answer
Drupal 8 does not have built in field-level language fallbacks. That feature was removed in favor entity level language fallbacks since that is the common case. Usually an entity is translated as a while (or not) and it removes a huge amount of complexity, especially in views or so.

If you have a specific field where you want to apply this, then you need to implement that yourself. You can check if an entity-level translation exists with $node-\>hasTranslation('en') and if so, get it with $translation = $node-\>getTranslation('de') ($translation is still a node object, it's a clone of the original one with a different active language). Then check if you have a value and repeat until find one.

Something like this:

```
$value = NULL;
$language_manager = \Drupal::languageManager();
$current_langcode = $language_manager->getLanguage(Drupal\Core\Language\LanguageInterface::TYPE_CONTENT);
foreach ($language_manager->getFallbackCandidates(['langcode' => $language_manager->getLanguage(]) as $langcode) {
  if ($node->hasTranslation($langcode) && !$node->getTranslation($langcode)->field_my_awesome_field->isEmpty()) {
    $value = $node->getTranslation($langcode)->field_my_awesome_field->value;
    break;
  }
}

```
> 5 votes

# Answer
Drupal 10. Face same problem where client needed field level fallback functionality. Did below code. Hope it will help someone

```
 function yourmodule_paragraph_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
   if ($display->id() == "paragraph.image_video_media.default" && empty($build['field_image_video_media'])) {
     // Display data in the default language when a translation is unavailable.
     $defaultLanguage = \Drupal::languageManager()->getDefaultLanguage()->getId();
     $defaultLanguageEntity = \Drupal::service('entity.repository')->getTranslationFromContext($entity, $defaultLanguage);
     $defaultLanguageBuild = $display->build($defaultLanguageEntity);
     if (isset($defaultLanguageBuild['field_image_video_media'])) {
       $build['field_image_video_media'] = $defaultLanguageBuild['field_image_video_media'];
     }
   }
}

```
> 0 votes

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


# Question
Title: How do I import a sync config file into my Kernel unit test?
How do I import a sync config file into my Kernel unit test ?

Specifically, I have some REST resources in files `config/sync/rest.resource.foo.yml`,`config/sync/rest.resource.bar.yml`

At present, when I run `\Drupal::service('router.builder')->rebuild()` in my `setUp()` function, it does not add in the routes for these resources, so when I make GET requests to them in the tests, I get 404.

I don't want to import all of the config for my Drupal site into the unit test, just the REST resources.

# Answer
You can add the two ReST resources to your module's /config/optional directory. The config files will be installed with the module if the dependencies are met.

In the kernel test, use `$this->installConfig(['your_module']);` to install the two ReST resources.
> 0 votes

---
Tags: configuration, testing
---


title: Add Expression for Entity Query

text:
# Question
Title: Add Expression for Entity Query
I've been working with the `entityQuery` to query the db and get an array of filtered `nids` however I need to add an expression to my query.

I've checked the `Query` class and found a protected `sqlQuery` attribute that has access to `addExpression()`. In my case I'm not extending the class but rather instantiating it through `\Drupal::entityQuery('node')`.

Also after checking a bit I found that the `Select` class has a function addExpression() that does exactly what I need, but then I lose the `entityQuery` and has to addJoin/addField and so on for each of the fields I would like to include in my conditions.

My objective:

```
$expression = "
    (
        6371000
        * acos(
            cos( radians({$latitude}) )
            * cos( radians( {$latitudeField} ) )
            * cos(
                radians( {$longitudeField} )
                - radians({$longitude})
            )
            + sin( radians({$latitude}) )
            * sin( radians( {$latitudeField} ) )
        )
    )";
$query = \Drupal::entityQuery('node')
->condition('status', 1)
->condition(`field_city`,1,'=')
->addExpression($expression, 'distance');

$nids = $query->execute();

```

Did I miss something ? Is there any other way to achieve what I want ?

EDIT: I found this approach but doesn't seem straight forward

EDIT2: Better approach is this

# Answer
> 0 votes
> Is there any other way to achieve what I want ?

Nope. Sorry. Entity query is backend agnostic and doesn't support SQL. It wouldn't make much sense using it with config queries for example. You could manually assemble your SQL query against the default SQL entity storage using table mapping:

```
$storage = \Drupal::entityTypeManager()->getStorage('node');
if (!$storage instanceof SqlEntityStorageInterface) {
  return;
}
$mapping = $storage->getTableMapping();

```

and from there you can call the methods on TableMappingInterface to find table and column names.

```
$query = \Drupal::database()->select($storage->getDataTable(), 'n');
// We know status is stored in the data table, no need to make this fully generic.
$query->condition('n.status', 1)
// But we know fields are in dedicated tables.
$city = $mapping->getFieldTableName('field_city`);
$query->innerJoin($city, 'c', 'c.entity_id = n.nid AND c.langcode = n.langcode');
// It's not clear what type field_city is, use whatever property is
// appropriate here instead of value.
$column = $mapping->getColumnNames('field_city')['value'];
$query->condition("c.$column", 1);
// Do the same for latitude and longitude tables and column names...
// Finally:
$query->addExpression($expression, 'distance');

```

It's a balancing act when reaching this deep of what you hardwire and what you do not. For example, we presumed status is not stored in a separate table. In a future Drupal version it might become one. Is it worth the code complexity? Not in my opinion. Your opinion might differ. You need to retrieve the field storage definitions from `entity_field.manager` and check `$mapping->requiresDedicatedTableStorage($definition)`.

Another thing we hardwired is the dedicated field tables use entity\_id and langcode as respective column names for that data. This is much less of an opinion whether to do so: there's no API to query them (`getExtraColumns` is not keyed so there's not really a way to figure out what those columns mean) so it's reasonable to expect core will keep those column names as they are.

I also hardwired nid and langcode. You could retrieve the entity type definition, run getKey('id') and getKey('langcode') and then use those as field names and retrieve their column names... utterly pointless in my opinion. Even more so than `status`.

Now, I did not hardwire `node__field_city`. Unlike the previous paragraphs, expecting table names to be node\__fieldname is not valid even at present time: table names for longer than 48 character field names get hashed. Who knows what the future might bring. Also the API is very simple and straightforward quite unlike the previous ones.

# Answer
> -1 votes
I am not sure if following is what you're looking for, it helped me when I was doing something similar

```
    $sql_snippet = <<<EOF

ROUND(
  CASE $this->tableAlias.$unit_column
    WHEN 'kg' THEN $this->tableAlias.$this->realField * :kg_coefficient
    WHEN 'lb' THEN $this->tableAlias.$this->realField * :lb_coefficient
  END
, :precision) = :value
EOF;

    // The difference in this invocation of ::addWhereExpression() compared to
    // the invocation in the filter handler is that here part of the DB
    // placeholders come from $this->options (such as precision) and others come
    // from the actual argument we have received, i.e. derived from
    // $this->argument.
    $this->query->addWhereExpression(0, $sql_snippet, [
      ':value' => round($arg['value'], $this->options['precision']),
      ':kg_coefficient' => $kg_coefficient,
      ':lb_coefficient' => $lb_coefficient,
      ':precision' => $this->options['precision'],
    ]);
  }

```

Lifted from Here

---
Tags: 8, entities, database
---


# Question
Title: RestUI: The used authentication method is not allowed on this route
The following works on three sites but doesn't work on one. I've restored the site from the backup of another site, and this works, until it doesn't work the next day. I've reinstalled modules.

I make the following POST request:

```
POST /node?_format=hal_json HTTP/1.1
Content-Type: application/hal+json
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
User-Agent: Ruby
Authorization: Basic <authstr>
Connection: close
Host: <domain>
Content-Length: 215

"
<- "{\"_links\":{\"type\":{\"href\":\"https://<domain>/rest/type/node/article\"}},\"title\":[{\"value\":\"2024-03-15 Test\"}],\"body\":[{\"value\":\"\\u003cimg src='' alt='' /\\u003e\",\"format\":\"full_html\"}],\"type\":[{\"target_id\":\"article\"}]}"

```

where `<authstr>` and `<domain>` are my reasonable values. I'm getting `<Net::HTTPForbidden 403 Forbidden readbody=true>`.

with message:

```
 "{\"message\":\"The used authentication method is not allowed on this route.\"}"

```

What is wrong?

I am using:

* HAL 1.0.3
* HTTP Basic Authentication 9.5.11
* restui 8.x-1.21
* RESTful Web Services 9.5.11
* Drupal 9.5

# Answer
I can't believe it...

The problem was that I created a `/node` Page, with content: `<script>window.location = '/some-redirect'</script>` and assigned that as the front page. This is perfectly reasonable behavior. And it broke a POST route, with the error ^ described in the question! I'd say this is a bug in Drupal. Deleting the page that does javascript redirect, fixed this issue.

What is also important is that `/node` is the default homepage route, so you may inadvertently do something on that page, breaking REST. I'd recommend not using `/node` at all, other than for REST POST'ing.
> 2 votes

---
Tags: authentication-authorization
---


# Question
Title: Changing the weight of my custom module does not affect the order of execution of my hook implementation
I use the `goalgorilla/open_social` profile which brings in open social with its various modules. Inside its `social_user.module` there is a standard `hook_form_FORM_ID_alter` implementation which I temporarily edit and prepend `echo 'social';`. I also have a custom module `my_custom_module` with the same `hook_form_FORM_ID_alter` implementation which simply contains `echo 'custom';`.

My problem is that no matter what, I cannot get my custom module's echo to run after the open social's one. The higher weight of my custom module does not seem to affect anything. So far I've done the following:

1. `module_set_weight('my_custom_module', 9999);`
2. Confirmed in `core.extension.yml` that:

```
social: 0
social_user: 0
my_custom_module: 9999

```
3. Installed https://www.drupal.org/project/modules\_weight and confirmed the expected weights at `admin/config/system/modules-weight`.

Where should I look at next?

# Answer
You might want to read this issue. Didn't read it because there are most times better solutions by adding a callback to the form build which gets executed at the right time: `#process`, `#after_build` or `#pre_render`.
> 1 votes

# Answer
I faced the similar issue recently and figured out that some modules (like Field Group in my case) uses hook\_module\_implements\_alter to change the order of execution.
> 0 votes

---
Tags: 9, distributions
---


# Question
Title: Remove unnecessary JS files to optimize Total Blocking Time
I need to improve the performance of a site and check it with Carbon Neutral Website. One of the most difficult thing I find is to remove "Total Blocking Time", the problem is that Drupal includes a lot of files that really aren't used in the web design.

I would like to be able to search and remove the files that aren't really used. Is it a way how to remove them? (maybe with libraries-override). Or what is the recommended way to optimice a Drupal site?

PD: I know about "Aggregate JavaScript files", however, the result shows a lot of problems. So I prefer to remove unnecessary files.

```
<script src="/core/assets/vendor/underscore/underscore-min.js?v=1.13.6"></script>
<script src="/core/misc/polyfills/object.assign.js?v=9.5.3"></script>
<script src="/core/misc/polyfills/nodelist.foreach.js?v=9.5.3"></script>
<script src="/core/assets/vendor/css-escape/css.escape.js?v=1.5.1"></script>
<script src="/core/assets/vendor/es6-promise/es6-promise.auto.min.js?v=4.2.8"></script>
<script src="/core/assets/vendor/jquery-once/jquery.once.min.js?v=2.2.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/version-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/data-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/disable-selection-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/focusable-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/form-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/ie-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/jquery-patch-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/keycode-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/plugin-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/safe-active-element-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/safe-blur-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/scroll-parent-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/unique-id-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/widget-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/widgets/autocomplete-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/labels-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery.ui/ui/widgets/menu-min.js?v=9.5.3"></script>
<script src="/core/assets/vendor/tabbable/index.umd.min.js?v=5.3.3"></script>
<script src="/core/misc/autocomplete.js?v=9.5.3"></script>
<script src="/libraries/bootstrap/js/bootstrap.min.js?sacm5y"></script>
<script src="/themes/contrib/bootstrap/js/drupal.bootstrap.js?sacm5y"></script>
<script src="/themes/contrib/bootstrap/js/attributes.js?sacm5y"></script>
<script src="/themes/contrib/bootstrap/js/theme.js?sacm5y"></script>
<script src="/core/misc/jquery.once.bc.js?v=9.5.3"></script>
<script src="/themes/contrib/bootstrap/js/popover.js?sacm5y"></script>
<script src="/themes/contrib/bootstrap/js/tooltip.js?sacm5y"></script>
<script src="/core/misc/debounce.js?v=9.5.3"></script>
<script src="/core/misc/form.js?v=9.5.3"></script>
<script src="/themes/contrib/bootstrap/js/misc/form.js?sacm5y"></script>
<script src="/modules/contrib/webform/js/webform.behaviors.js?v=9.5.3"></script>
<script src="/core/misc/states.js?v=9.5.3"></script>
<script src="/themes/contrib/bootstrap/js/misc/states.js?sacm5y"></script>
<script src="/modules/contrib/webform/js/webform.states.js?v=9.5.3"></script>
<script src="/modules/contrib/webform/js/webform.form.js?v=9.5.3"></script>
<script src="/modules/contrib/webform/js/webform.element.details.save.js?v=9.5.3"></script>
<script src="/core/misc/announce.js?v=9.5.3"></script>
<script src="/modules/contrib/webform/js/webform.element.details.toggle.js?v=9.5.3"></script>
<script src="/core/misc/progress.js?v=9.5.3"></script>
<script src="/themes/contrib/bootstrap/js/misc/progress.js?sacm5y"></script>
<script src="/core/assets/vendor/loadjs/loadjs.min.js?v=4.2.0"></script>
<script src="/core/modules/responsive_image/js/responsive_image.ajax.js?v=9.5.3"></script>
<script src="/core/misc/ajax.js?v=9.5.3"></script>
<script src="/themes/contrib/bootstrap/js/misc/ajax.js?sacm5y"></script>
<script src="/modules/contrib/webform/js/webform.scroll.js?v=9.5.3"></script>
<script src="/modules/contrib/webform/js/webform.ajax.js?v=9.5.3"></script>
<script src="/modules/contrib/webform/js/webform.element.message.js?v=9.5.3"></script>
<script src="/core/assets/vendor/jquery-form/jquery.form.min.js?v=4.3.0"></script>
<script src="/modules/contrib/webform/js/webform.element.select.js?v=9.5.3"></script>
<script src="/modules/custom/zoom_messenger/js/scriptZoom.js?v=1"></script>
<script src="/libraries/dompurify/dist/purify.min.js?sacm5y"></script>
<script src="/core/misc/jquery.tabbable.shim.js?v=9.5.3"></script>
<script src="/core/misc/position.js?v=9.5.3"></script>
<script src="/modules/contrib/search_autocomplete/js/jquery.autocomplete.js?v=9.5.3"></script>
<script src="/themes/contrib/bootstrap/js/misc/autocomplete.js?sacm5y"></script>

```

# Answer
> -2 votes
Well your question isn't clear enough.

when you say "PD: I know about "Aggregate JavaScript files", however, the result shows a lot of problems. So I prefer to remove unnecessary files."

Do you mean you have design problems? (can you give an example?), if so it means you need to investigate why that happens. most probably its an issue with libraries priorities and dependancies. so fixing that is recommended.

you could always prevent a library from loading by using `libraries-override:` but that always comes at a cost of testing.

Finally you could also play around with processing your JS files and creating bundles outside of Drupal and using these files.

---
Tags: performance
---


# Question
Title: Import custom data from another DB to nodes
For create/update new nodes I used the Feeds module.

It works well with CSV/OPML.

But now I need to import a new data from another database, forming result by SQL query. There are old modules for this:

Feeds Database

Feeds SQL

For Drupal 10 I cannot find nothing.

Dump from external DB and following import by Feeds module works, but I'd like to get result without intermediate entities like CSV files.

# Answer
in your Settings.php you could include the "external" DB and then run your queries.

for example in settings.php:

```
 $databases['default']['default'] = [
  'database' => // The DB Name,
  'driver' => 'mysql',
  'host' => // The DB Host,
  'username' => // DB username,
  'password' => // The DB password,
  'port' => // Mysql port,
];

```

Then in your code, you could switch between both Databases for example: using

```
\Drupal\Core\Database\Database::setActiveConnection('external');// connect to "source" DB
$db = \Drupal::database();
$db->query(); // Perform your queries here and get the results you need
\Drupal\Core\Database\Database::setActiveConnection();// Connect to "destination" DB
// create your nodes using the data retrieved from the query above.

```

I suggest reading more here: https://www.drupal.org/docs/drupal-apis/database-api/static-queries

and: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Database%21Database.php/class/Database/10
> -2 votes

---
Tags: feeds, 10
---


# Question
Title: Cancel adding an order item at any point
I think I have an quite unusual usecase.

In my commerce installation, there are two possible carts for each user. "buy" and "sell". Each product has two variations, also called "buy" and "sell". Commerce is configured to add those variations to the corresponding carts.

Now the problem: There should always only be one cart for the user. Either of type "buy" or type "sell".

## Example:

The user has just added item "Apple" to his "buy" cart. Now he tries to add "Bananas" to his "sell" cart. This should be aborted/cancelled.

---

I have seen there are events for the add to cart, but those run when the item has been added and the cart was created if I'm not mistaken.

Are there any events that would help me in that usecase? Or do I need to somehow hook myself into any possible form to prevent the adding? Cause I'm using a combination of the module "variation cart form", "add to cart link" and a custom form.

thanks in advance

# Answer
> -1 votes
I dont think there are any events that would help, looking at

```
Drupal\commerce_cart\Event\CartEvents

```

as you said they all run after an item has been added, i think your best bet is to alter the add to cart form and query the other cart for items.

---
Tags: commerce
---


title: Get Field Weights Programmatically

text:
# Question
Title: Get Field Weights Programmatically
I have a custom module which ultimately creates a node of a given type. It gets the fields of that node type and creates my own form with them, HOWEVER, it does not preserve that node's order of fields.

I can do it manually, but would prefer to follow one of the display mode's configuration, like 'view' or 'form'

How can I access the field weights in PHP?

# Answer
> 1 votes
If $build is your own form, keyed by field names, you can try something like this:

```
$display = \Drupal::service('entity_display.repository')
  ->getFormDisplay('node', 'given_type');

foreach ($display->getComponents() as $name => $options) {
  if (isset($build[$name])) {
    $build[$name]['#weight'] = $options['weight'];
  }
}

```

---
Tags: entities, 10
---


# Question
Title: Block Plugin not Showing on Certain Pages
This issue has been bugging me for some time and maybe this is just how Drupal is or I am missing something. Anyway, the setup is like this:

I have my defined regions on the site. One region is **Hero**. Hero as a region should have two things:

1. A block that displays an image with some text overlay. (Hero Block)
2. A block that displays relevant notifications if applicable (Alert Block)

Both of these blocks are custom block plugins with a class and template housed in a custom module. These blocks render and work just fine on any of the pages for my custom content types. **They however don't render on Group pages or View pages.**

So that is my question: Why don't my custom block plugins show on my Group or View pages. Is this by design? All other menu, footer, etc. blocks show just fine on these pages but not my custom blocks. If I set a breakpoint in the `build()` method in my blocks the breakpoint does not even hit so its like they are not even trying to render.

Is this desired Drupal functionality or am I missing something? I could probably use Twig Tweak or render the blocks via preprocessor but I only want to do so as a last resort.

# Answer
I figured it out. If anyone has a similar issue mine was caused by a **ContextDefinition** I placed on the block. The context was of type node so I suppose it would make sense that the block was not trying to render in places outside of this context.

Adding `required = FALSE` to the definition and adding another **ContextDefinition** for group entities resolved my issue. I did have to replace the block(s) on the blocks layout page for this to take effect.

```
context_definitions = {
    "node" = @ContextDefinition("entity:node", label = @Translation("Node"), required = FALSE),
    "group" = @ContextDefinition("entity:group", label = @Translation("Group"), required = FALSE),
}

```
> 1 votes

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


# Question
Title: Get value from list_string instead of key
I have this field created through baseFieldDefinition

```
$fields['type'] = BaseFieldDefinition::create('list_string')
        ->setRevisionable(TRUE)
        ->setLabel(t('Type'))
        ->setRequired(TRUE)
        ->setSettings([
            'allowed_values' => [
                'house'    => 'House',
                'business' => 'Company',
            ],
        ])
        ->setDisplayOptions('view', [
            'label' => 'visible',
            'type' => 'list_default',
            'weight' => 6,
        ])
        ->setDisplayOptions('form', [
            'type' => 'options_select',
            'weight' => 6,
        ])
        ->setDisplayConfigurable('view', TRUE)
        ->setDisplayConfigurable('form', TRUE);

```

But when i get the entity in php rest resource

```
$request = RequestEntity::load($id);

$request->get('type)->value
// Returns key 'business' instead of value 'Company'

```

Is there a way to fix this?

Any help is welcome!

# Answer
I could make this work by changing

```
$request->get('type)->value

```

to

```
$request->house_type->getSetting('allowed_values')[$request->get('house_type')->value]

```
> 3 votes

# Answer
This is working for me (Drupal 9):

```
  $request->get('type')->view()[0]['#markup'];

```
> 0 votes

---
Tags: entities
---


# Question
Title: Why Drupal is faster than WordPress in general
Some people say that Drupal, in general, is faster(requests per second) than WordPress. I want to know why Drupal is faster. Is it faster because of its cache, sql query or something else?

I see a benchmark here http://sven.webiny.com/benchmark-webiny-vs-wordpress-vs-drupal-vs-joomla-vs-tomatocms/

# Answer
It's almost impossible to meaningfully compare the performance of Drupal and Wordpress, because their speed varies widely depending on the configuration and installed modules / plugins. Both are capable of scaling when sites are built by skilled developers.

Regarding the Webiny benchmark, it's almost certain that Drupal's page cache was disabled (the default setting) for the test; I ran the same `ab` command on an Amazon micro instance and got over 100 requests per second.

That said, the Drupal community has a lot of interest in performance (the High Performance group is a good place to start). The core development workflow has a process to account for performance issues. And the ecosystem offers a range of modules to scale even further, including support for memcached, boost, varnish, APC, MongoDB, CDNs, and others.
> 8 votes

# Answer
Drupal definitely has a leg up in the ability to scale with performance and build upon the core technology. It's framework is more flexible because developers need it to be and are usually more interested, as Dylan mentioned. Wordpress is faster out of the gate because its users wouldn't really know how to improve it because they don't need to. They aren't interested as much in the best performance, which fits the platform design and use case. I wrote a blog about performance if you want more information
> 0 votes

# Answer
As they say, "There are three kinds of lies: lies, damned lies, and statistics (or benchmarks)". Ever more so when comparing such diverse CMS as Drupal and WordPress.

This recent (as of 15 March 2024) page shows PHP speed differences for many various environments, including Drupal and WordPress.

IMHO, an informed decision would be taken by installing both, on exactly same VPS, with similar plugins and themes.
> 0 votes

---
Tags: performance
---


# Question
Title: How do I print the variable "activeLangcode" in a paragraph twig template?
I tried to get the value with (what didn't work):

{{ paragraph.activeLangcode }} {{ paragraph.activeLangcode.value }}

# Answer
Get the language of the paragraph entity through the method language() in a preprocess hook:

```
function mytheme_preprocess_paragraph(&$variables) {
  $variables['lang_id'] = $variables['paragraph']->language()->getId();
}

```

For a Twig only solution you would need to adjust the twig sandbox policy, see Language name of translated node
> 3 votes

# Answer
Didn't work for me; So I used this method:

> {% set language = content.field\_title\['#language'\] %}
> -1 votes

---
Tags: theming
---


# Question
Title: How to render a paragraph field in Twig in correct language?
I've got nodes with hero images. The hero images are a paragraph field with unlimited cardinality, each with an image and a translatable text. For design reasons I need to print the hero images in `page.html.twig` (using Twig Tweak for simplicity)

`{{ drupal_field('field_banner_slide', 'node', node.id) }}`

The hero slider has some options like timer, size,... which are other fields on the same host node, and pulled in during preprocess

```
function MYTHEME_base_preprocess_field(array &$variables, $hook) {
  $parentEntity = $element['#object'];

  if ($parentEntity && $variables['field_name'] == 'field_banner_slide') {
    // attach JS library
    // add HTML data attributes on this field based on other field values of same host node
    // ...and so on...
  }
}

```

All worked fine until my site went to the translator. My slider always returned the default lang. Next I tried setting the language in `page.html.twig`

`{{ drupal_field('field_banner_slide', 'node', node.id, 'default', language.getId()) }}`

This works for every other field - except Paragraphs. I've also tried the alternative

`{{ node.field_banner_slide|view('default', language.getId()) }}`

but still the same language problem.

I've already checked the source code from Twig Tweak, it seems to correctly set the language

```
  public function drupalField($field_name, $entity_type, $id = NULL, $view_mode = 'default', $langcode = NULL, $check_access = TRUE) {
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $entity = $id
      ? \Drupal::entityTypeManager()->getStorage($entity_type)->load($id)
      : \Drupal::routeMatch()->getParameter($entity_type);
    if ($entity && (!$check_access || $entity->access('view'))) {
      $entity = \Drupal::service('entity.repository')
        ->getTranslationFromContext($entity, $langcode);
      if (isset($entity->{$field_name})) {
        return $entity->{$field_name}->view($view_mode);
      }
    }
  }

```

I've been really digging here, but I can't find any single error. How do I get my correctly translated paragraphs?

PS: I don't want to use `{{ drupal_entity('paragraph', my_field_banner_slide_target_ids, 'default', my_langcode) }}`, because I also need the preprocessing from the host field.

# Answer
The problem is that `FieldItemInterface::view()` has no language parameter. Furthermore paragraph fields are not translatable (only the subfields of the paragraph entity are translatable). So when rendering a paragraph field directly, without going through the host entity render stack, the language information is lost.

My solution was to force the translation in a preprocess function:

```
function MYTHEME_preprocess_field(array &$variables, $hook) {

  // field_banner_slide is a paragraph field which needs
  // translation AND is rendered directly, e.g. by using Twig Tweak's
  // {{ drupal_field('field_banner_slide', 'node', node.id) }} in page.html.twig
  //
  // don't to this for "normal" rendering, e.g. when using
  // {{ content.field_banner_slide }} in node.html.twig

  if ($variables['field_name'] == 'field_banner_slide') {
    $lang = \Drupal::languageManager()->getCurrentLanguage()->getId();
    if(count($variables['items'])) {
      foreach($variables['items'] as $key => $item) {
        if ($item['content']['#paragraph']->hasTranslation($lang)) {
          $variables['items'][$key]['content']['#paragraph'] = $item['content']['#paragraph']->getTranslation($lang);
        }
      }
    }
  }
}

```

For a better technical explanation see issue #2753201 on d.o
> 1 votes

# Answer
Didn't work for me; So I used this method:

> ```
> {% set language = content.field_title['#language'] %}
>
> ```
> -1 votes

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


title: How can I import staged configuration?

text:
# Question
Title: How can I import staged configuration?
I'm trying to import configuration with `drush cim`. I'm getting

```
Rename operation for simple configuration. Existing configuration system.site and staged configuration domain.config.xxx.system.site.

```

I looked at config/sync and there are a bunch of domain.config.xxx.system.site files. I looked at settings.php and there's no mention of the domain keyword. I was referred https://drupal.stackexchange.com/questions/150481/how-can-i-import-the-configuration-on-a-different-site but that's a different issue. Search engines don't have information on this specific issue. How can I import these?

# Answer
It's likely that config was created using the Domain module, or more accurately its submodule, Domain Config.

To import it without changing the files, you'll need to install and configure the module so it has the same settings as the site it was exported from, at least in terms of the domain settings.

Another approach might simply be to remove `domain.config.xxx` from the start of each file name. looking at how the `ConfigDomainOverrider` class works it seems to just be adjusting file names, so it might be that simple.
> 1 votes

---
Tags: drush, configuration, 10
---


# Question
Title: Wrapping content in anchor tags with CKEditor
I am trying to **wrap a block of HTML content** in an tag in a Drupal 8 installation:

```
<a href="/link"><h2>Link 1</h2><h3>Subheader link 1</h3></a>

```

**CKEditor changes it** to:

```
<h2><a href="/link">Link 1</a></h2><h3><a href="/link">Subheader link 1</a></h3>

```

The **Limit allowed HTML tags** I have set are:

```
<div class id> <p class id> <img class id> <a href hreflang class id> <em> <strong> <cite class id> <blockquote cite cla> <code> <ul type class id> <ol start type class id> <li class id> <dl class id> <dt class id> <dd> <h2 class id> <h3 class id> <h4 class id> <h5 class id> <h6 class id> <s> <sup> <sub> <img src alt data-entity-type data-entity-uuid data-align data-caption class id> <table class id> <caption class id> <tbody class id> <thead class id> <tfoot class id> <th class id> <td class id> <tr class id> <hr class id> <p class id> <h1 class id> <pre class id><section class id><header class id> <a div> <a span>

```

How can I wrap content in an anchor tag with CKEditor?

# Answer
> 6 votes
I found a solution. As @Clive said CKEDITOR.dtd.a.h2 = 1; and CKEDITOR.dtd.a.h3 = 1; is the solution.

These need to be declared in a my\_module.module file:

```
function my_module_editor_js_settings_alter(array &$settings) {

  foreach (array_keys($settings['editor']['formats']) as $text_format_id) {
    if ($settings['editor']['formats'][$text_format_id]['editor'] === 'ckeditor') {
        $settings['editor']['formats'][$text_format_id]['editorSettings']['customConfig'] =
        base_path() . drupal_get_path('module', 'my_module') . '/ckeditor_config.js';
}
  }
}

```

And then we create a file ckeditor\_config.js:

```
CKEDITOR.dtd['a']['h2'] = 1;
CKEDITOR.dtd['a']['h3'] = 1;

```

Doing this we can wrap h2 and h3 elements with an anchor tag and CKEditor is not going to modify it.

# Answer
> 0 votes
Adding below lines in config.js file has resolved my problem:

```
config.protectedSource.push(/<h1[\s\S]*?\>/g);
config.protectedSource.push(/<\/h1[\s\S]*?\>/g);
config.protectedSource.push(/<h2[\s\S]*?\>/g);
config.protectedSource.push(/<\/h2[\s\S]*?\>/g);
config.protectedSource.push(/<h3[\s\S]*?\>/g);
config.protectedSource.push(/<\/h3[\s\S]*?\>/g);
config.protectedSource.push(/<h4[\s\S]*?\>/g);
config.protectedSource.push(/<\/h4[\s\S]*?\>/g);
config.protectedSource.push(/<h5[\s\S]*?\>/g);
config.protectedSource.push(/<\/h5[\s\S]*?\>/g);
config.protectedSource.push(/<h6[\s\S]*?\>/g);
config.protectedSource.push(/<\/h6[\s\S]*?\>/g);

```

---
Tags: 8, wysiwyg
---


title: Admin Search Report Data

text:
# Question
Title: Admin Search Report Data
On the /admin/reports/search report, there are the most searched terms listed. On the installation I'm responsible for since a few weeks, this list is emptied every day. This is one part of the problem, but my question is another, as I also have to create a detailed report on how the search was being used.

For that reason I'd like to export the data as it is shown on the /admin/reports/search page on a daily basis. Unfortunately the content of the database table "search\_total" seems not to be the resource of the report. I looked into the Drupal Search Tables: https://www.drupal.org/node/2360879 but didn't manage to reproduce the contents of the report page.

Does anyone know how this data is curated and how I can export this data via mysql?

I'm using the default drupal search and Drupal v9.5.11.

Thanks in advance :)

# Answer
> 1 votes
A quick look at the codebase shows that this route is provided in `core/modules/dblog/dblog.routing.yml`. The route is controlled by `\Drupal\dblog\Controller\DbLogController::topLogMessages` with type `search`. So the complete query is:

```
    $header = [
      ['data' => $this->t('Count'), 'field' => 'count', 'sort' => 'desc'],
      ['data' => $this->t('Message'), 'field' => 'message'],
    ];
    $count_query = $this->database->select('watchdog');
    $count_query->addExpression('COUNT(DISTINCT([message]))');
    $count_query->condition('type', $type);

    $query = $this->database->select('watchdog', 'w')
      ->extend(PagerSelectExtender::class)
      ->extend(TableSortExtender::class);
    $query->addExpression('COUNT([wid])', 'count');
    $query = $query
      ->fields('w', ['message', 'variables'])
      ->condition('w.type', $type)
      ->groupBy('message')
      ->groupBy('variables')
      ->limit(30)
      ->orderByHeader($header);
    $query->setCountQuery($count_query);
    $result = $query->execute();

```

---
Tags: search
---


# Question
Title: Adding price values in webform with Twig
I'm using Drupal 10.2.4 with webform 6.2.2 I have a content type extras with a field\_prix

```
langcode: fr
status: true
dependencies:
  config:
    - field.storage.node.field_prix
    - node.type.extras
id: node.extras.field_prix
field_name: field_prix
entity_type: node
bundle: extras
label: Prix
description: ''
required: true
translatable: false
default_value: {  }
default_value_callback: ''
settings:
  min: null
  max: null
  prefix: ''
  suffix: €
field_type: decimal

```

i have a form with 2 fields : --extras for the end user to select the extras he wishes --prix\_extras to add up the prices of the selected extras with a calculated twig

```
    extras:
  '#type': entity_checkboxes
  '#title': 'Extras :'
  '#title_display': before
  '#target_type': node
  '#selection_handler': 'default:node'
  '#selection_settings':
    target_bundles:
      extras: extras
    sort:
      field: title
      direction: ASC
prix_extras:
  '#type': computed_twig
  '#title': 'Montant des Extras : '
  '#title_display': before
  '#template': |
    {# Initialize total price variable #}
    {% set total_price = 0 %}

    {# Get the raw price values of selected extras using webform_token() #}
    {% set raw_prix_extras = webform_token('[webform_submission:values:extras:entity:field_prix]', webform_submission, [], options) %}

    raw_prix_extras {{ raw_prix_extras }}<br>

    {# Check if raw prices of extras are not empty #}
    {% if raw_prix_extras is not empty %}
        {# Remove the currency symbol '€' and trim raw prices #}
        {% set cleaned_prices = raw_prix_extras|replace({'€': ''})|trim %}
        cleaned_prices {{ cleaned_prices }}<br>

        {# Split cleaned prices into an array #}
        {% set prices_array = cleaned_prices|split(',') %}
        prices_array {{ prices_array }}<br>

        {# Loop through prices array to sum up the total price #}
        {% for price in prices_array %}
            {% set total_price = total_price + price|replace({' ': ''})|number_format(0, '.', '') %}
        {% endfor %}
    {% endif %}

    total_price {{ total_price }} €
  '#whitespace': spaceless
  '#store': true
  '#ajax': true

```

I have 2 extras : A = 20€ and B = 10€ If i select one or the other it returns the right price If i select both it retuns only the price of A

how to you get calculated twig to loop through the extras and add up the prices of each ?

# Answer
> 1 votes
It seems that the issue lies in the way the prices are added to the total\_price variable. The prices are being concatenated as strings rather than being summed up as numbers. To correct this, we need to ensure that the prices are converted to numbers before adding them to total\_price.

```
{# Initialize total price variable #}
{% set total_price = 0 %}

{# Get the raw price values of selected extras using webform_token() #}
{% set raw_prix_extras = webform_token('[webform_submission:values:extras:entity:field_prix]', webform_submission, [], options) %}

raw_prix_extras {{ raw_prix_extras }}<br>

{# Check if raw prices of extras are not empty #}
{% if raw_prix_extras is not empty %}
    {# Remove the currency symbol '€' and trim raw prices #}
    {% set cleaned_prices = raw_prix_extras|replace({'€': ''})|trim %}
    cleaned_prices {{ cleaned_prices }}<br>

    {# Split cleaned prices into an array #}
    {% set prices_array = cleaned_prices|split(',') %}
    prices_array {{ prices_array }}<br>

    {# Loop through prices array to sum up the total price #}
    {% for price in prices_array %}
        {% set total_price = total_price + price|float %}
    {% endfor %}
{% endif %}

total_price {{ total_price }} €
{# Initialize total price variable #}
{% set total_price = 0 %}

{# Get the raw price values of selected extras using webform_token() #}
{% set raw_prix_extras = webform_token('[webform_submission:values:extras:entity:field_prix]', webform_submission, [], options) %}

raw_prix_extras {{ raw_prix_extras }}<br>

{# Check if raw prices of extras are not empty #}
{% if raw_prix_extras is not empty %}
    {# Remove the currency symbol '€' and trim raw prices #}
    {% set cleaned_prices = raw_prix_extras|replace({'€': ''})|trim %}
    cleaned_prices {{ cleaned_prices }}<br>

    {# Split cleaned prices into an array #}
    {% set prices_array = cleaned_prices|split(',') %}
    prices_array {{ prices_array }}<br>

    {# Loop through prices array to sum up the total price #}
    {% for price in prices_array %}
        {% set total_price = total_price + price|float %}
    {% endfor %}
{% endif %}

total_price {{ total_price }} €

```

In this adjusted code, price|float ensures that each price is treated as a float (number) before being added to total\_price. This should correctly sum up the prices as numbers.

let me know

---
Tags: webforms
---


title: Use token from parent entity

text:
# Question
Title: Use token from parent entity
In a drupal 10 site I have a content type called **article** with an entity reference field on it called "Related nodes". Those related nodes are of type **page**. On the page content type there is a wysiwy field with tokens formatting enabled.

How can I access tokens of the parent entity of type article within the wysiwyg field on node of type page that is referenced in the "Related nodes" field?

# Answer
You can access the entity reference fields by using the entity keyword in the token, assuming your field is called `related_nodes` it would be `[node:field_related_nodes:entity]`

You should be able to access any field on the related node by appending the field name, e.g. `[node:field_related_nodes:entity:field_name]`
> 0 votes

---
Tags: tokens, 10, entity
---


# Question
Title: How to produce GeoJSON from a set of Geofields without a single point error?
I'm getting an error from a geoJSON view

```
Exception: Cannot construct a LineString with a single point in LineString->__construct() (line 18 of /vendor/itamair/geophp/lib/geometry/LineString.class.php).

```

Edit - possibly this bug https://www.drupal.org/project/views\_geojson/issues/3332457

The purpose of the view is to list geoJSON from the content that matches the criteria. Each content item has a Geofield with a POLYGON() pasted into it

A view has been created.

The style plugin formatting is

The polygon field configuration is

This is a migration from drupal-7.

# Answer
The problem was caused by this bug https://www.drupal.org/project/views\_geojson/issues/3332457 and solved by patching the module.
> 0 votes

---
Tags: views
---