# Question
Title: Extended CKEditor 5 toolbar appears cropped when editing a section-block
Anytime I try to edit a Layout Builder section-block with an **expanded** CKEditor 5, the toolbar is cropped.

This is probably a bug and may have to do with Right to Left languages like Hebrew or Arabic, but how to cope with that anyway?

>

These CSS codes work in console but not from a CSS file.

```
#drupal-off-canvas-wrapper {
    width: 600px !important;
}

```

```
#drupal-off-canvas-wrapper {
    display: none !important;
}

```

This JavaScript code works in console but not from a JS file.

```
window.setInterval( () => {
    if (window.location.href.includes('layout')) {
        document.querySelector('#drupal-off-canvas-wrapper').style.width = "600px";
    }
}, 1);

```

How to solve this problem or at least how to get the window to always be broader as I have tried with the CSS and JS?

# Answer
> -1 votes
A workaround that solves this problem is running the following code with a user script manager (such as Greasemonkey or Tampermonkey).

```
// ==UserScript==
// @name         Drupal Layout Builder Broadening
// @match        https://DOMAIN_NAME.TLD/*

// ==/UserScript==

window.setInterval(()=>{
    if (window.location.href.includes('layout')) {
        document.querySelector('#drupal-off-canvas-wrapper').style.width = "600px";
    }
}, 1);

```

---
Tags: 10, layout-builder
---


# Question
Title: Mod rewrite enabled and working, urls contain index.php/
I have a strange issue: I have a drupal 8 instance on a subfolder in `/var/www`, I have enabled mod-rewrite in apache, I changed the `apache.config` file as in this post and the clean urls are working if I navigate directly to `/drupal/admin` for example.

I also added the `RewriteBase /drupal` in my .htaccess file.

The problem is that any link generated by drupal still contains the `/drupal/index.php/` part and I don't know how to get rid of that `/index.php` part.

I worked with Drupal 7 since it was launched but I never had this problem.

Is there a setting somewhere in db or in the config file where I should 'tell' drupal to use clean urls?

My server runs Apache 2.4.7 and PHP 5.5.

Thank you.

# Answer
> 0 votes
If you didn't append /index.php to the base URL (e.g. setting `$base_url` to http://example.com/index.php, in the settings.php file), then the rewrite rules in the Apache configuration files are wrongly adding /index.php to your links.
Check both of them, and you should find what is causing the wrong behavior.

# Answer
> 0 votes
I have had the same or similar problem with Drupal 10.1.x when logged in when running PHP (8.1.x) as a FPM application on Apache 2.2. i.e. index.php being prepended to url path despite mod\_rewrite being enabled. For me I was able to modify the .htaccess file and then after restarting the web service and clearing drupal cache, sometimes twice, with the following changed in my .htaccess.

```
- RewriteCond %{REQUEST_URI} !=/favicon.ico
+ RewriteCond %{REQUEST_URI} "!=/favicon.ico"

```

I have posted an issue here for this.

https://talk.plesk.com/threads/index-php-prepended-to-drupal-10-1-x-admin-paths-when-running-php-as-fpm-application-served-via-apache.372187/

---
Tags: 8, uri
---


# Question
Title: How can I programmatically stop webform from sending an email?
I need to stop sending my webform submission email programmatically and conditionally. By conditionally I mean I have two contact forms and two locales on my Drupal application. I have a custom configuration in the admin end based upon which I will be allowing/disallowing the webform submission emails only for the contact form and locale I choose at the backend configuration.

I have seen an answer at How to stop webform from sending an email that point me to do this in hook\_webform\_submission\_insert but my preference is do do it via a handler. I'm not able to comment on that answer as i don't have enough stackoverflow reputation.

I know in Drupal 7 we were able to do it by simply setting the flag $message\['send'\] = false; Is there a way to in a similar way in Drupal 10? This might be simple but I could not find a way around this. Please help.

# Answer
> 0 votes
You can use hook\_webform\_handler\_invoke\_alter() to Conditionally enable or disable a handler:

```
function Mymodulename_webform_handler_invoke_alter(\Drupal\webform\Plugin\WebformHandlerInterface $handler, $method_name, array &$args) {
  $webform = $handler->getWebform();
  $webform_id = $handler->getWebform()->id();
  $handler_id = $handler->getHandlerId();
  if($webform_id == 'webform_machine_name' && $handler_id == 'handler_machine_name'){
     // Add logic here to disable webform handler programatically
      $operation = 'disable';
      // call disable() function
      $handler->$operation();
      // Save the webform.
      $webform->save();
  }
}

```

Note: Make sure clear cache & check email handler list of webform whose email handler you want to disable , you 'll see email handler 'll disble for eg: /admin/structure/webform/manage/contact/handlers

For more documentation you can check here

---
Tags: webforms, emails, 10
---


# Question
Title: How do I inject a dateFormatter servide into a service class named MyService?
I have a service class declared like this:

```
 class MyService implements MyServiceInterface {

```

I want to get rid of a (working) call to a the `static \Drupal::service('date.formatter')` function and replace with a injected call to `$this->dateFormatter`.

I am looking at the most upvoted answer to this question: Make a custom date formatter for view.

It suggests that you can output a custom formatted timestamp like this:

```
$now = \Drupal::time()->getCurrentTime();
$currenttime = $this->dateFormatter->format($now, 'custom', 'Y-m-d H:i');

```

However, this does not work for me. It uses an injected call to the public function DateFormatter::format, and the upvoted answer does not explain how to set up the class where it is used to inject this service. This produces a WSOD on my site. The cause is obviously that `dateFormatter` has not been initialized.

As noted, I know that *using* a static call works:

```
$now = \Drupal::time()->getCurrentTime();
$currenttime = \Drupal::service('date.formatter')->format($now, 'custom', 'Y-m-d H:i');

```

I have a *rough* idea bout how to set up a service class to initialize an injected service. I.e. I *think* to be able to use it, I need to do at least three things:

1. Declare the injected service as an argument in `myservice.services.yml`.
2. Declare the injected property as a `$protected` variable.
3. Initialize it in the class' contructor.

But I am not even sure if this is correct. And the details eludes me. For example: How do I discover what name to include in `myservice.services.yml`?

Any guidance will be appreciated.

PS: I have studied this answer: How do I inject services in a service, but I don't understand how it applies to my question.

It has been suggested that Inject a class as dependecy injection in a service is a duplicate. The accepted answer to that question is *not* about the `@date.formatter` service that is the subject of my question, and it does not mention using `autowire` to solve the problem. (Which I learned how to use in the answer I now have accepted.)

# Answer
> 5 votes
*But I am not even sure if this is correct. And the details eludes me. For example: How do I discover what name to include in myservice.services.yml?*

Now that Drupal 9 is end of life you no longer need to do that. Replace the argument list with the autowire option:

*mymodule.services.yml*

```
services:
  mymodule.my_service:
    class: Drupal\mymodule\MyService
    autowire: true

```

and in the service class:

```
  /**
   * The date formatter.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * Constructs \Drupal\mymodule\MyService
   *
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter.
   */
  public function __construct(DateFormatterInterface $date_formatter) {
    $this->dateFormatter = $date_formatter;
  }

```

So to discover the service you only need the interface DateFormatterInterface. Use autocomplete and the IDE will automatically add a use statement at the top:

```
use Drupal\Core\Datetime\DateFormatterInterface;

```

See the change record: Core services provide aliases for autowiring

---
Tags: dependency-injection
---


title: Commerce module can't be enabled

text:
# Question
Title: Commerce module can't be enabled
I have installed the Commerce module but when I want to enable it, it does not give me the opportunity to check the checkbox, do you know how I can solve it?

# Answer
> 1 votes
**Manually**

If you install the module manually then module dependencies are not getting installed automatically. Some required dependent modules might be missing. If you add these dependent missing modules manually then it works.

**Using composer**

If you install the module using composer then that module is installed with their dependencies, and there is no need to manually install the dependency modules.

For best practices use composer for module installation.

Refer to this documentation for the installation of the commerce module : https://docs.drupalcommerce.org/commerce2/developer-guide/install-update/installation

Also refer to this document for installing modules using composer: https://modulesunraveled.com/drupal-8-composer-and-configuration-management/installing-and-uninstalling-modules-composer

---
Tags: commerce
---


# Question
Title: How to use 'required' and 'optional' states with form api when using a select field?
I'm trying to create a form in Drupal 10 that will show an field that is both visible and required depending on the selection of a radio input that comes before it. The visible state seems to work well but for some reason the required and/or optional states do not seem to work on select fields.

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $form['field_1'] = [
    '#type' => 'radios',
    '#title' => $this->t('Field 1'),
    '#options' => [
        'one' => $this->t('One'),
        'two' => $this->t('Two')
      ],
      '#required' => TRUE,
  ];

  // The field will become invisible but is still required.
  $form['field_2'] = [
      '#type' => 'select',
      '#title' => $this->t('Field 2'),
      '#options' => [
        'A' => $this->t('A'),
        'B' => $this->t('B'),
        'C' => $this->t('C'),
        'D' => $this->t('D'),
      ],
      '#required' => true,
      '#states' => [
        'visible' => [
          ':input[name="field_1"]' => ['value' => 'two']
        ],
        'optional' => [
          ':input[name="field_1"]' => ['value' => 'one']
        ],
      ],
    ];

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

  return $form;
}

```

When inspecting the HTML you can see that the code for the select is invisible but the required attribute is still present so when you hit submit the form will throw an error. This only happens for select field types as changing the type to textfield/radios seems to work without issues.

# Answer
You have to tweak code like this:

```
  $form['field_2'] = [
        '#type' => 'select',
        '#title' => $this->t('Field 2'),
        '#options' => [
          'A' => $this->t('A'),
          'B' => $this->t('B'),
          'C' => $this->t('C'),
          'D' => $this->t('D'),
        ],
        '#states' => [
          'visible' => [
            ':input[name="field_1"]' => ['value' => 'two']
          ],
          'required' => [
            ':input[name="field_1"]' => ['value' => 'two']
          ],
        ],
  ];

```

I passed the required attribute inside state properly & removed the required attribute from the field definition

Note: Basically if you want to attach the required attribute to field w.r.t to Form state then you should attach with state property, if attach outside the state property then it 'll always bind to form element & 'll always fire

Additional Info: Since states are driven by JavaScript only, it is important to understand that all states are applied on presentation only, none of the states force any server-side logic, and that they will not be applied for site visitors without JavaScript support
> 0 votes

---
Tags: forms, 10
---


title: How to get translated menu link entity

text:
# Question
Title: How to get translated menu link entity
I have a headless Drupal 9 solution and I'm currently working on i18n of the whole site.

I've managed to do everything except menus. The content translation core module is installed and setup correctly. I have all the menu items translated. This a snippet of the code:

```
  $parameters = new MenuTreeParameters();
  $parameters->onlyEnabledLinks();

  // Get drupal menu tree.
  $menu_tree = \Drupal::menuTree();

  // Load the menu tree.
  $main_menu_tree = $menu_tree->load('main', $parameters);

```

...

```
$manipulators = [
  ['callable' => 'menu.default_tree_manipulators:checkNodeAccess'],
  ['callable' => 'menu.default_tree_manipulators:checkAccess'],
  ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
];

$tree = $menu_tree->transform($main_menu_tree, $manipulators);

```

...

```
  foreach ($tree as $key => $menu_tree_element) {
    $menu_object = $this->generateSingleMenuObject($menu_tree_element, $max_depth);

    array_push($menu_array, $menu_object);
  }

```

The 'generateSingleMenuObject' function is where I'd expect to somehow get the objects in a certain language. Here's how the function starts

```
// Get link from menu tree element.
$menu_tree_element_link = $menu_tree_element->link;

// Get url object from link.
$menu_url_object = $menu_tree_element_link->getUrlObject();

// Create dummy object for storing data.
$menu_object = new stdClass();

// Get id and label.
$menu_object->id = $menu_tree_element_link->getDerivativeId();
$menu_object->label = $menu_tree_element_link->getTitle();

// Get href.
$menu_object->href = $menu_url_object->toString();

```

I've tried some of the standard options that worked on other entities but without luck.

This is basically the same question as this one.

The only thing I need is the translated menu label. What am I missing? This really sounds like it should be a relatively simple ask. Thank you!

# Answer
> 0 votes
I managed to solve this issue with the following code:

```
if ($lang) {
  $entity = \Drupal::service('entity.repository')
    ->loadEntityByUuid('menu_link_content', $menu_tree_element_link->getDerivativeId());

  if ($entity->hasTranslation($lang)) {
    $translation = $entity->getTranslation($lang);
    $link_override = $translation->get('link_override')->first();
    if ($link_override) {
      $menu_object->href = $link_override->getUrl()->toString();
    }
    $menu_object->label = $translation->getTitle();
  }
  else {
    $menu_object->label = $menu_tree_element_link->getTitle();
  }
}
else {
  $menu_object->label = $menu_tree_element_link->getTitle();
}

```

Basically loading the `menu_link_content` entity by Uuid from the `menu tree element link`. Then checking if the entity has a translation and if so populating the fields from the translated entity.

# Answer
> 0 votes
It seems like you're building a custom solution to generate menu items for a headless Drupal site, and you're encountering difficulties with retrieving translated menu labels. In Drupal 9, using the right services and methods is crucial to achieving accurate translations. To get the translated menu labels for each language, you can follow these steps:

1. **Use the Translation Manager:** The `MenuLinkManagerInterface` provides a method to load menu links with translations. Using the `MenuLinkManagerInterface::loadLinks()` method with the appropriate parameters, you can load translated menu links.
2. **Loop Through Translated Links:** Once you have the translated menu links, you can loop through them and extract the translated label for each link. This ensures that you get the labels in the correct language.

Here's how you can modify your code to achieve this:

```
use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MyMenuService {

  protected $menuLinkManager;

  public function __construct(MenuLinkManagerInterface $menuLinkManager) {
    $this->menuLinkManager = $menuLinkManager;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('menu.link_manager')
    );
  }

  public function generateMenu() {
    $parameters = new MenuTreeParameters();
    $parameters->onlyEnabledLinks();

    // Load the menu tree.
    $main_menu_tree = $this->menuLinkManager->loadLinks('main', $parameters);

    // Add your manipulators and transform the tree.
    // ...

    $menu_array = [];

    foreach ($tree as $key => $menu_tree_element) {
      $menu_object = $this->generateSingleMenuObject($menu_tree_element, $max_depth);

      array_push($menu_array, $menu_object);
    }

    // ...
  }

  protected function generateSingleMenuObject($menu_tree_element, $max_depth) {
    // ... your existing code ...

    // Load the translated link.
    $translated_menu_tree_element_link = $this->menuLinkManager->loadLink($menu_tree_element->link->getPluginId(), $menu_tree_element->link->getMenuName(), $menu_tree_element->link->getPluginDefinition());

    // Get the translated title.
    $translated_label = $translated_menu_tree_element_link->getTitle();

    // Set the translated label in the menu object.
    $menu_object->label = $translated_label;

    // ... rest of your code ...
  }
}

```

By using the `MenuLinkManagerInterface` methods to load and handle menu links, you ensure that you get the translated menu labels for each language. This approach should work well with your headless Drupal solution. Just make sure you have the necessary dependency injections set up and the right services used in your class.

---
Tags: i18n-l10n, navigation
---


# Question
Title: Register an object with the Service Container and give it a setRequest() (get base url)
I'm looking for a way to get the hostname of a multisite, and I've found several answers about it.

One of the solutions was to use: Answer link

```
$host= \Drupal::request()->getHost();

```

or

```
\Drupal::request()->getSchemeAndHttpHost();

```

Per also a user comments that the use of the Request object can be dangerous, as mentioned in the following link.

The comment warning say: Url to documentation

> Note: The use of this wrapper in particular is especially discouraged. Most code should not need to access the request directly. Doing so means it will only function when handling an HTTP request, and will require special modification or wrapping when run from a command line tool, from certain queue processors, or from automated tests.
>
> If code must access the request, it is considerably better to register an object with the Service Container and give it a setRequest() method that is configured to run when the service is created. That way, the correct request object can always be provided by the container and the service can still be unit tested.
>
> If this method must be used, never save the request object that is returned. Doing so may lead to inconsistencies as the request object is volatile and may change at various times, such as during a subrequest.

I have a custom module and I have a service, is it possible to implement it in a service?

My question is according to the comment and recommendation of the API, how is it that it should be implemented?

Thanks.

# Answer
> 1 votes
Here's an example (extracted from real code I just wrote in for Drupal 10.1) of getting the current request from the `request_stack` service in a plugin. Another service would just be wired into your `module.services.yml` instead of using the `create()` method:

```
<?php

namespace Drupal\my_module\Plugin\MyPlugin;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

class MyPlugin extends implements ContainerFactoryPluginInterface {

  /**
   * Resoruce Manager service.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * {@inheritdoc}
   */
  public function __construct(RequestStack $requestStack,
                              array $configuration,
                              $plugin_id,
                              $plugin_definition) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->requestStack = $requestStack;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $container->get('request_stack'),
      $configuration,
      $plugin_id,
      $plugin_definition
    );
  }

  function doSomething() {
    $request = $this->requestStack->getCurrentRequest();
    ...
  }

}

```

And here's the Symfony documentation that basically says the same thing.

---
Tags: 8, uri
---


# Question
Title: How can I display site logo, name and slogan?
how can i show site logo, name and slogan Separately in custom area in my site theme, I now use this code to display theme, buts this code don't allow me to edit each of them Separately.

```
{{ page.header }}

```

# Answer
```
function mytheme_preprocess_page(&$variables) {
  $site_config = \Drupal::config('system.site');
  $variables['site_name'] = $site_config->get('name');
  $variables['site_slogan'] = $site_config->get('slogan');

  // logo needs to be placed within specified folder
  $variables['logopath'] = file_url_transform_relative(file_create_url(theme_get_setting('logo.url')));

}

```

Then in `page.html.twig` you can use variables `site_name` and `site_slogan` as follows:

```
{{ site_name }}
{{ site_slogan }}

```

and for the logo:

```
<img src="{{ logopath }}" />

```

note: logo image file will need to be available in your current theme's root folder (or subfolder of your choice).
> 13 votes

# Answer
If you use `{{ page.header }}` to get the site logo and name, then you have a *branding block* in the region `header`.

To change how this block is rendered, you can copy the twig into your theme template folder and change the markup:

**block--system-branding-block.html.twig**

```
{% extends "block.html.twig" %}
{#
/**
 * @file
 * Theme override for a branding block.
 *
 * Each branding element variable (logo, name, slogan) is only available if
 * enabled in the block configuration.
 *
 * Available variables:
 * - site_logo: Logo for site as defined in Appearance or theme settings.
 * - site_name: Name for site as defined in Site information settings.
 * - site_slogan: Slogan for site as defined in Site information settings.
 */
#}
{% block content %}
  {% if site_logo %}
    <a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">
      <img src="{{ site_logo }}" alt="{{ 'Home'|t }}" />
    </a>
  {% endif %}
  {% if site_name %}
    <a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">{{ site_name }}</a>
  {% endif %}
  {{ site_slogan }}
{% endblock %}

```
> 6 votes

# Answer
If the logo is provided by the custom theme, I will simply use in my twig:

`<img src="{{ directory ~ '/logo.svg' }}" width="220px" />`

`directory` will lead to the current theme path instead of hooking.
> 3 votes

# Answer
`theme_get_setting('logo.url')` was the best option for me as `\Drupal::theme()->getActiveTheme()->getLogo()` doesn't return the right file name. I've got the default file name logo.svg instead.

I'm using a subtheme of Bootstrap barrio 5.1.4.

Figuring out in `getActiveTheme()` method : in my case `$theme->info['logo']` returns `NULL`
> 3 votes

# Answer
You can also get the active theme's logo path by using the theme manager service.

```
\Drupal::theme()->getActiveTheme()->getLogo().

```
> 2 votes

# Answer
Add as separate blocks configured to only display the required item for which there is a checkbox to do so.
> 1 votes

# Answer
It works on Drupal 9.

```
$host = \Drupal::request()->getSchemeAndHttpHost();
// Get a setting from theme.
$logo_url = \Drupal::theme()->getActiveTheme()->getLogo();
$logo = $host .'/'. $logo_url;

```
> 0 votes

# Answer
**Example for Drupal 10 get URL logo**

for file .theme add next lines

```
function theme_preprocess(&$variables) {
 // Get the admin logo path from the theme settings.
 $path_logo_admin = theme_get_setting('logo.url');
 // Pass the path of the admin logo to the template.
 $variables['logo_path'] = $path_logo_admin;
};

```

for twig file

```
<img class="text-white mr-3 logo" src="{{ logo_path }}" alt="Description" >

```
> 0 votes

---
Tags: 8, theming
---


# Question
Title: Custom field type - cardinality unlimited - multi column - radios to select default/primary
I created a custom field for the CRM project to handle telephone numbers. It has multiple properties. I am having trouble getting primary to work; I want to be able to mark one of the telephone numbers as primary.

The CRMTelephoneWidget displays a radio as the primary property, and the value is saved. Still, more than one item can be primary because each has a different form name.

```
$element['primary'] = [
  '#type' => 'radios',
  '#options' => [$delta => $this->t('Primary')],
  '#title' => $this->t('Primary'),
  '#default_value' => $items[$delta]->primary ?? NULL,
];

```

I manually set the form name, as follows. Only one radio can be selected, but the value is not saved.

```
$element['primary'] = [
  '#type' => 'radios',
  '#options' => [$delta => $this->t('Primary')],
  '#title' => $this->t('Primary'),
  '#default_value' => $items[$delta]->primary ?? NULL,
  '#attributes' => ['name' => 'telephones[primary]'],
];

```

Any help or advice will be greatly appreciated!

| Name | Type | Example |
| --- | --- | --- |
| Phone | string | 555-555-5555 |
| Extension | string | 123 |
| Type | string | phone, fax, mobile (entity reference to config) |
| Location | string | home, work, billing (entity reference to config) |
| Primary | boolean |  |
| Mobile Provider | string | t\_mobile |

# Answer
This is the interesting part of `massageFormValues`. I can pull the primary value from the user input.

```
/**
 * {@inheritdoc}
 */
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
  $primary = 0;
  foreach($values as $delta => $value) {
    if (isset($value['primary'])) {
      $primary = $value['primary'];
    }
  }
  foreach ($values as $delta => $value) {
    $values[$delta]['primary'] = FALSE;
    if ($values[$delta]['_original_delta'] == $primary) {
      $values[$delta]['primary'] = TRUE;
    }
  }
  return $values;
}

```

```
    $field_name = $this->fieldDefinition->getName();
    $element['primary'] = [
      '#type' => 'radio',
      '#return_value' => $delta,
      '#title' => $this->t('Primary'),
      '#default_value' => $items[$delta]->primary ? $delta : NULL,
      '#attributes' => [
        'id' => $field_name . '-primary-' . $delta,
      ],
      '#parents' => [$field_name, 0, 'primary'],
    ];

```
> 2 votes

---
Tags: 10
---


# Question
Title: How to restrict access to some nodes based on roles or users?
I am using Drupal 8 and I am a little bit confused that there is no core functionality to restrict the access to some nodes based on roles or users.

I found PageAccess, which is marked as unsecure and ACL/Access Control which are both dev and not working on my system.

Isn't there any option to do so? I need the private sector on my site and can't believe there is no way in Drupal.

Hope you can help me, because if not I have to redo the whole site with another wcms.

# Answer
> 4 votes
The Group module is what you should be looking at.

It creates groups as entities, making them fully fieldable, extensible and exportable. For this specific question, you'd enable the `gnode` submodule, and for each group type you would define the appropriate permissions (view, edit, delete, etc) for the various Content Types.

For the *private sector* (as in your question), it seems that you would want to grant access to what, in Group, is called "Members". But you wouldn't allow access to that part of the website for:

* "Outsiders" (= logged in users who are not a member of a group).
* "Anonymous" (site visitors that are not logged it).

# More info

# Resources

# Answer
> 3 votes
Try using the Group module.

> The Group module allows you to create arbitrary collections of your content and users on your site and grant access control permissions on those collections

It has a release candidate published, so it should be somewhat stable and an initial 1.x should be coming soon because it is actively maintained. Over 4,000 sites are using this module.

# Answer
> 3 votes
There is the Access by Entity module that can do this.

https://www.drupal.org/project/access\_by\_entity

There is also Permissions by Term.

https://www.drupal.org/project/permissions\_by\_term

There is also Taxonomy Access Control Lite.

https://www.drupal.org/project/tac\_lite

# Answer
> 1 votes
If all you want to do is control access to nodes or content types based roles one of the most straight forward modules is node view permissions

If you want to do anything fancier, like your own forums or groups of content editors etc then group as discussed by @Pierre.Vriens is hard to go past.

# Answer
> 1 votes
We can use **Node View Permissions** module to achieve the requirement. Try this, hope it helps.

# Answer
> 1 votes
This is a few years old but I thought I would throw in an answer on how to do this with a very light weight custom module. This answer would be applicable to Drupal 8, 9, and 10.

> I am using Drupal 8 and I am a little bit confused that there is no core functionality to restrict the access to some nodes based on roles or users.

Yes, welcome to the world of Drupal! Drupal doesn't have an out of the box UI for restricting access to nodes based on roles.

> I found PageAccess, which is marked as unsecure and ACL/Access Control which are both dev and not working on my system.

No comment on these modules. I find contributed modules end up giving you more than you need. If you are not comfortable with coding than a good module that does what you want is encouraged.

> Isn't there any option to do so? I need the private sector on my site and can't believe there is no way in Drupal.
>
> Hope you can help me, because if not I have to redo the whole site with another wcms.

You have likely found a solution that works for you but for someone looking in the future here is how you can do it with a custom module.

1. Name and place your module
2. Let Drupal know about it
3. Create a .module file

## Create a .module file

Within your custom module root folder, the same place your `.info` file is, create a new file with your module name ending with `.module`. i.e. `custom-module/custom-module.module`)

Within that file add the following code:

```
<?php

/**
 * @file
 * Contains custom_module.module
 */

// Allows you to load the node's info
use Drupal\node\NodeInterface;
// Allows you to load and change access attributes
use Drupal\Core\Access\AccessResult;

/**
 * Implements hook_ENTITY_TYPE_access().
 */
function custom_module_node_access(NodeInterface $node, $op, AccountInterface $account) {
    /**
     * The $node argument can be either a $node object or a machine name of
     * node's content type. It is called multiple times during a page load, so
     * it is enough if you perform the check once you get the object.
     *
     * If $node is an object, is a custom_content_type, and the operation is
     * view get the role continue processing or return access neutral. If the
     * current user does not have the paid_user role and the node is published
     * return access forbidden.
     */
    if (is_object($node) && $node->getType() == 'custom_content_type' && $op == 'view' ) {
        // Get the roles of the current user.
        $roles = \Drupal::currentUser()->getRoles();
        // If the current user does not have the paid_user role deny access.
        if (!in_array('paid_user', $roles))  {
            return AccessResult::forbidden();
        }

    }
    // Return a neutral opinion otherwise.
    return AccessResult::neutral();
}

```

About the code... The comments in the code already explain quite a bit but there are a few things that I intentionally left out of the comments as they aren't really comment worthy.

Drupal has a standard way of doing things. Either a node is a draft or published. Published for the most part means it is viewable by the public and draft means that it isn't. Using the hook\_ENTITY\_TYPE\_access() function I can change that functionality.

By checking if the node is an object it only triggers the code on the page once. Likely, you only want to limit viewer to a specific content type. That is why I am checking for `custom_content_type`. That would be replaced with the machine name of your content type. I am also want the `$op` or operation the be view to continue processing. These checks narrow down the scope to what access I want to affect.

The `return AccessResult::neutral();` at the end is best practice if there is no change to the access results.

---
Tags: 8, nodes
---


# Question
Title: How to prevent adding of duplicate item to Drupal Queue?
I am using Drupal Queue (Class `DrupalQueue`) to store items (a simple objects).

How can I check if there is already the same object in the queue before adding a new one ?

# Answer
I initially used the answer provided by George, to do a text search for the given queue item. However, I decided that this would often end up with more overhead than just skipping the queue altogether.

So in the end, I changed it so that each queue item does it's job, then uses a similar query to clear out any queue items that are duplicate to itself. This puts the heavy query into the queue processing.
> 2 votes

# Answer
You cannot find the previously entered values in the queue, since the `DrupalQueueInterface` interface doesn't expose a method to retrieve a previously added value. You cannot even rely on the fact the value is added in a database table, since that is an implementation detail that can change with the class actually implementing the queue, which can be easily changed from a module.

That is the reason why modules like the Aggregator module take their data from their own database table, where they record the last time they added those values in the queue. (See the comment that says *Add timestamp **to avoid queueing item more than once**.*)

```
  $result = db_query('SELECT * FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', array(
    ':time' => REQUEST_TIME,
    ':never' => AGGREGATOR_CLEAR_NEVER
  ));
  $queue = DrupalQueue::get('aggregator_feeds');
  foreach ($result as $feed) {
    if ($queue->createItem($feed)) {
      // Add timestamp to avoid queueing item more than once.
      db_update('aggregator_feed')
        ->fields(array('queued' => REQUEST_TIME))
        ->condition('fid', $feed->fid)
        ->execute();
    }
  }

  // Remove queued timestamp after 6 hours assuming the update has failed.
  db_update('aggregator_feed')
    ->fields(array('queued' => 0))
    ->condition('queued', REQUEST_TIME - (3600 * 6), '<')
    ->execute();

```

You could implement a queue class that checks the value has been already inserted, and use that as default queue class, but a module cannot rely on such implementation details.
> 1 votes

# Answer
**Michal**, Here is how I solved this for myself: prior to calling `createItem` I was making a DB request to `queue` table searching for a value in `data` field.

Here is a piece of code that is working for my site: function

```
__my_custom_queue_add_id_for_worker_achievements_guides_flags_updates ($uid) {
    // But 1st confirm that this user is not already scheduled for recalc
    if (!db_query( // Returns Queue ID if found
        'SELECT item_id  FROM {queue} WHERE name = :name AND data LIKE :nid LIMIT 1',
        array(
            ':name' => 'achievements_guides_flags_updates',
            ':nid' => '%"' . $uid . '%',
        )
    )->fetchField()) {
        $queue = DrupalQueue::get('achievements_guides_flags_updates');
        $queue->createItem($uid);
    }
}

```
> 0 votes

# Answer
Hi I stumbled upon this question looking for an answer myself, and my team and I came up with a viable, performant solution using static caching.

```
$queue_cache = &drupal_static($cache_name, []);
if (!empty($queue_cache[$entity->id()])) {
  return;
}

... Build your queue data here ...

$queue->createItem($data);
$queue_cache[$entity->id()] = TRUE;

```

What this does is it creates a static cache during runtime when queueing items. It will first check if the entity id exists, and if so, skips it. Otherwise, it queues it normally. No need for querying blobs in the queue table or anything like that.
> 0 votes

# Answer
Create a class (or you can put it in the .module file if you want):

```
/**
 * Custom queue implementation to merge on creation, preventing duplicates.
 *
 * See https://www.webomelette.com/overriding-queues-drupal-7-or-how-not-create-duplicate-queue-items
 */
class MergeQueue extends SystemQueue {

  /**
   * Overriding the method to make sure no duplicate queue items get created.
   */
  public function createItem($data) {

    $serialized = serialize($data);

    // Merge instead of insert to prevent duplicates. An item is updated if it
    // already exists.
    $query = db_merge('queue')
      ->key(array('name' => $this->name, 'data' => $serialized))
      ->fields(array(
        'name' => $this->name,
        'data' => $serialized,
        'created' => time(),
      ));
    return (bool) $query->execute();
  }

}

if (module_exists('queue_ui')) {
  /**
   * Support Queue UI inspection.
   */
  class QueueUIMergeQueue extends QueueUISystemQueue {}
}

```

And in the .install file:

```
/**
 * Implements hook_install().
 */
function my_module_install() {
  variable_set('queue_class_merge_queue', 'MergeQueue');
}

/**
 * Implements hook_uninstall().
 */
function my_module_uninstall() {
  variable_del('queue_class_merge_queue');
}

```

See https://www.webomelette.com/overriding-queues-drupal-7-or-how-not-create-duplicate-queue-items
> 0 votes

---
Tags: 7, queue
---


# Question
Title: How to make media description show on form view when used as entity reference
Drupal 9... I have a content type of "Resource" which uses a field "download" which references the media type "document", but when I upload a file to the field, it gives me no opportunity to enter a description for the newly uploaded file.

Resource content type Field\_download (entity reference to Media Type = Document)

Media Type: Document

* field\_description (text -- required)
* field\_media\_document (file -- required -- enabled description field)

1 - New Resource content type… upload the media file

2 - the media upload box appears

3 - Selected the file I want to upload - it is here that I want to enter the file's description. The help text even says "Fill in any required fields and save..." but no required field appears.

4 - Insert the media, now that it has been uploaded

5 - The new "Resource" node shows the new file, but still no opportunity to enter description

# Answer
> 0 votes
I had this same issue and found the solution:

> If you want to be able to add a new file with a description using Media library then visit /admin/structure/media/manage/document/form-display/media\_library and enable the "Document" field.

Source: https://www.drupal.org/forum/support/post-installation/2022-08-24/how-to-use-description-when-inlining-link-to-media-documents-d9#comment-14669785

---
Tags: entities, media, 9
---


# Question
Title: Edit index config (Search API) programmatically and get the status index updated
I have a site with 14 pieces of news and 44 basic pages.

1. I have created an index (Search API) with this bundle:

and this is the index status (the content is already indexed during cron):

2. When I edit the config, add the Basic page bundle and save it:

The index status is updated:

I want to do the part 2 programmatically. I tried two ways:

```
$index = Index::load('my_index');
$index->setOption('datasource_settings', [
  'entity:node' => [
    'bundles' => [
      'default' => 0,
      'selected' => ['news', 'page'],
      'languages' => [
        'default' => 1',
        'selected' => [ ],
      ],
    ]
  ],
]);
$index->save();

```

and

```
$datasource_settings = [
  'entity:node' => [
    'bundles' => [
      'default' => 0,
      'selected' => ['news', 'page'],
      'languages' => [
        'default' => 'TRUE',
        'selected' => [ ],
      ],
    ]
  ],
];
$search_index = \Drupal::configFactory()->getEditable('search_api.index.my_index');
$search_index->set('datasource_settings', $datasource_settings)->save();

```

The config is saved, but the status index is not updated:

I tried to use these codes:

Option 1:

```
$index = Index::load('my_index');
$index->reindex();

```

But the nodes number are not updated, and I lose the nodes indexed:

Option 2:

```
$index = Index::load('my_index');
$index->rebuildTracker();

```

Result:

Option 3:

```
$index = Index::load('my_index');
$index->clear();

```

Result:

So my question is: How to update an index config programmatically and get the index status updated like the UI does when you click the Save button. I tried to look inside the search\_api module code, but I got lost :(

Thank you in advance.

# Answer
You can update the configuration of the search index with the following code

```
use Drupal\search_api\Entity\Index;

$index = Index::load('my_index');
$datasources = $index->getDatasources();
foreach ($datasources as $datasource_id => $datasource) {
  if ($datasource_id == 'entity:node') {
    $configuration = $datasource->getConfiguration();
    // This will add the 'page' bundle to the configuration.
    $configuration['bundles']['selected'][] = 'page';
    $datasources[$datasource_id]->setConfiguration($configuration);
  }
}
$index->save();

```

After saving the index, automatically a batch process will be called, if the changes are submitted in a form. Otherwise you manually need to add the new items to the index or reindex the whole index. For manually adding the new items, you can for example use the following code

```
$tracker = $index->getTrackerInstance();
$entity_type_manager = \Drupal::entityTypeManager();
$node_storage = $entity_type_manager->getStorage('node');
// Get the IDs of the new items.
$query = $node_storage->getQuery();
$query->condition('type', 'page');
$new_ids = $query->execute();
$entities = $node_storage->loadMultiple($new_ids);
$content_entity_tracking_manager = \Drupal::service('search_api.entity_datasource.tracking_manager');
foreach ($entities as $entity) {
  // Index the newly added item.
  $content_entity_tracking_manager->entityInsert($entity);
}

```

This may only works if you just have a few hundred new nodes, because you otherwise will get a timeout. Thats the reason, why the indexing happens in the batch process.
> 2 votes

# Answer
To reindex items as it's done through the UI, you can do the following (but this *won't* queue the action so it can be super slow and you should avoid calling it inside a controller action for example):

```
$index = Index::load('my_index');
$index->reindex();

$datasource_ids = $index->getDatasourceIds();

foreach ($datasource_ids as $datasource_id) {
    // The method returns the number of indexed elements if needed.
    $index->indexItems(-1, $datasource_id);
}

```
> 0 votes

---
Tags: search, 9
---


# Question
Title: How can I have updated content entity data immediately available after update?
I created custom content entities to handle a small NGO membership (Member, Person, both linked to Drupal 'users').
I have a form allowing users to perform online membership application.
Submitting this form creates/updates these custom content entities.

My problem is that these changes to the content entities doesn't show until I clear all the caches (for example with UI: Administration \> Configuration \> Development \> Clear all caches.

In a previous version of my form, I had a `drupal_flush_all_caches()` that did the job, but it lead to other problems I could get rid of only removing `drupal_flush_all_caches()`.

How can I have the same result (immediate availability of entities updates) without using `drupal_flush_all_caches()`?

# Answer
> 0 votes
I solved my problem indirectly.
My code to create the content entities was using Database API, mainly

```
$database->merge('entity')
    ->insertFields($insertFields)
    ->updateFields($updateFields)
    ->key('id', someId)
    ->execute();

```

I changed it to use Entity API:

```
$storage = Drupal::entityTypeManager()->getStorage('entity');
$entity = $storage->load(someId);
$entity->someField = someValue;
$entity->save();

```

And Drupal does its magic, taking care of entities’ cache (in EntityBase.php, if I understood well).

# Answer
> 2 votes
It could be the way you reference the custom entity. If users reference the custom entity, the render cache will be invalidated when updating the references. If you reference backward, from the custom entity to the user entity, this does not happen. Then you need the cache metadata of the custom entity when you are rendering users and their membership status. If you also want to react to new custom entities that don't yet exist when rendering the user, you need the list tag of this entity type, as already suggested by @Clive:

```
function mymodule_preprocess_user(&$variables) {
  $variables['#cache']['tags'][] = 'my_custom_entity_list';
}

```

# Answer
> 1 votes
This is generic code that use to invalidate tags:

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

Cache::invalidateTags($node->getCacheTags());

```

Note: where $node denotes entity object whose tags needs to invalidate

if you know how cache tags maintained for your custom entity then you can directly pass the tags instead of getting by this: $node-\>getCacheTags()

---
Tags: entities, 9
---


# Question
Title: How can I set a custom project directory structure?
For Drupal 10 there's a recommended project structure (httpdocs/web, httpdocs/vendor) and a legacy structure (httpdocs, httpdocs/vendor). These are suitable for sites on shared hosts that provide SSH access only to a single server directory.

Provided you have full root access to the server, another option is to move the recommended structure one level up, while Apache still uses httpdocs as DocumentRoot. This separates Composer files from the website even more clearly.

```
domain/composer.json
domain/composer.lock
domain/httpdocs/...  (Drupal site)
domain/vendor/...

```

I used this with non-Drupal PHP projects, so Composer is basically fine with it. Now I wonder how to configure Drupal 10 in order to work with this structure, too. Moving the files obviously isn't enough, so what else is needed to make this work?

# Answer
> 1 votes
Please follow the guide how to install Drupal 10

`composer create-project drupal/recommended-project my_site_name_dir`

You need to keep this structure, the "project-root" will be at `my_site_name_dir` and your webserver must point to the "web-root" which will be at `my_site_name_dir/web` by default, AFAIS you want to change only the directory of the web-root which you can easily do by adjusting the composer.json drupal-scaffold, e.g

```
"extra": {
        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            }
        },

```

and adjust the installer\_paths accordingly

and make composer install

---
Tags: installation, 10
---


# Question
Title: Prepopulating a drop-down select box that references another entity
I have a node create form for content type "space" so that the URL looks like https://.../node/add/space.

In this page, there is a form with a drop-down select that corresponds to an entity reference field type to a "floor" content type.

I would like that value to be pre-populated from a URL parameter or similar and I was trying with the Entity Reference module. I added *\[current-page:query:floor\]* in the Entity Prepopulate value for the floor field and then tried to pass that parameter via URL as https://.../node/add/space?floor=floor 1.

That does not pre-populate the select box as I would have expected.

# Answer
> 0 votes
Just realized I needed to query the ID and not the actual value. Like "https://.../node/add/space?floor=1" or "https://.../node/add/space?floor=floor 2"

---
Tags: entities, forms
---


# Question
Title: Permissions to edit user field data, but not fields itself
How to allow a role to edit/manage user accounts e.g. click Edit and change email, username, password etc., but do not edit the fields itself, e.g. cannot just go to `Manage fields` and delete/create/edit fields?

Field permission doesn't do that, it's specifically just for each field per field.

Do not have access to `admin/config/people/accounts/fields` at all.

But they still can go to `admin/people` and update/manage users. So they still must have the `Administer users` permission

# Answer
> 1 votes
On Drupal 7, the permission to access admin/config/people/accounts is the same permission that allows to edit every account created on the site. The permission is returned by `user_entity_info()`, a `hook_entity_info()` implementation. Any module that implements `hook_entity_info_alter()`, including a custom module, can alter what the User module returns in its hook implementation.

```
/**
 * Implements hook_entity_info_alter().
 */
function mymodule_entity_info_alter(&$entity_info) {
  $entity_info['user']['bundles']['user']['admin']['access arguments'] = 'a new permission defined from the module';
}

```

The module must then implement `hook_permission()` to define a new permission, keeping in mind that what I indicated with `'a new permission defined from the module'` is the new permission required to access *admin/config/people/accounts*.

# Answer
> 0 votes
Solved with Rules.

1. Action: Drupal is initializing
2. Condition: Text Comparison or Data Comparison, put in the URL path
3. Action: Page redirect.

---
Tags: 7, users
---


# Question
Title: How to access and change a form's display mode in hook_form_alter() or similar?
Is it possible to access and change a form's display mode in hook\_form\_alter()? I'd like to use some context to say "use this display mode, not the other one."

My specific use case is selecting a form display mode for a paragraph type nested (in multiple layers) inside one of several node forms. Based on details of the parent layers, I want to control which form display mode is used.

I've looked at `hook_field_widget_entity_reference_paragraphs_form_alter()` and `hook_entity_form_display_alter()` as well. While I could, it seems in principle, change the display in that last one, there's no information I could use to make the decision. The widget function doesn't seem to provide anything that looks potentially useful.

I would expect some sort of connection from either the `$form` or `$form_state` in `hook_form_alter()` to the display being used, but can't find one. Either I haven't dug down the right rabbit hole, or that connection doesn't exist there, and I need to look at some other processing step, but don't know which.

# Answer
> 0 votes
There ought to be a method to get this analogous to `$form_state->getFormObject()->getOperation()` but I am not aware of one. You can fallback to getting the form display mode from the query string in the URL:

`$form_display = \Drupal::request()->get('display');`

This would not allow changing the form mode.

---
Tags: 8, hooks
---


# Question
Title: Fatal error: concerning DrushStyle::warning not being compatible with SymfonyStyle::warning
I just upgraded our site from Drupal 9.5.9 to Drupal 10.1 (following instructions from here - https://www.drupal.org/docs/upgrading-drupal/upgrading-from-drupal-8-or-later/upgrading-a-composer-based-site).

Upon launching the site right after I received these errors

```
The website encountered an unexpected error. Please try again later.

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "node_type" plugin does not exist. Valid plugin IDs for Drupal\rules\Core\ConditionManager are: gtag_domain, gtag_language, language, rules_entity_is_of_type, rules_entity_field_access, rules_entity_is_of_bundle, rules_ip_is_banned, rules_list_count_is, rules_path_has_alias, rules_user_has_role, rules_data_comparison, rules_node_is_of_type, rules_entity_has_field, rules_user_is_blocked, rules_text_comparison, rules_entity_is_new, rules_node_is_promoted, rules_path_alias_exists, rules_node_is_published, rules_list_contains, rules_data_is_empty, rules_node_is_sticky, current_theme, request_path, user_role, webform, entity_bundle:block_content, entity_bundle:crop, entity_bundle:entity_subqueue, entity_bundle:media, entity_bundle:node, entity_bundle:redirect, entity_bundle:shortcut, entity_bundle:taxonomy_term, entity_bundle:webform_submission, entity_bundle:menu_link_content, entity_bundle:paragraph in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 53 of core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).

```

I recognize that this error (and similar issues) have been reported on this forum and I have tried all the suggested fixes but it still reports failures. Here's what I have tried.

I understand the error is b/c `node_type` is deprecated and removed in Drupal 10, and instead it should be replaced with `entity_bundle:node`. So I exported all my configuration from the upgraded env (using drush config-export). I found two .yml configuration files that were using `node_type` in its conditions. I started by replacing just one of those two files as below

**BEFORE**

```
...
conditions:
  node_type:
    id: node_type
...

```

**AFTER**

```
...
conditions:
  'entity_bundle:node':
    id: 'entity_bundle:node'
...

```

Cleared the cache and tried to import just this updated config yml file (using `drush config-import --partial <path_to_dir_w_updated_config`) as a test to see if the change might help resolve the initial errors. But I received the below error on running the config-import

```
+------------+--------------------------+-----------+
| Collection | Config                   | Operation |
+------------+--------------------------+-----------+
|            | asset_injector.css.media | Update    |
+------------+--------------------------+-----------+
PHP Fatal error:  Declaration of Drush\Style\DrushStyle::warning(array|string $message) must be compatible with Symfony\Component\Console\Style\SymfonyStyle::warning($message) in <site_root>/vendor/drush/drush/src-symfony-compatibility/v6/Style/DrushStyle.php on line 35

```

I am not sure what is causing the valid plugin type of entity\_bundle:node to not be accepted. Any help is appreciated.

Here are my Symfony and Drush version info at present -

```
% composer show | grep symfony
symfony/console                           v5.4.3
symfony/dependency-injection              v6.0.3
symfony/deprecation-contracts             v3.0.0
symfony/error-handler                     v6.0.3
symfony/event-dispatcher                  v6.0.3
symfony/event-dispatcher-contracts        v3.0.0
symfony/filesystem                        v6.3.1
symfony/finder                            v6.3.3
symfony/http-foundation                   v6.0.3
symfony/http-kernel                       v6.0.4
symfony/mime                              v6.0.3
symfony/polyfill-ctype                    v1.24.0
symfony/polyfill-iconv                    v1.24.0
symfony/polyfill-intl-grapheme            v1.24.0
symfony/polyfill-intl-idn                 v1.24.0
symfony/polyfill-intl-normalizer          v1.24.0
symfony/polyfill-mbstring                 v1.24.0
symfony/polyfill-php72                    v1.27.0
symfony/polyfill-php73                    v1.27.0
symfony/polyfill-php80                    v1.24.0
symfony/polyfill-php81                    v1.24.0
symfony/process                           v6.0.3
symfony/psr-http-message-bridge           v2.1.2
symfony/routing                           v6.0.3
symfony/serializer                        v6.0.3
symfony/service-contracts                 v3.0.0
symfony/string                            v6.0.3
symfony/translation-contracts             v3.0.0
symfony/validator                         v6.0.3
symfony/var-dumper                        v6.0.3
symfony/yaml                              v6.0.3

% composer show | grep drush
drush/drush                               11.6.0

```

**Edit - My composer.json**

```
{
    "name": "pantheon-upstreams/drupal-project",
    "description": "Install Drupal 9 with Composer on Pantheon.",
    "type": "project",
    "license": "MIT",
    "dev notes": [
        "Entityqueue locked at 8.x-1.0-beta5 due to fatal error on /our-focus.",
        "switch_page_theme is on dev release for d9 compatibility"
    ],
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "path",
            "url": "upstream-configuration"
        }
    ],
    "require": {
        "chi-teck/drupal-code-generator": "^2.6",
        "drupal/admin_toolbar": "^3.3",
        "drupal/advagg": "^6.0@alpha",
        "drupal/asset_injector": "^2.16",
        "drupal/better_exposed_filters": "^6.0",
        "drupal/block_class": "^2.0",
        "drupal/block_field": "^1.0@RC",
        "drupal/captcha": "^1.9",
        "drupal/chosen": "^3.0",
        "drupal/color_field": "^3.0",
        "drupal/conditional_fields": "^4.0@alpha",
        "drupal/core-composer-scaffold": "^10",
        "drupal/core-project-message": "^10",
        "drupal/core-recommended": "^10",
        "drupal/crop": "^2.3",
        "drupal/ctools": "^3.13",
        "drupal/devel": "^5.1",
        "drupal/embed": "^1.6",
        "drupal/entity_reference_revisions": "^1.10",
        "drupal/entity_usage": "^2.0@beta",
        "drupal/entityqueue": "^1.6",
        "drupal/eu_cookie_compliance": "^1.24",
        "drupal/field_group": "^3.4",
        "drupal/filebrowser": "^3.1@RC",
        "drupal/flexslider": "2.x-dev@dev",
        "drupal/focal_point": "^2.0@alpha",
        "drupal/formblock": "^2.0@beta",
        "drupal/google_analytics": "^4.0",
        "drupal/google_tag": "^1.6",
        "drupal/imce": "^3.0",
        "drupal/jquery_ui": "^1.6",
        "drupal/jquery_ui_accordion": "^2.0",
        "drupal/jquery_ui_datepicker": "^2.0",
        "drupal/jquery_ui_slider": "^2.0.0",
        "drupal/jquery_ui_touch_punch": "^1.0",
        "drupal/language_switcher_extended": "^1.1",
        "drupal/libraries": "^4.0",
        "drupal/menu_link_attributes": "^1.3",
        "drupal/metatag": "^1.22",
        "drupal/node_revision_delete": "^2.0@alpha",
        "drupal/pantheon_advanced_page_cache": "^2.1",
        "drupal/paragraphs": "^1.15",
        "drupal/pathauto": "^1.11",
        "drupal/permissions_by_term": "^3.1",
        "drupal/quick_node_clone": "^1.16",
        "drupal/recaptcha": "^3.1",
        "drupal/redirect": "^1.8",
        "drupal/redirect_after_login": "2.x-dev@dev",
        "drupal/redis": "^1.6",
        "drupal/registration_role": "^2.0",
        "drupal/rules": "3.x-dev@dev",
        "drupal/search404": "^2.1",
        "drupal/smart_trim": "^2.0",
        "drupal/smtp": "^1.2",
        "drupal/stable": "^2.0",
        "drupal/svg_formatter": "^2.0",
        "drupal/switch_page_theme": "^4.0",
        "drupal/tac_lite": "1.x-dev@dev",
        "drupal/taxonomy_multidelete_terms": "^1.3",
        "drupal/token": "^1.11",
        "drupal/toolbar_menu": "^3.0",
        "drupal/twig_field_value": "^2.0",
        "drupal/twig_tweak": "^3.2",
        "drupal/typed_data": "^1.0@beta",
        "drupal/upgrade_status": "^4.0",
        "drupal/url_embed": "^2.0@alpha",
        "drupal/video_embed_field": "^2.5",
        "drupal/views_conditional": "^1.5",
        "drupal/views_field_view": "^1.0@beta",
        "drupal/views_infinite_scroll": "^2.0",
        "drupal/views_slideshow": "^5.0",
        "drupal/viewsreference": "^2.0@beta",
        "drupal/webform": "^6.2@beta",
        "drupal/webp": "^1.0@beta",
        "drupal/xmlsitemap": "^1.4",
        "drupal/zurb_foundation": "^9.0@beta",
        "drush/drush": "^11.5",
        "mglaman/composer-drupal-lenient": "^1.0",
        "pantheon-upstreams/upstream-configuration": "*",
        "phpstan/extension-installer": "*",
        "topfloor/composer-cleanup-vcs-dirs": "^1.1"
    },
    "conflict": {
        "drupal/drupal": "*"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "extra": {
        "installer-paths": {
            "web/core": [
                "type:drupal-core"
            ],
            "web/libraries/{$name}": [
                "type:drupal-library"
            ],
            "web/modules/composer/{$name}": [
                "type:drupal-module"
            ],
            "web/profiles/composer/{$name}": [
                "type:drupal-profile"
            ],
            "web/themes/composer/{$name}": [
                "type:drupal-theme"
            ],
            "drush/Commands/contrib/{$name}": [
                "type:drupal-drush"
            ],
            "web/private/scripts/quicksilver/{$name}/": [
                "type:quicksilver-script"
            ]
        },
        "composer-exit-on-patch-failure": true,
        "patchLevel": {
            "drupal/core": "-p2"
        },
        "patches": {
            "drupal/better_exposed_filters": {
                "fix undefined array key '#options' error": "./patches/composer/better_exposed_filters/fix_bef_#1.patch"
            },
            "drupal/rules": {
              "additional fixes to module for D10 compatibility": "./patches/composer/rules/fix_rules_for_D10_compatability_#1.patch"
            },
            "drupal/taxonomy_multidelete_terms": {
              "additional fixes to module for D10 compatibility": "./patches/composer/taxonomy_multidelete_terms/fix_taxonomy_multidelete_terms_for_D10_compatability_#1.patch"
            },
            "drupal/flexslider": {
              "additional fixes to module for D10 compatibility": "./patches/composer/flexslider/fix_flexslider_for_D10_compatability_#1.patch",
              "additional fix 2 to module for D10 compatibility": "./patches/composer/flexslider/fix_flexslider_for_D10_compatability_#2.patch"
            }
        },
        "patches-ignore": {
          "drupal/redirect_after_login": {
            "Headers have already been sent after upgrade to Drupal 9.2 (can't login)": "https://www.drupal.org/files/issues/2021-06-20/3214949.patch"
          },
          "drupal/tac_lite": {
            "fix d9 error on permission rebuild": "https://www.drupal.org/files/issues/2021-05-28/Fix_D9.patch"
          }
        },
        "drupal-lenient": {
          "allowed-list": [
            "drupal/better_exposed_filters",
            "drupal/rules",
            "drupal/taxonomy_multidelete_terms",
            "drupal/flexslider"
          ]
        },
        "hooks": {
            "post-checkout": "composer install",
            "post-merge": "composer install"
        },
        "drupal-scaffold": {
            "allowed-packages": [
                "pantheon-systems/drupal-integrations"
            ],
            "locations": {
                "web-root": "./web"
            },
            "file-mapping": {
                "[project-root]/.editorconfig": false,
                "[project-root]/pantheon.upstream.yml": false,
                "[project-root]/.gitattributes": false
            }
        }
    },
    "scripts": {
        "git-hooks": "vendor/bin/cghooks add --ignore-lock"
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "platform": {
            "php": "8.1"
        },
        "allow-plugins": {
            "grasmash/drupal-security-warning": true,
            "zaporylie/composer-drupal-optimizations": true,
            "drupal/core-composer-scaffold": true,
            "cweagans/composer-patches": true,
            "composer/installers": true,
            "topfloor/composer-cleanup-vcs-dirs": true,
            "drupal/core-project-message": true,
            "phpstan/extension-installer": true,
            "mglaman/composer-drupal-lenient": true
        }
    },
    "require-dev": {
        "brainmaestro/composer-git-hooks": "^2.8",
        "grasmash/drupal-security-warning": "1.x-dev",
        "topfloor/composer-cleanup-vcs-dirs": "*"
    }
}

```

And this is the configuration (yml) file I was trying to `config-import` after making the change from `node_type` to `entity_bundle:node`

```
uuid: a4a66f36-3ba7-4444-8619-5a2c9e2affec
langcode: en
status: true
dependencies:
  module:
    - node
id: media
label: Media
code: |-
  iframe {
      border: 0;
      width: 400px;
  }

  section.content-area {
      padding: 20px;
      max-width: 1200px;
      margin: 0 auto;
  }
media: all
preprocess: true
conditions:
  'entity_bundle:node':
    id: 'entity_bundle:node'
    negate: false
    context_mapping:
      node: '@node.node_route_context:node'
    bundles:
      media: media
conditions_require_all: true
contexts: {  }

```

# Answer
> 0 votes
I also encountered this error after following instructions for upgrading from Drupal 9 to Drupal 10 on d.o.

With Drush 11 installed, I ran 'drush updb' and got the following:

```
PHP Fatal error:  Declaration of Drush\Style\DrushStyle::warning(array|string $message) must be compatible with Symfony\Component\Console\Style\SymfonyStyle::warning($message)

```

I found that installing drupal/core-recommended, as instructed on d.o., caused some Symfony packages to be locked to out-of-date versions, such as the symfony/console package which causes the incompatibility with Drush 11 that results in this error.

So I would advise to (composer) remove drupal/core-recommended and then (composer) require the latest version of Drupal 10 Core explicitly, and use the --with-all-dependencies option. Like:

composer require drupal/core:^10.1.5 --with-all-dependencies

I also had to remove Drush 11 before I could update to the latest version of drupal/core. Because Drush 11 was also locking some Drupal Core 10.1.5 dependency to an older version. So I removed Drush 11, then updated Drupal Core, then composer require'd Drush 11 again. This resolved the issue for me.

# Answer
> 0 votes
I will also join in on these answers. In my case, I had this issue locally with Lando on a Windows machine. I have excluded vendor and contrib modules and therefore they're only rebuilt when I explicitly call `lando rebuild`.

However despite doing this, lando did still have the old `vendor/drush/drush/src/Style/DrushStyle.php` inside the VM. I had to manually `lando destroy` (watch out, you'll lose the database) and then cleanly restart lando again to have it working just fine.

# Answer
> -1 votes
I was able to resolve this by deleting the vendor folder and my composer.lock file and then reinstall all of my dependencies.

```
rm -rf vendor/
rm composer.lock

```

and then

```
composer install

```

This process will download and install fresh copies of all the necessary components based on the specifications in your composer.json file. Once this is done, try running Drush again to see if the problem has been resolved.

---
Tags: drush, composer, plugins, upgrading, 10
---


# Question
Title: I am trying to upgrade and Composer is complaining. How do I figure out what the actual issue is and fix it?
I am trying to update my Drupal 9 site to Drupal 10. I installed the *Upgrade status* module (and removed it before trying to update); my site is good with the exception of updating the *Dynamic Entity Reference* module, which requires Drupal 10.

I followed the Upgrading a Composer-based site documentation but when I try to run `composer update`, I get these errors.

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - symfony-cmf/routing[1.4.0, ..., 1.4.1] require php ^5.3.9|^7.0 -> your php version (8.2.9) does not satisfy that requirement.
    - drupal/core[8.9.11, ..., 8.9.20] require php ^7.0.8 -> your php version (8.2.9) does not satisfy that requirement.
    - Root composer.json requires drupal/linkchecker ^1.1 -> satisfiable by drupal/linkchecker[1.1.0].
    - drupal/core-recommended 10.0.2 requires drupal/core 10.0.2 -> satisfiable by drupal/core[10.0.2].
    - Conclusion: don't install drupal/core 10.0.2 (conflict analysis result)
    - drupal/core-recommended 10.0.3 requires drupal/core 10.0.3 -> satisfiable by drupal/core[10.0.3].
    - Conclusion: don't install drupal/core 10.0.3 (conflict analysis result)
    - drupal/core-recommended 10.0.4 requires drupal/core 10.0.4 -> satisfiable by drupal/core[10.0.4].
    - Conclusion: don't install drupal/core 10.0.4 (conflict analysis result)
    - drupal/core-recommended 10.0.5 requires drupal/core 10.0.5 -> satisfiable by drupal/core[10.0.5].
    - Conclusion: don't install drupal/core 10.0.5 (conflict analysis result)
    - drupal/core-recommended 10.0.6 requires drupal/core 10.0.6 -> satisfiable by drupal/core[10.0.6].
    - Conclusion: don't install drupal/core 10.0.6 (conflict analysis result)
    - drupal/core-recommended 10.0.7 requires drupal/core 10.0.7 -> satisfiable by drupal/core[10.0.7].
    - Conclusion: don't install drupal/core 10.0.7 (conflict analysis result)
    - drupal/core-recommended 10.0.8 requires drupal/core 10.0.8 -> satisfiable by drupal/core[10.0.8].
    - Conclusion: don't install drupal/core 10.0.8 (conflict analysis result)
    - drupal/core-recommended 10.0.9 requires drupal/core 10.0.9 -> satisfiable by drupal/core[10.0.9].
    - Conclusion: don't install drupal/core 10.0.9 (conflict analysis result)
    - drupal/core-recommended 10.0.10 requires drupal/core 10.0.10 -> satisfiable by drupal/core[10.0.10].
    - Conclusion: don't install drupal/core 10.0.10 (conflict analysis result)
    - drupal/core-recommended 10.0.11 requires drupal/core 10.0.11 -> satisfiable by drupal/core[10.0.11].
    - Conclusion: don't install drupal/core 10.0.11 (conflict analysis result)
    - drupal/core-recommended 10.1.0 requires drupal/core 10.1.0 -> satisfiable by drupal/core[10.1.0].
    - Conclusion: don't install drupal/core 10.1.0 (conflict analysis result)
    - drupal/core-recommended 10.1.1 requires drupal/core 10.1.1 -> satisfiable by drupal/core[10.1.1].
    - Conclusion: don't install drupal/core 10.1.1 (conflict analysis result)
    - drupal/core-recommended 10.1.2 requires drupal/core 10.1.2 -> satisfiable by drupal/core[10.1.2].
    - Conclusion: don't install drupal/core 10.1.2 (conflict analysis result)
    - drupal/core-recommended 10.1.3 requires drupal/core 10.1.3 -> satisfiable by drupal/core[10.1.3].
    - Conclusion: don't install drupal/core 10.1.3 (conflict analysis result)
    - drupal/core-recommended 10.1.4 requires drupal/core 10.1.4 -> satisfiable by drupal/core[10.1.4].
    - Conclusion: don't install drupal/core 10.1.4 (conflict analysis result)
    - drupal/core-recommended 10.1.5 requires drupal/core 10.1.5 -> satisfiable by drupal/core[10.1.5].
    - Conclusion: don't install drupal/core 10.1.5 (conflict analysis result)
    - drupal/core-recommended 10.1.6 requires drupal/core 10.1.6 -> satisfiable by drupal/core[10.1.6].
    - Conclusion: don't install drupal/core 10.1.6 (conflict analysis result)
    - drupal/core[8.9.0, ..., 8.9.10] require symfony-cmf/routing ^1.4 -> satisfiable by symfony-cmf/routing[1.4.0, 1.4.1].
    - drupal/core-recommended 10.0.1 requires drupal/core 10.0.1 -> satisfiable by drupal/core[10.0.1].
    - Conclusion: don't install drupal/core 10.0.1 (conflict analysis result)
    - drupal/linkchecker 1.1.0 requires drupal/core ^8.9 || ^9.2 -> satisfiable by drupal/core[8.9.0, ..., 8.9.20, 9.2.0, ..., 9.5.11].
    - You can only install one version of a package, so only one of these can be installed: drupal/core[8.0.0, ..., 8.9.20, 9.0.0, ..., 9.5.11, 10.0.0, ..., 10.1.6].
    - You can only install one version of a package, so only one of these can be installed: drupal/core[8.7.0, ..., 8.9.20, 9.0.0, ..., 9.5.11, 10.0.0, ..., 10.1.6].
    - drupal/core-recommended 10.0.0 requires drupal/core 10.0.0 -> satisfiable by drupal/core[10.0.0].
    - Root composer.json requires drupal/core-recommended ^10 -> satisfiable by drupal/core-recommended[10.0.0, ..., 10.1.6].

```

I tried specifically updating symfony-cmf/routing to the 2.x version, but that still threw errors.
I really struggle digging through the lines of problems to figure out what the actual issue is.

Does anybody know how I can fix this and explain how you figured that out, so that I can hopefully know for the future?

# Answer
> I am trying to update my Drupal 9 site to Drupal 10. I installed the Upgrade Status module (and removed it before trying to update)

This is great, this should prevent any composer errors. Reinstall the *Upgrade Status* module to look again. Is there an entry for the *Link Checker* module? It should be in the *Update* section, or if not installed by Drupal in the *Remove* section with the description:

> The likely best action is to remove projects that are uninstalled. Why invest in updating them to be compatible if you are not using them?
> 0 votes

---
Tags: composer, upgrading, 10
---


# Question
Title: What permission controls access to "webform_html_editor" input type?
I'm a Drupal site owner, and my admins cannot access any webform\_html\_editor elements.

The administrators have full access to all wysiwyg inputs, but there is no permission obvious to me that controls access to this field.

What permission grants access to edit the webform wysiwyg?

# Answer
I found the answer:

Webform wysiwyg uses the "Webform (Default)" input type, which doesn't show up on the "input filter" admin listing, but does show up in the permissions table.

Granting this permission unlocks the webform\_html\_editor wysiwyg.
> 0 votes

---
Tags: webforms
---


# Question
Title: Is it possible to override config in settings.local.php by prepending/appending to the current value?
I have tried both of the following:

```
$config['my_module.default']['content'] = 'prepend ' . $config['my_module.default']['content'];

```

```
$config['my_module.default']['content'] .= ' append';

```

but the output was just the text:

```
prepend

```

```
 append

```

Any suggestions?

(My site is running Drupal 10.1.4)

# Answer
> 2 votes
No, it is not possible.

`Drupal\Core\Site\Settings::initialize`, which is the function that reads `settings.php`, initializes $config as an empty array. The `$config` values in `settings.php` are added as overrides when the configuration system initializes. `$config` is empty when Drupal reads `settings.php`.

# Answer
> 1 votes
The $config array is just stored in $GLOBALS to be used later when Drupal has a database connection. Overrides are then applied on demand when you request a config object.

What you can do, however, is create a `config.factory.override` tagged service. This service has access to the existing config data, but you have to load the mutable config to avoid applying config overrides recursively:

```
$original = \Drupal::configFactory()->getEditable('my_module.default')->getOriginal('content', FALSE);

```

See https://www.drupal.org/docs/drupal-apis/configuration-api/configuration-override-system#s-providing-overrides-from-modules

# Answer
> 0 votes
If you try to print the $config variable , then 'll not print any config that are maintained in the site. It is very early stage of Drupal process ,in which not database connection is established neither service containers, so not possible to get config value in settings.php/settings/local.php file.

---
Tags: configuration
---


# Question
Title: How to reference a class with a use statement?
Inside a function in a controller class, I have the following:

```
$form_state = new \Drupal\Core\Form\FormState();

```

It works, and produces a new instance of a FormState.

Codesniffer is not happy with this, and tells me:

> Namespaced classes/interfaces/traits should be referenced with use statements

So far I've added this use statement:

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

```

which is accepted (i.e. it does not break anything).

However, I am unable to figure out what to use to use to produce a new instance of a FormState, that Codesniffer will accept.

# Answer
In this case you need a use statement for the class, not the interface

```
use Drupal\Core\Form\FormState;

```

and then

```
$form_state = new FormState();

```
> 1 votes

---
Tags: coding-standards
---


# Question
Title: What's the meaning of [Drupal 10.0.x will receive security coverage until December 2023.] in release note
What's the meaning of \[Drupal 10.0.x will receive security coverage until December 2023.\] in release note. Can I continue to use Drupal 10.0.x after December 2023, is there any problem that I need to consider if I still use Drupal 10.0.x after December 2023.

# Answer
Security bugs in 10.0.x will no longer be fixed after that date. That version will be “end-of-life”.
> 1 votes

---
Tags: security, upgrading
---


# Question
Title: How do I change the input type created by views daterange filter?
I am using a view created with the views module. The view displays all change requests, and I wanted to expose a filter to users to be able to filter the change requests by date.

The change requests themselves use the daterange field, which I was able to find and expose in Filter Criteria. All of this worked well, but for some reason this filter creates an input field of type "text" which is not user friendly, as users have to type in a machine-recognized input similar to `CCYY-MM-DD HH:MM:SS`.

I was able to use the chrome developer tools to change the type to "datetime-local" which created a date & time widget that eliminated the need for users to enter the times manually, but I don't know the best way to change this.

# Attempt

My first thought was to use jQuery to change the type, so I was able to find this question that gave me a hint as to how it is done.

My result was the following code snippet: `$('#edit-field-date-value-min').attr('type', 'text');`

When this didn't work, I tried `$('#edit-field-date-value-min').get(0).type = 'text';`

Neither of these worked for me unfortunately.

# More Info

I have twig debugging enabled, and it is showing me that it is outputting from `input.form.twig` as per the below screenshot, but there is only one line in that file which is:

`<input{{ attributes }} />{{ children }}`

So I am not sure if this is something within drupal, or if I have to override the daterange module, or what I have to do.

# Preferred solution

Ideally, I want to know how to actually generate the html so that the input is automatically created with the type "datetime-local" instead of using jQuery to change it after the fact. I know how to edit twig templates, but I don't know how to figure out which template to use, or how to target this specific element.

# Question Summary

So to summarize my question: What do I need to do in order for this daterange filter to create an input of type "datetime-local" instead of "text"?

# Answer
> 1 votes
This hook\_preprocess\_input\__textfield() hook can be use: to convert field type from text to datetime-local

```
function Mymodulename_preprocess_input__textfield(&$vars) {
  $view_id = \Drupal::routeMatch()->getParameter('view_id');
  // Added condition so that code execute for specfied view.
  if (!empty($view_id) && $view_id == 'view_machine_name') {
    // Added Check to find whether specified exist in the view & code execute for specified field only
    if(isset($vars['element']['#name']) && $vars['element']['#name'] == 'field_name'){
      // convert input type to datetime-local
      $vars['attributes']['type'] = 'datetime-local';
    }
  }
}

```

**Note:** You can print this variable "$vars\['element'\]\['#name'\]" to get machine name of field name

You can add or remove conditions added inside hook\_preprocess\_input\__textfield() hook as per logic

click here for more documentation

# Answer
> 0 votes
To make the daterange filter create an input of type "datetime-local" instead of "text", you'll need to modify the template that is being used to render the filter.

In your case, it looks like the template is being defined in `input.form.twig`. To change the input type, you'll need to find the line in the template that is rendering the input field, and modify it to use the `type="datetime-local"` attribute instead of `type="text"`.

Here's an example of how you might do this:

```
<input{{ attributes }} />{{ children }}

```

In this example, the `attributes` variable contains the attributes that are being applied to the input field, and the `children` variable contains the content that is being displayed inside the input field.

To change the input type, you can simply add the `type="datetime-local"` attribute to the `attributes` variable, like this:

```
<input{{ attributes }} type="datetime-local" />{{ children }}

```

This will render an input field with the type "datetime-local" instead of "text".

I hope this helps!

---
Tags: theming, datetime
---


# Question
Title: How to join the node table with the url_alias table in a dynamic query?
Joining the node table to the url\_alias table requires CONCAT. Here is an example of how this can be done:

```
$results = $db->query("
  SELECT
    n.nid, n.title,
    a.source, a.alias
  FROM {node} n
  LEFT JOIN {url_alias} a
    ON CONCAT('node/', nid) = source
  ")->fetchAll();

```

The above query is taken from How to map url\_alias table to node table?

How can I do the same thing with a dynamic query?

My Drupal version is 10.1.5, but the answer is likely the same for Drupal 8 and 9.

# Answer
> 0 votes
The following dynamic query can use to join node with path\_alias table: (Drupal 8/9/10)

```
 $query = \Drupal::database()->select('node', 'n');
  $query->join('path_alias', 'pa', 'CONCAT(\'/node/\', n.nid) = pa.path');
  $rst = $query->fields('pa')
      ->execute()
      ->fetchAll();

```

Note: In Drupal(8/9/10) path\_alias table can use to get path alias maintained for node

---
Tags: database, 10
---


# Question
Title: Sorting by title of a referenced entity instead of ID
On a view, I have a content type "A" that references another content type "B".

Content "B" has, for eg, the following records:

ID 1: Title "AAA" ID 2: Title "CCC" ID 3: Title "BBB"

I would like, inside the view of content type "A", to sort by the Title of content type "B". As it works out of the box, afaik, the records will be sorted by ID, thus being displayed on a table like this:

AAA CCC BBB

but I would like to sort them alphabetically by title.

Is this possible? Thank you.

# Answer
Follow below steps to sort inside the view of content type "A", to sort by the Title of content type "B":

* Take relationship of "Content type B" field for eg: **Content referenced from field\_name**(reference field name of content type B inside content type A)
* In sort criteria \> add title field , then from "**Relationship**" drop-down select "**field name**" that added in first step
* In Order select **"ascending order"** & save the view
> 1 votes

---
Tags: views
---


# Question
Title: Media library widget: Table instead of grid?
## Background

I have a multiple-value entity reference field with target type = media. It is used for "document" media, so mostly pdf files.

I am using the "Media library" widget shipped with core. With this widget, items appear in a grid with thumbnail, and can be reordered with drag + drop.

## Problems

Most of the pdf files don't have a useful thumbnail, so they all look the same.

Due to the grid display, the title of each document is not fully visible.

The grid drag + drop reorder is less intuitive than a tabledrag, especially if the thumbnails all look the same, and sometimes even the visible part of the title is the same.

Once a media entity is added to the list, there is no link to edit this media entity from the node / host entity form.

## Questions

Is there a table version of the media library widget?

Is there a way to show an edit link with each item? Either to edit the media in a form on a new page, or in a popup.

## What I tried

Widget settings?
-\> The widget does not have any settings.

Configure the display of documents in "Core | Media library" view mode?
-\> Items still displayed in a grid.
-\> The only field that looks well in a grid mode is the thumbnail. Text fields look weird.

## References

Poor soul who asked the same in drupal.org, with no success: https://www.drupal.org/forum/support/module-development-and-code-questions/2020-06-29/how-set-media-library-widget-to

# Answer
> 1 votes
In response to your second question, there is a core issue open regarding editing media items within the field widget: https://www.drupal.org/project/drupal/issues/2985168

There is also a contrib module Media Library Edit.

One problem is that you will edit the media entity itself, affecting all usages of the media item.

# Answer
> 0 votes
There is a way to achieve this (to an extent) without modules:

1.) Go to the media library view: /admin/structure/views/view/media\_library/edit

2.) Swap the **display names** of widget and widget\_table displays.

My approach is to delete the headers on widget and widget\_table, delete the widget display, and rename widget\_table display to widget. I then add the edit link to the table.

Looks like soon a fix for this issue might get added to core: https://www.drupal.org/project/drupal/issues/2985168

# Answer
> 0 votes
If you are not wedded to MediaLibrary widget, you can use some other modules like Inline Entity Form and Entity Browser. However in my case this meant I lose the Media Library modal for adding new files and therefore lost dropzone support.

Entity Browser apparently has dropzone support but i didn't get this far.

I have verified you can use CSS to create a list. But it's not easy. It does work. I'll edit this post if I do that.

I went down the path of writing an extension of media library but the Ajax Remove buttons stopped working and I felt like it was getting too complex. However the code is here for what it's worth. https://gist.github.com/simesy/ceb2f3406bba20d6337ff6439c32247a

---
Tags: 8, entities, media
---


# Question
Title: How to list all content types by number?
I have a website with many content types and my problem is that counting the number of content types unlisted by numbers might be hard or confusing because of the high amount of content types.

When in `/admin/structure/types` the following JavaScript codes may somewhat help.

### JavaScript 1

```
console.log(document.querySelectorAll('tr').length -1);
// -1 to reduce table heading;

```

> **50** (just an example number)

## JavaScript 2

```
const allTableRowsExceptTableHeading = document.querySelectorAll('tr.odd, tr.even');

allTableRowsExceptTableHeading.forEach((element) => {
    const newCell = document.createElement('td');
    // This variable must be here inside the function because...
        // For each table row we work on, we create and add a table cell...

    element.insertAdjacentElement('afterbegin', newCell);

    newCell.innerHTML = '<span class="numberCell">A</span>';
    newCell.style.display = 'table-cell';
    newCell.style.width = 'maxContent';
    newCell.style.textAlign = 'center';
    newCell.style.backgroundColor = 'yellow';
    // These HTML-CSS directives must be here inside the function because...
        // For each table row we work on, we create and add these new HTML-CSS directives...
});

let baseNumber = 1;
document.querySelectorAll('.numberCell').forEach((element)=>{
    element.innerHTML = `<span>${baseNumber++}</span>`;
});

```

## My question

How to list all content types by number, especially backendly instead frontendly?

# Answer
In backend PHP add your own list builder to the content type aka node type:

*mymodule.module*

```
/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(array &$entity_types) {
  $entity_types['node_type']->setHandlerClass('list_builder', 'Drupal\mymodule\MyNodeTypeListBuilder');
}

```

*/src/MyNodeTypeListBuilder.php*

```
<?php

namespace Drupal\mymodule;

use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeTypeListBuilder;

class MyNodeTypeListBuilder extends NodeTypeListBuilder {

  protected $number = 1;

  public function buildHeader() {
    $header['number'] = t('Number');
    return $header + parent::buildHeader();
  }

  public function buildRow(EntityInterface $entity) {
    $row['number'] = $this->number++;
    return $row + parent::buildRow($entity);
  }

}

```

This answers the second javascript snippet, the question title and the last **my question**. If the first javascript snippet is not only for debugging but should also be included in the entity list then override render() as well:

```
  public function render() {
    $build = parent::render();
    $this->number--;
    $build['total'] = ['#markup' => "<p>Total: $this->number<p/>"];
    return $build;
  }

```

If you want to have all content types on one page add

```
  protected $limit = FALSE;

```

to the class to disable the pager.
> 0 votes

---
Tags: 10
---


title: Comments not displayed

text:
# Question
Title: Comments not displayed
On my Drupal 8 I have a blog, which should have a comment function. I added the comment field in the content type of the blog posts and I also checked the checkbox that the comment input field is shown. But the comment section is not displayed. Even in my template file in my `theme_preprocess_node` function I could not find the comment field. I also tried it with the Bartik theme, but that also didn't work.

My question now is: How can I display the comments section on my blog articles?

# Answer
> 0 votes
Debugging is the art of taking away all possible causes ... in this case you want to make sure that the permissions are set correctly. so that for the user id you're using, it's allowed to post comments.

Not sure if it is "the" reason for your issue, but without appropriate permission Drupal seems to work as it should.

Another reason might be that you have "*the field deactivated in the manage dispay settings of the related content type*" (as per your comment below this answer seems to be your case).

# Answer
> 0 votes
Try check or set this permission

# Answer
> 0 votes
I had manage display setting and permissions set but the comment form wasn't displaying on my article post. It turns out I needed to click "open" for comments on the actual article.

---
Tags: 8, comments
---


# Question
Title: "Twig_Error_Syntax: The block 'content' has already been defined line"
I have a block template in Drupal 8. I want to wrap a section element around the block when it is in the right region.

Twig gives me this error.

> Twig\_Error\_Syntax: The block 'content' has already been defined line

I understand the error, but I don't know how to fix it. Can anyone show me how to fix the code?

```
   {% set block_region_var = block_region %}
   {% if block_region_var == 'footer' %}
     <div{{ attributes.addClass(classes) }}>
       {% block content %}
         {{ content.body }}
       {% endblock %}
     </div>
   {% else %}
     <section id="{{ section_custom_id }}">
       <div{{ attributes.addClass(classes,'container') }}>
         {{ title_suffix }}
         {% block content %}
           {{ content.body }}
         {% endblock %}
       </div>
     </section>
   {% endif %}

```

# Answer
You can remove all twig blocks from the template; that is, remove all of these lines:

```
{% block content %}
{% endblock %}

```

This defines a Twig Block, which could be used to extend this template, but this doesn't make sense anymore after you have implemented the condition.
> 2 votes

# Answer
1. Write a block preprocessing function in the .theme file and check the block region as in the following code.

```
 function THEMENAME_preprocess_block(&$variables ){
   $region = $variables['elements']['#configuration']['region'];
   if($region == "right"){  // please use specific region value
     $variables['right_region'] = TRUE;
   }
 }

```
2. In block.html.twig, verify `right_region` is set to `TRUE`; then, add the wrapper class.

```
{% if right_region %}
  // Add the wrapper class.
{% else %}
  //
{% endif %}

```
> 1 votes

# Answer
For future developers who encounter same issue as me. I fixed it like this

```
{% if condition %}
    <div class="simple block">{% block content %}{% endblock %}</div>
{% else %}
    {% include 'extended_block.twig' %}
{% endif %}

// extended_block.twig with a bit different html structure
<div class="something">
    <div class="something2">
        {% block content %}{% endblock %}
    <div>
</div>

```
> 1 votes

# Answer
It'd be something like this:

```
{% set block_region_var = block_region %}
{% if block_region_var == 'footer' %}
   <div{{ attributes.addClass(classes) }}>
       {% block content %}
         {{ content.body }}
       {% endblock %}
   </div>
{% else %}
   <section id="{{ section_custom_id }}">
     <div{{ attributes.addClass(classes,'container') }}>
       {{ title_suffix }}
       {{ block(content) }}
     </div>
   </section>
{% endif %}

```

You really just need to replace any further repetitions of the block with `{{ block(content) }}`.

It's explained in the Twig documentation here: https://twig.symfony.com/doc/3.x/functions/block.html
> 1 votes

# Answer
Although this might not exactly fit OP's needs I'd like to highlight Twig `extends` to only override one certain `{% block %}` to get rid of that error.

In Twig blocks are overridable portions. You can simply extend one `{% block %}` in a child template and *everything else in the parent template stays untouched*. You also can simply reference the parent's `{{ content }}` by calling `{{ parent() }}`.

`themes/custom/MYTHEME/templates/paragraph.html.twig`:

```
{# extends and include paths always start inside Drupal web root #}
{% extends "modules/contrib/paragraphs/templates/paragraph.html.twig" %}

{# And now you only extend the content block of the parent template #}
{% block content %}
  {% if neat_grid %}
    <div class="neat-container">
      <div class="neat-row">
        <div class="inner">
          {{ parent() }}
        </div>
      </div>
    </div>
  {% else %}
    {{ parent() }}
  {% endif %}
{% endblock %}

```
> 0 votes

# Answer
This is the way I would do it:

```
{% block content %}
  {% set block_region_var = block_region %}
   {% if block_region_var == 'footer' %}
     <div{{ attributes.addClass(classes) }}>
         {{ content.body }}
     </div>
   {% else %}
     <section id="{{ section_custom_id }}">
       <div{{ attributes.addClass(classes,'container') }}>
         {{ title_suffix }}
           {{ content.body }}
       </div>
     </section>
   {% endif %}
{% endblock %}

```
> 0 votes

# Answer
I cannot comment becase the reputation. I think the best answer is this: https://drupal.stackexchange.com/a/312346/111639

But the first parameter of block function is a string.

The code is:

```
{% set block_region_var = block_region %}
{% if block_region_var == 'footer' %}
   <div{{ attributes.addClass(classes) }}>
       {% block content %}
         {{ content.body }}
       {% endblock %}
   </div>
{% else %}
   <section id="{{ section_custom_id }}">
     <div{{ attributes.addClass(classes,'container') }}>
       {{ title_suffix }}
       {{ block('content') }}
     </div>
   </section>
{% endif %}

```
> 0 votes

---
Tags: theming
---