# Question
Title: Get path from router and redirect after autocomplete selection
I have a form that is inflated inside a box. In that form I have an autocomplete field. I want to allow the user, when they select an item from the autocomplete's suggestions they are automatically redirected to the appropriate page.

My current idea is to handle this in JS. But I don't like this as it makes it very difficult to use Drupal's routing system to route -- instead I have to hardcode things, which is bad.

```
class AutocompleteSearchForm extends FormBase {

  public function getFormId() {
    return 'search_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['search'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Lookup'),
      '#description' => $this->t('Search.'),
      '#placeholder' => $this->t('Search'),
      '#autocomplete_route_name' => 'block.autocomplete.callback',
      '#autocomplete_route_parameters' => array('name' => 'name'),
      '#attached' => array(
        'library' => array('module/autocomplete'),
      ),
    );
    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    \Drupal::logger('module')->warning('form submitted for' . $form_state->get('search'));
  }
}

```

And my JS is:

```
(function ($) {
    $('#edit-search').on('autocompleteclose', function (event, node) {
        var entity_id = $(this).val();
        alert(entity_id);
    });
}(jQuery));

```

As you can see, I tried to manage this through the callback, but I don't expose a button and this doesn't submit unless the user hits the "enter" button, which isn't exactly intuitive.

Is JS the best way to handle this? If it is, is there a good way to get access to Drupal's path/router system from JS?

# Answer
Try to use `$build['#attached']['drupalSettings']['vartest'] = $test;` to pass `$test` from PHP to JS. The variable `$test` contains the Drupal's path/routes.

Replace `$build` with the variable containing the form or the render array to which the settings are attached. In a form builder or `hook_form_alter()`, that would be `$form`.
> 0 votes

# Answer
No out-of-the-box feature in Drupal handles redirects directly after an autocomplete selection. However, the following approach, which does use a bit of JavaScript but also takes advantage of Drupal's routing system, might work for you:

In your JavaScript, you listen to the `autocompleteclose` event (as you are currently doing), but instead of trying to redirect immediately, you trigger form submission.

```
(function ($) {
    $('#edit-search').on('autocompleteclose', function (event, node) {
        $(this).closest('form').submit();
    });
}(jQuery));

```

In your submitForm function in PHP, you can handle the redirect using the form state setRedirect function, which does use Drupal routing system:

```
public function submitForm(array &$form, FormStateInterface $form_state) {
    $entity_id = $form_state->getValue('search');
    // Perform your logic to get the route name based on the entity id.
    $route_name = 'my_module.entity_view';  // Replace this with your logic.

    $form_state->setRedirect($route_name);
}

```

In the submitForm method above, you would replace 'my\_module.entity\_view' with the appropriate route name based on the entity id. If the entity id does not map directly to a route, you might need to load the entity, check its type or other properties, and determine the correct route based on that.
> 0 votes

---
Tags: 8, forms, javascript, redirection
---


# Question
Title: How can I programmatically display a block?
I'm developing a site using Drupal 8 beta-14. I've created a view block of different terms and now I want to display it using code. How can I display it programatically? I used to do it in Drupal 7 using this code but I'm confused about Drupal 8.

```
$block = module_invoke('block', 'block_view', '4');
$text_block = render($block['content']);

```

# Answer
There are two types of blocks, and the method for rendering the two is a bit different:

## Content Blocks

Content blocks are blocks that you create in the interface. They are much like nodes configurable data structures, with fields etc. If you want to render one of these, you can do what you would normally do with entities, load them and render them with the view builder:

```
$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
  getViewBuilder('block_content')->view($block);
return $render;

```

## Plugin blocks

Blocks can also be plugin, defined in various modules. An example could be the breadcrumb block. If you want to render these, you will need to use the block plugin manager.

```
$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
  // You might need to add some cache tags/contexts.
  return [];
}
$render = $plugin_block->build();
// Add the cache tags/contexts.
\Drupal::service('renderer')->addCacheableDependency($render, $plugin_block);
return $render;

```

## Config entities

Shared for the two types are blocks, are that once you insert them into a region, you will create a config entity that has all of the settings for the block. In some cases it will be more useful handling config entities. Since the same block can be place in multiple regions with and with different configuration, it can get more tricky using the block config entities. The nice thing is that you might want to render a block with specific configuration, the bad thing is that config ids can change by messing with the interface, so the code might end up not working after letting users use the block interface.

```
$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
return $render;

```
> 102 votes

# Answer
For display only your block in your templates with preprocess the best way is

```
$block = \Drupal\block\Entity\Block::load('my_block_id');
$variables['My_region'] = \Drupal::entityTypeManager()
          ->getViewBuilder('block')
          ->view($block); // Works in Drupal 9

```

And in your `page.html.twig` or `node.html.twig` or `xxx.html.twig` use your variable My\_region like this :

```
{% if page.My_region %}
    {{ page.My_region }}
{% endif %}

```

And in renderable array (custom module) by example into an controller custom in content() :

```
public function content() {
    $block = \Drupal\block\Entity\Block::load('my_block_id');
    $block_content = \Drupal::entityManager()
      ->getViewBuilder('block')
      ->view($block);

          return array(
        '#type' => 'container',
        '#attributes' => array(
          'class' => array("Myclass"),
        ),
        "element-content" => $block_content,
        '#weight' => 0,
      );
}

```

Using ~~`drupal_render`~~ is not useful as Drupal already assume the render in D8 and this is deprecated. You should use `\Drupal::service('renderer')->renderRoot()` instead.

It's a bit heavy, it is better to use the maximum area system and does not add load block from the preprocess. In the case of using a controller in your modules this seems a justified use.
> 20 votes

# Answer
I needed to get the HTML of a custom block and got it using:

```
$con = \Drupal\block\BlockViewBuilder::lazyBuilder('bartik_search', 'full');
$d   = \Drupal::service('renderer')->renderPlain($con);

print $d->__toString();

```
> 11 votes

# Answer
In addition to the top answer... If you want to render a block from a view, you may have to do things a little differently.

```
$view = views_embed_view('my_view_name', 'my_display_name');

```

(display name eg -\> block\_1)

Since we're going to pass it to twig, we don't need to render (using render service).

So you can just pass it as a variable to twig (for this example, its the return of a Controller):

```
return [
  ['description' => [
    '#theme' => 'your_theme_hook',
    '#your_variable => $view
  ]
]

```

in your module you need a hook\_theme() for your variable:

```
function hook_theme($existing, $type, $theme, $path) {
  return array(
    'your_theme_hook' => array(
      'variables' => [
        'your_variable' => NULL,
      ]
    )
  )
}

```

And finally in your twig template:

```
{{ your_variable }}

```
> 9 votes

# Answer
Basically, there are two types of renders.

1. When there is an existing instance of the block in the layout. the block can be rendered in twig using preprocess as

```
$block = Block::load('BLOCK_ID');
$variables['social_links'] = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);

```
2. There is no instance or configurations for the block. Then in the preprocessor, we need to create the instance, build the block and then render it

```
$block_manager = \Drupal::service('plugin.manager.block');
$config = [];
$plugin_block = $block_manager->createInstance('farmjournal_social_sharing', $config);
$render = $plugin_block->build();
$variables['farmjournal_social_sharing'] = render($render);

```
> 5 votes

# Answer
The following code works for blocks.

```
$block = \Drupal\block\Entity\Block::load('some_block_id_3');
$plugin = $block->getPlugin();
$build = $plugin->build();
$build['#weight'] = 4;
$form['block'] = $build;

```
> 4 votes

# Answer
```
// You need a block_id! to get it just click configure in the desire block and you'll get url like this /admin/structure/block/manage/bartik_search   the last part of the parameter is the block id
$block = \Drupal\block\Entity\Block::load('bartik_search');
$block_content = \Drupal::entityManager()
  ->getViewBuilder('block')
  ->view($block);

return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));

```
> 2 votes

# Answer
You get the block output and then you may return it.

```
$block = \Drupal\block\Entity\Block::load ('my_bock_id');
block_content = \Drupal::entityManager()->getViewBuilder('block')->view($block);

return [
  '#type' => 'container',
  'element-content' => $block_content
];

```
> 1 votes

# Answer
Adding an additional answer here for better visitbility:

There is now a module that allows you to render a plugin block called Block plugin view builder: https://www.drupal.org/project/block\_plugin\_view\_builder.

You can of course still use Drupals render service, however that returns a \Drupal\Component\Render\MarkupInterface object. In some cases, you need a render array. For example if wanting to render the block in the lazy builder.

Example of using that modules service once that module is installed:

```
$block_view_builder = \Drupal::service('block_plugin.view_builder');
$block = $block_view_builder->view('bid', []);
return $block;

```
> 0 votes

# Answer
Based on my research, you could base the code from How to render a block programmatically in drupal 8. You could also change

```
return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));

```

into something as simple as:

```
$output .= \Drupal::service('renderer')->renderRoot($block_content);

```

to attach it for example into a page's return variable.
> -1 votes

---
Tags: 8, blocks
---


# Question
Title: Theming image.html.twig for one paragraph type with custom template suggestion
I have a custom module that when installed, creates a paragraph type called "Gallery". Gallery has one field called "field\_gallery\_images", which is a media reference.

**I am trying to replace `image.html.twig` with `image--gallery.html.twig` only for images inside my gallery.**

I have managed to get Drupal to recognise and load my custom template from the modules template directory. However, every single image on the site now uses this template. **I only want the template to be used for images of my paragraph type** (or it's field). All other images should use the default image.html.twig.

Here is `gallery.module`:

```
function gallery_theme($existing, $type, $theme, $path) {
  return [
        'image__gallery' => [
      'template' => 'image--gallery',
      'base hook' => 'image',
    ],
  ];
}

function gallery_theme_suggestions_image_alter(array &$suggestions, array $variables) {
 $suggestions[] = 'image__gallery';
}

```

There is nothing I can test against inside any of the variables passed into both hooks to target my templates scope.

Am I using the wrong hooks?

# Answer
Yes, the variables passed by default are not very helpful. The trick is to add an identifier of the field to the image attributes in field preprocessing. See this great answer How to add attributes to a specific field's image
> 0 votes

---
Tags: theming, hooks, 9
---


title: Get the route name of the current page

text:
# Question
Title: Get the route name of the current page
The route name of the current page is available in `page.html.twig`? The page is generated by the default feedback form.

# Answer
To get the current route name, use:

```
$route_name = \Drupal::routeMatch()->getRouteName();

```

You can add the current page's route name as a variable in your theme's ".theme" file. Add a \_preprocess\_page function like this, and clear the drupal cache.

```
/**
 * Implements hook_preprocess_page().
 *
 */
function mytheme_preprocess_page(&$variables) {
  $variables['route_name'] = \Drupal::routeMatch()->getRouteName();
}

```

Then you can access in page.html.twig like this:

```
{{ route_name }}

```

**Note:** `\Drupal::routeMatch()->getRouteName()` will sometimes return null.

If you are inside a class, to do things properly, you'll want to inject the route match service in the constructor and then call it this way:

```
$this->currentRouteMatch->getRouteName()

```

The constructor (and variable) will be like this:

```
  /**
   * The current route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $currentRouteMatch;

  /**
   * Constructs a new ThemeTestSubscriber.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
   */
  public function __construct(RouteMatchInterface $current_route_match) {
    $this->currentRouteMatch = $current_route_match;
  }

```

If it's a service class, you'd then pass it into the service in the yaml file in your custom module:

```
services:
  mymodule.service:
    class: Drupal\mymodule\MyCustomService
    arguments: ['@current_route_match']

```
> 105 votes

# Answer
Another way to handle this is by using the Devel Module if you are developing locally.

1. Download and enable Devel
2. Log in as an administrator
3. Navigate to /admin/config/development/devel/toolbar
4. check "Current route info"
5. click Save configuration
6. Navigate to the url you are wanting the route information for
7. Click Devel in your toolbar above the admin menu
8. Click Current route info

If you are in a theme or situation where you can't find the admin toolbar or can't find the "Current route info" menu link, modify the url `/devel/routes/item?path=/user/1` where `/user/1` is the path that you are looking for path information for. It appears that this method will not work for pages that change routes based on get parameters... for example, `?_format=json` or other custom routing like that.
> 5 votes

# Answer
Not for in a template, but to inspect the route: `drush core:route`:

```
drush core:route --path=/node/123/latest
drush core:route --path=/user/1

```

Ref: drush commands docs: core:route

Example:

```
$ drush core:route --path=/node/123/latest
name: entity.node.latest_version
path: '/node/{node}/latest'
defaults:
  _entity_view: node.full
  _title_callback: '\Drupal\Core\Entity\Controller\EntityController::title'
requirements:
  _entity_access: node.view
  _content_moderation_latest_version: 'TRUE'
  node: \d+
options:
  _content_moderation_entity_type: node
  parameters:
    node:
      type: 'entity:node'
      load_latest_revision: true
      converter: paramconverter.entity
  _access_checks:
    - access_check.entity
    - access_check.latest_revision

```
> 1 votes

---
Tags: 8, routes
---


# Question
Title: Translating media and other reference fields
I am new to Drupal and I am setting up a new Drupal 10 website with multiple languages. I just wanna make sure that as a beginner I have understood the concept of translation for fields that reference to other entities.

For example, I have an *Article* content type with three fields:

* field\_related\_pages that references multiple *Page* nodes
* field\_main\_image that references a media entity (an Image bundle)
* field\_related\_places which references a *Places* vocabulary

From what I've concluded from my search, those three fields should be marked as NON Translatable on the *Article* content type. Moreover, on the configuration page admin/config/regional/content-language, the *Places* vocabulary should be marked as translatable with all its translatable fields, the content type page should be also marked as translatable with all its translatable fields, the Image should also be marked as translatable with all its translatable fields.

Is this correct, or should I mark the field\_main\_image field as translatable from the beginning in the *Article* content type?

# Answer
> 1 votes
Short answer: Yes, this is correct.

Only make reference fields translatable when they should have completely different values in different languages.

---
Tags: 10
---


# Question
Title: How do I get information about the payment method from the order object programmatically?
I'm trying to do some different processing after an order is placed depending on which payment method a customer uses.

In my EventSubscriber, I have the following code:

```
 public static function getSubscribedEvents() {
    $events = [
      'commerce_order.place.post_transition' => 'onPlaceTransition'
    ];
    return $events;
  }

  public function onPlaceTransition(WorkflowTransitionEvent $event) {
    $order = $event->getEntity();

```

Now I want to get the name or id of the payment method that was used from the order, but when I used `kint($order)` I couldn't find a way to access the payment method.

How do I access the payment method given an `$order` object?

# Answer
> 10 votes
The Commerce Payment module adds the `payment_method` base field when it is enabled, see `commerce_payment_entity_base_field_info` https://github.com/drupalcommerce/commerce/blob/8.x-2.x/modules/payment/commerce\_payment.module#L28

You can access the payment method (and gateway) through

```
$order->get('payment_method')->first()->entity
$order->get('payment_gateway')->first()->entity

```

Example of when we get the payment method label for the order receipt email.

```
if (!$order->get('payment_method')->isEmpty()) {
  $variables['payment_method'] = [
    '#markup' => $order->get('payment_method')->first()->entity->label(),
  ];
}

```

From https://github.com/drupalcommerce/commerce/blob/77b25bf4889a940eed6652475c3952c36144efc0/modules/payment/commerce\_payment.module#L122

# Answer
> 1 votes
It looks like it changed at some point after 2018. I could only get the label in this way (for my offsite payment method):

```
use Drupal\commerce_payment\Entity\PaymentGateway;

/** @var PaymentGateway $paymentGateway */
$paymentGateway = $order->get('payment_gateway')->entity;

$label = $paymentGateway->getPluginConfiguration()['display_label'];

```

`$order->get('payment_method')` was empty for my orders, but according to the code, payment methods are only set, if they are stored payment methods of the customer.

---
Tags: 8, commerce
---


# Question
Title: Twig: display linkfield with optional title
I created a linkfield within a paragraph with an optional title. The textlink should only be displayed, when the title is not empty. I need the URL from the linkfield for another field (an image where the users can click to open the same URL from the linkfield), so the editor can chose if he wants the textlink as well to be displayed or only the linked image.

```
{% if content.field_link.0['#title']|render %}
<a href="{{ content.field_link.0['#url'] }}" target="{{ content.field_link.0['#options']['attributes']['target'] }}">{{ content.field_link.0['#title'] }}</a>
{% endif %}

```

Unfortunately the textlink will be displayed anyway, even if the title of the textlink is empty :-( If the title of the textlink is empty, the URL of the link will be displayed (linked).

What am I doing wrong? Is there another solution for this? Thanks

# Answer
You are using a render filter in your condition. When the title is empty, the render filter will still return the link URL because that's part of what's being rendered.

This is why your link is displayed even when the title is empty.

Instead of using the render filter, you can check directly if the title is not empty using the empty test:

```
{% if content.field_link.0 is defined and content.field_link.0['#title'] is not empty %}
  <a href="{{ content.field_link.0['#url'] }}" target="{{ content.field_link.0['#options']['attributes']['target'] }}">{{ content.field_link.0['#title'] }}</a>
{% endif %}

```

The empty test will return true if the variable is empty or not set and false otherwise. By using the not operator, you can check if the title is not empty.
> 0 votes

# Answer
For doing logic I generally recommened the raw entity object variable (`paragraph` in a paragraph template, `node` in a node template, etc) instead of the `content` HTML render array.

```
{% if paragraph.field_link.0.title %}
  ...your stuff here...
{% endif %}

```

The schema is `entity_type.field_name.numeric_index.database_column`
(`database_column` is usually `value`, except link fields have a `uri` and a `title`; and entity references use `target_id` instead of value)
> 0 votes

---
Tags: paragraphs
---


title: Disabling the links in menu item

text:
# Question
Title: Disabling the links in menu item
When I visit a page , say 'About Us' I want the 'About Us' in the menu-items to act as a simple text (not as a link). How can I achieve that ? Thank you in advance.

# Answer
You can use the Special menu items module.
In your case you can use the \<nolink\> placeholder in the menu link path field to show the menu item as text.
> 2 votes

# Answer
You can do this in your theme template with YOURTHEME\_menu\_link().

You need to replace YOURTHEME with whatever your theme is called.

```
function YOURTHEME_menu_link(array $variables) {

$element = $variables['element'];
$sub_menu = '';
$name_id = strtolower(strip_tags($element['#title']));
if (strpos($name_id, ':')) $name_id = substr ($name_id, 0, strpos($name_id, ':'));
$pattern = '/[^a-z]+/ ';
$name_id = preg_replace($pattern, '', $name_id); //this is what the link is called
$element['#attributes']['class'][] = $name_id;

//you can check the values of your links here by printing $name_id

if ($name_id == 'About Us') { //this is just an example, if it were called this it would probably be in lowercase
    $output = $element['#title']; //this will just output the title of what was going to be a link
} else { //else create links for the menu
    $output = l($element['#title'], $element['#href'], $element['#localized_options']);
}

return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n"; //this just puts it all together

}

```

If your using a contributed theme its most likely you will have something like this in your theme template already so its just a case of making some amendments.

BE SURE TO CLEAR CACHES ;-)
> 1 votes

# Answer
Most likely, the link for the page your are currently visiting will be marked as visited :

```
<a href="/about-us" class="active" >About us</a>

```

So you can use this attribute to add some jQuery disabling the link

```
$("a.active").replaceWith($("a.active").html());

```

JS Bin
> 0 votes

# Answer
By default, all menu items are "enabled." This means they display. Menu items can also be disabled though. A disabled menu item knows who its parent is, so the related sub-menu and breadcrumb will display. But - you don't have to necessarily clutter up your menu with another visible link. (*Note: this is only really applicable to the main menu since that's what drives the sub-menu and breadcrumb.*)

To create a disabled menu item:

1. Put the page/webform/list into the menu using the menu settings section of that content's edit form.
2. Click "Main menu" in the gray shortcut bar.
3. Find the menu item you want to disable.
4. Uncheck "enabled" next to it.
5. Click save at the bottom.

If you want to create a sub-menu below a page that doesn't display in the top menu, just disable the top menu item and leave it's children enabled.
> 0 votes

# Answer
Updated answer from: Non-Clickable Menu Items by @Guest312312

To create a menu item without link in a custom module add to \[module\_name\].links.menu.yml:

`url: 'internal:##'`

You need to add a second # character (or any other letter or word `url: 'internal:#nolink'`) in order to the href attribute will not rendered empty, which will cause a page reload if the user click the link.

Example:

```
# [module_name].links.menu.yml
edesk_toolbar.admin_help:
  title: My link name here
  url: 'internal:##'
  description: 'A nolink menu item'
  parent: system.admin
  menu_name: admin
  weight: 999

```

The above eaxmple is tested and works in drupal 10.1
> 0 votes

---
Tags: 7, routes
---


# Question
Title: How do I edit settings.php when it is read-only?
I have a Drupal 10 site that I just installed for the first time. I am very new to Drupal, and I haven't done anything to this site except install it and set up basic details like the site name, emails, and my admin login. The problem I am having is that the Status Details page lists 1 error which is:

`Trusted Host Settings`

```
Not enabled
The trusted_host_patterns setting is not configured in settings.php. This can lead to security vulnerabilities. It is highly recommended that you configure this. See Protecting against HTTP HOST Header attacks for more information.

```

I found this Drupal documentation that explains how to configure trusted host settings, which sounds very easy, however when I VIM into the file and attempt to add my localhost to the settings, it gives me a warning saying it is a readonly file. When I try to save the settings, it throws an error saying it is readonly.

The file I am attempting to edit is in `/project-folder/web/sites/default/settings.php` which I believe is the correct file.

# Attempted Solutions

1. This question talks about how Drupal can't make a file readonly, but I am able to VIM into other files without issues. I was also able to build it using composer which downloaded the files to this repository without any issues, so I don't know what else might be making this specific file readonly.

Continuing attempt 1, I went back one directory into `/sites/` and attempted to edit `README.txt` with vim. It did not show any warnings that this file is readonly. I also attempted to edit `example.sites.php` in the `/sites/` directory with vim and this one also did not give any readonly warning. Thus, I believe that the only file affected is the `/sites/default/settings.php` file, and I do believe that it has something to do with Drupal.

2. This documentation talks about Configuring Read-only mode, but it looks like editing the same `settings.php` file is necessary. Editing the file is what is causing the readonly error.
3. Changed ownership of `/Documents/Repositories/` Directory where my project folder is to my own user on a hunch. The file is still readonly.
4. Stopped apache server with `brew services stop httpd`, then attempted to edit the file once again. It is still readonly.

# Warning in settings.php

I continued to try to resolve this issue and noticed a block of text in the `settings.php` file that I did not see in the documentation. I believe this contains a hint to the solution to my issue:

```
 * In order to use the selection rules below the multisite aliasing file named
 * sites/sites.php must be present. Its optional settings will be loaded, and
 * the aliases in the array $sites will override the default directory rules
 * below. See sites/example.sites.php for more information about aliases.

```

# Question

What is the recommended way to alter the `settings.php` file? I assume that other Drupal users who may not be too experienced in the shell have come across this issue so I am wondering if there is a way to edit this file without manually disabling readonly and enabling it after the change is made. If not, how do I do this safely?

# More Information

* This is a freshly installed Drupal 10.1.0 site.
* Installed using Composer
* Installed locally and uses Postgres and Apache. Both services are running when I try to make the change.

# Answer
> 2 votes
This is explained in core/INSTALL.txt.

This will make the file editable:

`chmod a+w sites/default/settings.php`

It is recommended to harden the permissions after editing:

`chmod go-w sites/default/settings.php`

---
Tags: installation, security
---


# Question
Title: How to use a view mode for all the content entities
I would like all the nodes for the "Services" content type to use the "Demo" view mode.

Structure -\> Content type \> Services \> Manage Display tab shows 3 view modes: Default, Demo, and Teaser.

Structure -\> Content Type -\> Services -\> Manage Display -\> Demo view mode: I have one field "Marketing headline" enabled.

I added a node for the Services content type. When I visit the node, I see Body and Marketing headline but I was only expecting to see the Marketing headline field value. How can I configure in a way that all the nodes of the "Services" type use the "Demo" view mode?

Here are few screenshots:

# Answer
If all nodes should be displayed a certain way you should edit the `Default` view mode to do it.

Creating a new view mode doesn't automatically make it being used on the content type, that is why you're still seeing the Body content.

Or if you really need to use the Demo view mode you need to provide a way to display the nodes that way. That can be done with Views, but you should be mindful about what in the end ends up visible to users, because the default paths will remain and they will use the Default View mode.

---

Alternatively, you could use a module that creates a page for each of the view modes: View Mode Page, although that may be an overkill in your case, you probably don't want extra paths diluting your content.
> 1 votes

---
Tags: views
---


title: creating links containing anchors

text:
# Question
Title: creating links containing anchors
In relation to Drupal 8 ... if a user wanted to create a link such as the following:

```
<a href='#' onClick='testfunction ();'>link</a>

```

How could such a link be created, normally creating a link requires the use of the Url object and so the symbol '#' can't normally be used, nor can 'javascript:void (0)'.

Essentially I'm trying to create an link with an anchor tag in it.

Thanks.

# Answer
> 7 votes
Url component is not able to generate URLs with empty anchors, so you need create an anchor on your page or use existing one.

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

$url = Url::fromUserInput('#main-content');
print Link::fromTextAndUrl(t('Link text'), $url)->toString();

```

# Answer
> 0 votes
Digging it up to provide a broader approach. As per the documentation, one can use the "fragment" option in order to attach an anchor (#) to a drupal Link.

e.g.

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

$url = Url::fromRoute('example.route', ['route_parameter' => 'example'], ['fragment' => 'anchor-section']);
$link = Link::fromTextAndUrl(t('Link with anchor'), $url);

```

---
Tags: 8, uri, navigation
---


# Question
Title: How can I add inline markup to submit buttons?
I migrate code from Drupal 7 to Drupal 10, in Drupal 7 I often created buttons with an icon and text like showen aboven:

Drupal 7 code:

```
$form['submit'] = [
  '#type' => 'submit',
  '#value' => t('<i class="glyphicon glyphicon-share"></i> Register'),
  '#attributes' => ['class' => ['btn-success btn-sm']],
];

```

When I try to do this in my drupal 10 code, the icon (I replaced the glyphicon by a bootstrap icon and the icon is showen when I use it e.g. in #markup) is not visible. I recognized, that drupal 10 renders `'#type' => 'submit'` as `<input>` instead of `<button>` and I think that this is the reason for this behaviour.

(Not working) Drupal 10 Code:

```
$form['actions']['submit'] = [
  '#type' => 'submit',
  '#value' => Markup::create('<i class="bi bi-box-arrow-up-right"></i> Register'),
  '#attributes' => ['class' => ['btn-success btn-sm bi bi-box-arrow-up-right']],
];

```

I was really wondering why this is so complicated in D10, I thought this would be a common task. Is there perhaps a simple option that I missed or has anyone a suggestion how I can add icons to the text of submit buttons like I did it in Drupal 7?

Thank you for your ideas.

# Answer
One possible solution (as showen in the link of @Clive) might be using a html `<label>`.

The following works for me:

```
$form['actions']['submit'] = [
  '#type' => 'submit',
  '#prefix' => Markup::create('<label for="edit-submit" class="btn btn-primary"><i class="bi bi-box-arrow-up-right"></i> Register</label>'),
  '#value' => 'Register',
  '#attributes' => ['style' => ['visibility:hidden']]
];

```

The drupal created button will be hidden and replaced by the label, the drupal submit handler will still be called.
> 2 votes

# Answer
This is the sort of customisation best done in the theme, and fortunately there's a neat little trick that will help you achieve it, using the '#theme\_wrappers' key:

```
$form['actions']['submit'] = [
 '#type' => 'submit',
 '#value' => $this->t('Register'),
 '#theme-wrappers' => ['input__submit__register_button'],
];

```

With this setting in the button array the theme layer will, before using the default suggestions, look for a template called 'input--submit--register-button.html.twig', which might contain something like this:

```
<input{{attributes}}><i class="bi bi-box-arrow-up-right">{{children}}</i>

```

This technique extends to other elements though for some you will need to use the '#theme' key rather than '#theme\_wrappers', and some experimentation may be necessary. (Note that '#theme' expects a string value rather than an array.)
> 0 votes

---
Tags: theming, forms, 10
---


# Question
Title: Is there an alternative to hook_webform_submission_render_alter()?
In Drupal 7, I was able to use `hook_webform_submission_render_alter()` to alter the rendering of webform submissions. For example, I was able to completely remove the display of specific fields depending on their answered values.

I am looking to do the same in Drupal 9, where that hook no longer exist. I tried different approaches with no luck so far.

What would be the alternative to `hook_webform_submission_render_alter()` in Webform?

# Answer
Based on your specific use case, you can use `hook_webform_element_access` to hide elements.
> 1 votes

---
Tags: webforms
---


# Question
Title: How to redirect a user to the current page?
How can I redirect user to the current page using Drupal\Core\Link?

I am creating a breadcrumb where I want to redirect user to the current page

# Answer
You can try

```
   use Drupal\Core\Link;
   use Drupal\Core\Url;
   $redirect_to_same_page = Link::fromTextAndUrl('Same page', Url::fromUri('base:' .\Drupal::service('path.current')->getPath()));
   $breadcrumb->addLink($redirect_to_same_page);

```
> 3 votes

# Answer
Like this you get the actual path:

```
\Drupal::service('path.current')->getPath()

```

and then you just use it as:

```
$current_page_link = new Drupal\Core\Link('So here you are', Drupal\Core\Url::fromUri('base:' . Drupal::service('path.current')->getPath()));

```
> 4 votes

# Answer
Using Route. Drupal get the current route name

```
$route_name = \Drupal::routeMatch()->getRouteName();
// or
// $current_route_name = \Drupal::service('current_route_match')->getRouteName();
$this->messenger()->addMessage($this->t('Page redirected'));
return $this->redirect($route_name);

```

Reference: https://www.codimth.com/blog/web/drupal/get-route-name-current-page-drupal-8
> 0 votes

---
Tags: 8, redirection, breadcrumbs
---


# Question
Title: EntityQuery condition on translation status
Im currently using `Drupal::entityQuery()` to build a list of node.

I need to be able to query only contentEntities that have a specific translation not published. I struggle because I don't know how to make a condition on an entity translated field/property.

to sum up: **How to query all nodes that have 'de' translation AND which their 'de' translation are not published?**

Is there a way to do it with `Drupal::entityQuery()` or should I directly go with altering the query with `QueryInterface::addTag()` where I would be able to customize the query?

# Answer
> 5 votes
This should do what you want. Note that the id's will load the default language, you will need to use getTranslation(langCode) to get the translated node.

```
$query = \Drupal::entityQuery('node');
$query->condition('status', 0);
$query->condition('type', YOUR_TYPE);
$query->condition('langcode', 'de');
$ids = $query->execute();

```

# Answer
> 0 votes
> $query-\>condition('langcode', 'de');

This condition gets only nodes, that have last translation to 'de' language or created on 'de' language and didn't translate to another language (https://www.drupal.org/project/drupal/issues/3092835)

You can use this solution:

```
$query = \Drupal::entityQuery('node');
$query->condition('status', 0);
$query->condition('type', YOUR_TYPE);
$ids = $query->execute();

//And then check if entity has needed translation:
$language = 'de';
$list = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($ids);
foreach ($list as $key => $node) {
  if (!$node->hasTranslation($language)) {
    unset($list[$key]);
  }
  else {
    $list[$key] = $node->getTranslation($language);
  }
}

```

As a result, you have a correct list of entities that have relation to requested language.

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


# Question
Title: Update values using AJAX in field widget form
**Similar questions:**

Ajax wrapper replacement on a field widget form

how to create an AJAX field widget

**Problem:**

Get `FIELD_NAME` and `DELTA` in AJAX callback function? (See below)

**What is done:**

Change value of a `textfield` in a widget form (see here) upon value change (jQuery event .change()) of another `textfield` in widget form.

**Code Sample:**

in `hook_widget_form`:

```
// Changes of this field fire the AJAX event
$element['value'] = ...
$element['value']['#ajax'] = array(
                    'callback' => 'some_ajax_callback',
                    'wrapper' => 'location-div',
                    'method' => 'replace',
                    'effect' => 'fade'
            );
// This field is updated upon AJAX call
$element['location'] = ...
// Here is where the actual change occurs
if(!empty($form_state['values'][$field['field_name']]['und'][$delta]['value'])) {
            $element['location']['#value'] = ...;
        }

```

in `some_ajax_callback`:

```
function some_ajax_callback ($form, $form_state) {
  // Where do I get FIELD_NAME, and DELTA?
  return $field[FIELD_NAME]['und'][DELTA]['location'];
}

```

**What happens?**

As it is mentioned here `#default_value` is not populated using AJAX so according to this `#value` should be used instead.

The problem is how to get `FIELD_NAME` and `DELTA` in AJAX callback function? (See above)

**UPDATE (NOT WORKING!)**

~~I managed to figure out a workaround to make this work as following:~~

~~* Item to be updated receives an ID composed of field\_name and delta (e.g. `location-div-myfield-0` (this is necessary if multiple instances of the same field are on the same page)
* Save field name (here `myfield`) and delta (here `0`) in `$field_state` (in `hook_field_widget_form`)
* Read the saved values from `$field_state` in ajax callback (here `some_ajax_callback`) and return the desired form element.~~

~~This however works if there is only one instance of the field in the form, otherwise the values in `$form_state` are always those of last instance.~~

**Possible solution**

Using the `triggering_element` of `$form_state` in `some_ajax_callback` all necessary info can be derived:

```
function some_ajax_callback ($form, $form_state)
{
    // This contains info about triggering element
    // Index 0 = field name, 1 = language, 2 = delta, 3 = element name
    $element = $form_state['triggering_element']['#parents'];
    $delta = $element[2];
    $field_name = $element[0];
    ...
}

```

# Answer
> 1 votes
I generally do something like this:

```
function gft_enable_display_callback($form, $form_state) {
  // Get the array parents of the triggering element
  $parents = $form_state['triggering_element']['#array_parents'];
  // Pop off the triggering element as we usualy want the one above it
  array_pop($parents);
  // Get the element from the nested array
  $element = drupal_array_get_nested_value($form, $parents);

  return $element; // or we can return $element['someotherfield']
}

```

We can also use the drupal\_array\_get\_nested\_value to retrieve values from form\_state\['values'\] as needed.

# Answer
> 0 votes
I had the same problem. I could solve this by just using

* $element\['#parents'\]\[0\] for the field name
* $element\['#delta'\] for delta

This works with a multivalued field.

# Answer
> 0 votes
Since you can access the submit button form element in the AJAX callback, using `$form_state['triggering_element']`, you could add some identifier to the submit button. For example, in your `hook_widget_form()`:

```
$element['value']['#ajax'] = array(
  'callback' => 'some_ajax_callback',
  'wrapper' => 'location-div',
  'method' => 'replace',
  'effect' => 'fade'
);
$element['value']['#name'] = 'submit_field_name_FIELD_NAME';

```

and then in your AJAX callback:

```
$submit_name = $form_state['triggering_element']['#name'];
$field_name = str_replace('submit_field_name_', '', $submit_name);

```

You could do something similar to get the field delta (i.e. use `submit_field_name_FIELD_NAME_delta_DELTA`, and use some regex or something to extract both). This links the field name and delta directly to the submit button, so even if you had multiple fields and deltas, it would be easy to figure out which one each particular submit button applies to.

# Answer
> 0 votes
Add another property to the form element that contains the delta it had when it was built. In your AJAX callback you can retrieve this delta via the triggering element value.

```
$element[$delta]['value']['#element_index'] = $delta;
$element[$delta]['value']['#ajax'] ...;

```

And in your AJAX callback

```
$delta = $form_state['triggering_element']['#element_index'];

```

This lets you explicitly set and get the delta without relying on pulling it from other data.

# Answer
> 0 votes
This should help for Drupal 8/9:

```
function some_ajax_callback ($form, $form_state) {
  $trigger = $form_state->getTriggeringElement();
  $parents = NestedArray::getValue($form, array_slice($trigger['#array_parents'], 0, -1));
  ...
}

```

Don't forget to include **Drupal\Component\Utility\NestedArray**

---
Tags: 7, ajax, entities
---


# Question
Title: is it posible to get the value of other fields right inside the buildForm() method without having to save configuration?
I have a config form with two select fields. The first one(vocabulary) gets populated automatically without problems with options taken from the available vocabularies for users to pick up one. The problem comes now, the second select field should be automatically populated with taxonomy terms based con the chosen vocabulary...but it DOES NOT work (`$form_state->getValue('vocabulary';`). My quesion is: is it posible to get the value of other fields right inside the buildForm() method without having to save configuration in submitForm() and later get the value from saved configuration?

Here is my buildForm() method:

```
 public function buildForm(array $form, FormStateInterface $form_state) {

    //get all vocabularies available and store their vid in an array(to be passend to select htmm form element)
    //we store vid instead of label because the latest can change at any moment
    $vocabulary = $this->entityTypeManager->getStorage('taxonomy_vocabulary')->loadMultiple();
    $voc_options = ['--none--'];
    foreach ($vocabulary as $voc) {
      // $voc is here an entity object of type Drupal\taxonomy\Entity\Vocabulary;
      // convert the entity object to array and then access the value of vid(should be a better way)
      $voc_options[] = $voc->toArray()['vid'];
    }

    $form['vocabulary'] = [
      '#type' => 'select',
      '#title' => $this->t('Select vocabulary'),
      '#options' => $voc_options,
    ];

    //$vtarget = $form_state->getValue('vocabulary'); // does not work
    $vtarget = 'authors'; // works
    $terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadByProperties(['vid' => $vtarget]);
    //$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($vtarget);
    $sections = [];
    foreach ($terms as $term) {
      $sections[] = $term->label();

    }
    $form['section'] = [
      '#type' => 'select',
      '#title' => $this->t('Select section'),
      '#options' => $sections,
    ];

    return parent::buildForm($form, $form_state);
  }

```

# Answer
Yes, it is possible.

What you need is adding the `#ajax` property to your vocabulary form element.
A good place to look for an example is the Examples for Developers project, which contains the `DependentDropdown` class.
> 0 votes

---
Tags: entities, forms, taxonomy-terms, configuration
---


# Question
Title: theme_suggestions_html_alter not being picked
I'm trying to implement a custom template html--front--anonymous.html.twig which replaces html.html.twig. The suggestion is being showed, but its file is not being picked.

my\_theme.theme

```
function MY_THEME_theme_suggestions_html_alter(&$suggestions, $variables) {
    if (\Drupal::currentUser()->isAnonymous()) {
        if (\Drupal::service('path.matcher')->isFrontPage()) {
            $suggestions[] = 'html--front--anonymous';
        }
    }
}

```

# Answer
Suggestions need to use underscores rather than dashes:

```
$suggestions[] = 'html__front__anonymous';

```
> 1 votes

---
Tags: hooks, theming
---


# Question
Title: How to translate the administrative area in an address field?
I am currently trying to change the confirmation email sent to purchasers after checkout to Japanese, but I am stuck because I don't know how to change only the arrowed part of the image, which shows the prefecture, to Japanese. Does anyone know how to make this part Japanese? This may be a very elementary question, but I have very little experience in web development and there are very few resources in Japanese on drupal commerce, so I have no idea what to do.

# Answer
Drupal Commerce uses the Address module for handling addresses.

In Address fields, Japanese prefectures correspond to **Administrative area (e.g. State or Province)**.

I just installed the Address module in a Japanese language Drupal 10 site and the prefectures were translated correctly by default. So, it seems you failed to get the translations when you installed the module.

Usually, contrib module translations are bundled as PO files with the module. However, for the administrative divisions in the Address module, the commerceguys/addressing library is used, which provides its own translations.

There are docs for modifying the translations, but since the prefecture should already be translated, I would do the following:

* Make sure that you installed Commerce/the Address module with composer.
* Check the translation settings at `/admin/config/regional/translate/settings`. Make sure that the translation source is *Drupal translation server and local files*.
* If the site has multiple languages, check the language settings at `/admin/config/regional/language/detection` and ensure that the language is being correctly set to Japanese for the logged-in account.
> 3 votes

---
Tags: commerce
---


# Question
Title: How to create entity translations using JSON:API or REST API?
I working on a headless localized site in which entities need to be synced regularly from an external source.

During the sync process, I need to create new entities and their associated translations.

I found out that JSON:API doesn't support this. Are there any workarounds to achieve this in JSON:API?

Is it something that can be achieved with the REST API? If so could you point me to some documentation?

# Answer
Drupal's implementations of JSON:API and REST do not support creation of translated entities at this time as far as I know.

**Create Entity Translations**

You could try hacking a custom JSON-RPC route or JSON:API Resource, but these are not really intended for entity creation and you would have to do a lot of coding.

If possible, I would use Feeds to sync the entities and their translations. You will need to expose the content to sync in a format that Feeds supports:

* CSV
* XML
* OPML
* RSS/Atom
* HTML/JSON

There isn't a lot of documentation on multilingual Feeds but it does work.

**Create UI Translations**

This wasn't in your question but just as a note. You can't create UI translations via JSON:API now, either. One fix is to export your translations as a PO file and import the file with drush:

```
drush locale:import my_two_letter_language_code my_path/ja.po --type=customized --override=customized

```
> 1 votes

---
Tags: i18n-l10n
---


# Question
Title: How do I install commerceguys/addressing and commerceguys/int
I am trying to install drupal commerce i have put the files in their proper place (folders etc) but its like i didn tdo anything because it is not working for me. What should i do

# Answer
> 2 votes
As per the project page, "Commerce 2.x should only be installed via Composer", and via the Drupal commerce documentation site:

```
cd /path/to/drupal8
composer require "drupal/commerce"

```

Otherwise, if you are using Ludwig, you could try following the installation instructions for Drupal Commerce with Ludwig.

---
Tags: commerce
---


# Question
Title: How to get rid of "The %field_name field needs to be uninstalled."
I have a message in the `/admin/reports/status` page regarding some fields.

FYI, those are custom fields that I have deleted

Here is the message:

```
The %field_name field needs to be uninstalled.

```

To solve this, I ran cron, I `drush cr` and finally `drush entup` =\>but this last step display the following error:

```
In DiscoveryTrait.php line 52: The "field_item:mwd" plugin does not exist.

```

`mwd` is the id of custom field type for which there is a message in the status page...

Here is the Plugin definition and the Class definition of this custom field

```
 * @FieldType(
 *   id = "mwd",
 *   label = @Translation("Days of week in a Month for a user"),
 *   description = @Translation("Store all days of week in a month for a user."),
 *   category = @Translation("Calendar"),
 *   default_formatter = "mwd_ds_formatter",
 *   default_widget = "mwd_ds_widget",
 * )
 */
class MWDItem extends FieldItemBase implements FieldItemInterface{...

```

I have created an instance of this field type (with the GUI of drupal) and added it to a content type. This is this field which needs to be uninstalled if I conforms to the status page message.

Unfortunately I can't get rid of it: impossible to remove this warning in the /admin/reports/status page

# Answer
Here is a snippet which you could use in `hook_update` or `drush php` context. However it will only work if the tables are still there - while this is rare, it can happen - you're in this situation because something didn't happen correctly, so expect the unexpected.

```
$manager = \Drupal::entityDefinitionUpdateManager();
$definition = $manager->getFieldStorageDefinition("field_blah", "node");
$manager->uninstallFieldStorageDefinition($definition);

```

It the tables do not exist then the field cannot be programmatically uninstalled, as Drupal will try to query them. In this case, adding and removing the field through the UI is the easiest way, per other answers.
> 2 votes

# Answer
I had the same problem with a custom field. I solved it by **creating the broken field in the UI once again and deleting it afterwards:** The error went away. Just take care of the name of the field (without the string "field\_" at the beginning).
> 1 votes

---
Tags: 8
---


# Question
Title: How to Sort Views results based on two fields
I have a view that lists nodes of type Article. Each Article includes a boolean field and a date field. Neither field is required. I want to sort the list of articles so that the first articles are the ones with the boolean field checked **and** with a date that is in the future (sorted by published date – newest first) followed by all the other articles sorted by published date (newest first) (which includes ones without the boolean checked and ones that have the boolean checked but the date is in the past). The list has a pager showing 5 articles and there are approx 3,000 articles currently.

There is no way to create a sort like this in Views. I can separately create the two views above no problem, but I can't seem to figure out how to merge them into one list. I have tried using a View Attachment to attach a view of the checked and future articles above the other articles but the attachment appears on all pages of the pager. And if there are more that 5 articles in the attachment, then they are the only ones you ever see when paging.

So from what I can see I need to use a views\_query\_alter hook or maybe a views\_data\_alter hook to programmatically alter the sort of query but coding it not my forte and I'm a bit lost. I've created mymodule.info.yml and mymodule.views\_execution.inc and placed the two of them in a folder in modules-\>custom. My info file is

```
type: module
name: 'Views Article Custom Sort'
description: 'Custom Sorting of Articles'
package: 'custom'
core_version_requirement: ^9 || ^10

dependencies:
  - views

```

My mymodule.views\_execution.inc

```
<?php

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

function article_custom_sort_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'article_list' && $view->current_display == 'block_1') {
    $query->addField(
    NULL,
    'CASE WHEN (COALESCE(field_display_in_sticky_until, 0) >= CURRENT_TIMESTAMP AND COALESCE(field_stick_to_top_of_list, 0) == TRUE)',
    'sticky'
    );
    $query->addOrderBy(
    NULL,
    NULL,
    'ASC',
    'sticky'
    );
  }
}

```

Firstly, the module is not showing on my Module page, so I can't enable it and I'm fairly sure my code is full of errors. If anyone can help me, I'd really appreciate it.

Thanks

F

P.S. I had thought that maybe an alternative is to have the boolean unchecked if the date field is in the past when cron is run, but I have no idea where to start with coding that one. If I could get that working, then I could simply sort the view by the boolean field followed by published date. Sadly the module Scheduler only publishes and Unpublishes nodes on cron, it doesn't offer options to alter other fields.

# Answer
> 0 votes
In case anyone comes across this question, I used a different route to solve my problem. Rather than trying to merge two Views into one list, I use the module ECA: Event - Condition - Action to unselect the Boolean Field on Cron, so now I can sort my View by the Boolean Field followed by sorting by Published Date.

ECA is an excellent module by the way. It allows me to execute a View and then perform an action on the Views Results. It's similar to Rules, except it actually works with D9/D10. So I created a View that lists Nodes of type Article that have the Boolean Field selected and have a date in the past in the Custom Date Field. On Cron, the View is executed, and the Boolean Field is unselected and saved in each Node in the Views Result. So after cron, the only Articles that have the Boolean Field selected are the ones with the Custom Date in the future.

---
Tags: views
---


# Question
Title: Why doesn’t "composer update" upgrade this site?
I'm running Drupal 9.59. I tried following the instructions on drupal.org for upgrading to Drupal 10. The steps with `composer --no-update` went fine. The actual update step yields:

> Loading composer repositories with package information
> Info from https://repo.packagist.org: #StandWithUkraine
> Updating dependencies
> Your requirements could not be resolved to an installable set of packages.
>
> Problem 1
>
> * drupal/core 8.0.0-beta6 requires doctrine/common dev-master#a45d110f71c323e29f41eb0696fa230e3fa1b1b5 -\> found doctrine/common\[dev-remove-int-cast, 2.1.3, ..., 2.13.x-dev, 3.0.0, ..., 3.5.x-dev\] but it does not match the constraint.
> * drupal/core\[8.0.0-beta13, ..., 8.0.0-beta15\] require guzzlehttp/guzzle dev-master#1879fbe853b0c64d109e369c7aeff09849e62d1e -\> found guzzlehttp/guzzle\[v1.0.3, v1.0.4, v2.0.0, ..., v2.8.8, v3.0.0, ..., v3.8.1, 4.0.0-rc.1, ..., 4.x-dev, 5.0.0, ..., 5.3.x-dev, 6.0.0, ..., 6.5.x-dev, 7.0.0-beta.1, ..., 7.7.x-dev\] but it does not match the constraint.
> * zendframework/zend-feed\[dev-master, dev-develop, 2.11.0, ..., 2.13.x-dev\] require php ^5.6 || ^7.0 -\> your php version (8.1.16) does not satisfy that requirement.
> * laminas/laminas-feed\[2.12.0, ..., 2.12.x-dev\] require php ^5.6 || ^7.0 -\> your php version (8.1.16) does not satisfy that requirement.
> * symfony/psr-http-message-bridge\[v1.1.0, ..., 1.1.x-dev\] require php ^5.3.3 || ^7.0 -\> your php version (8.1.16) does not satisfy that requirement.
> * symfony-cmf/routing\[1.4.0-RC1, ..., 1.4.x-dev\] require php ^5.3.9|^7.0 -\> your php version (8.1.16) does not satisfy that requirement.
> * symfony/psr-http-message-bridge\[v1.2.0, ..., v1.3.0\] require php ^7.1 -\> your php version (8.1.16) does not satisfy that requirement.
> * drupal/core\[8.9.11, ..., 8.9.x-dev\] require php ^7.0.8 -\> your php version (8.1.16) does not satisfy that requirement.
> * drupal/core\[9.0.10, ..., 9.0.x-dev\] require php ^7.3 -\> your php version (8.1.16) does not satisfy that requirement.
> * laminas/laminas-feed\[2.13.0, ..., 2.14.x-dev\] require php ^7.3 || ~8.0.0 -\> your php version (8.1.16) does not satisfy that requirement.
> * Root composer.json requires drupal/token\_filter ^1.4 -\> satisfiable by drupal/token\_filter\[1.4.0, 1.x-dev\].
> * drupal/core-recommended 10.0.0-alpha1 requires drupal/core 10.0.0-alpha1 -\> satisfiable by drupal/core\[10.0.0-alpha1\].
> * Conclusion: don't install drupal/core 10.0.0-alpha1 (conflict analysis result)
> * drupal/core-recommended 10.0.0-alpha2 requires drupal/core 10.0.0-alpha2 -\> satisfiable by drupal/core\[10.0.0-alpha2\].
> * Conclusion: don't install drupal/core 10.0.0-alpha2 (conflict analysis result)
> * drupal/core-recommended 10.0.0-alpha3 requires drupal/core 10.0.0-alpha3 -\> satisfiable by drupal/core\[10.0.0-alpha3\].
> * Conclusion: don't install drupal/core 10.0.0-alpha3 (conflict analysis result)
> * drupal/core-recommended 10.0.0-alpha4 requires drupal/core 10.0.0-alpha4 -\> satisfiable by drupal/core\[10.0.0-alpha4\].
> * Conclusion: don't install drupal/core 10.0.0-alpha4 (conflict analysis result)
> * drupal/core-recommended 10.0.0-alpha5 requires drupal/core 10.0.0-alpha5 -\> satisfiable by drupal/core\[10.0.0-alpha5\].
> * Conclusion: don't install drupal/core 10.0.0-alpha5 (conflict analysis result)
> * drupal/core-recommended 10.0.0-alpha6 requires drupal/core 10.0.0-alpha6 -\> satisfiable by drupal/core\[10.0.0-alpha6\].
> * Conclusion: don't install drupal/core 10.0.0-alpha6 (conflict analysis result)
> * drupal/core-recommended 10.0.0-alpha7 requires drupal/core 10.0.0-alpha7 -\> satisfiable by drupal/core\[10.0.0-alpha7\].
> * Conclusion: don't install drupal/core 10.0.0-alpha7 (conflict analysis result)
> * drupal/core-recommended 10.1.0-alpha1 requires drupal/core 10.1.0-alpha1 -\> satisfiable by drupal/core\[10.1.0-alpha1\].
> * Conclusion: don't install drupal/core 10.1.0-alpha1 (conflict analysis result)
> * drupal/core-recommended 10.0.0-beta1 requires drupal/core 10.0.0-beta1 -\> satisfiable by drupal/core\[10.0.0-beta1\].
> * Conclusion: don't install drupal/core 10.0.0-beta1 (conflict analysis result)
> * drupal/core-recommended 10.0.0-beta2 requires drupal/core 10.0.0-beta2 -\> satisfiable by drupal/core\[10.0.0-beta2\].
> * Conclusion: don't install drupal/core 10.0.0-beta2 (conflict analysis result)
> * drupal/core-recommended 10.1.0-beta1 requires drupal/core 10.1.0-beta1 -\> satisfiable by drupal/core\[10.1.0-beta1\].
> * Conclusion: don't install drupal/core 10.1.0-beta1 (conflict analysis result)
> * drupal/core-recommended 10.0.0-rc1 requires drupal/core 10.0.0-rc1 -\> satisfiable by drupal/core\[10.0.0-rc1\].
> * Conclusion: don't install drupal/core 10.0.0-rc1 (conflict analysis result)
> * drupal/core-recommended 10.0.0-rc2 requires drupal/core 10.0.0-rc2 -\> satisfiable by drupal/core\[10.0.0-rc2\].
> * Conclusion: don't install drupal/core 10.0.0-rc2 (conflict analysis result)
> * drupal/core-recommended 10.0.0-rc3 requires drupal/core 10.0.0-rc3 -\> satisfiable by drupal/core\[10.0.0-rc3\].
> * Conclusion: don't install drupal/core 10.0.0-rc3 (conflict analysis result)
> * drupal/core-recommended 10.1.0-rc1 requires drupal/core 10.1.0-rc1 -\> satisfiable by drupal/core\[10.1.0-rc1\].
> * Conclusion: don't install drupal/core 10.1.0-rc1 (conflict analysis result)
> * drupal/core-recommended 10.0.0 requires drupal/core 10.0.0 -\> satisfiable by drupal/core\[10.0.0\].
> * Conclusion: don't install drupal/core 10.0.0 (conflict analysis result)
> * 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/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.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\[8.4.0-alpha1, ..., 8.7.7\] require symfony-cmf/routing ^1.4 -\> satisfiable by symfony-cmf/routing\[1.4.0-RC1, ..., 1.4.x-dev\].
> * drupal/core\[8.2.0-beta1, ..., 8.3.x-dev\] require symfony-cmf/routing ~1.4 -\> satisfiable by symfony-cmf/routing\[1.4.0-RC1, ..., 1.4.x-dev\].
> * drupal/core\[9.0.0-alpha1, ..., 9.0.0-alpha2\] require symfony/psr-http-message-bridge ^1.2.0 -\> satisfiable by symfony/psr-http-message-bridge\[v1.2.0, v1.3.0\].
> * drupal/core\[8.7.8, ..., 8.9.10\] require symfony/psr-http-message-bridge ^1.1.2 -\> satisfiable by symfony/psr-http-message-bridge\[v1.1.2, 1.1.x-dev, v1.2.0, v1.3.0\].
> * drupal/core\[8.8.0-alpha1, ..., 8.8.x-dev\] require zendframework/zend-feed ^2.12 -\> satisfiable by laminas/laminas-feed\[2.12.0, ..., 2.21.x-dev\], zendframework/zend-feed\[2.12.0, 2.12.x-dev, 2.13.x-dev\].
> * drupal/core-recommended 10.1.x-dev requires drupal/core 10.1.x-dev -\> satisfiable by drupal/core\[10.1.x-dev\].
> * Conclusion: don't install drupal/core 10.1.x-dev (conflict analysis result)
> * drupal/token\_filter\[1.4.0, ..., 1.x-dev\] require drupal/core ^8 || ^9 -\> satisfiable by drupal/core\[8.0.0-beta6, ..., 8.9.x-dev, 9.0.0-alpha1, ..., 9.5.x-dev\].
> * You can only install one version of a package, so only one of these can be installed: drupal/core\[8.0.0-beta6, ..., 8.9.x-dev, 9.0.0-alpha1, ..., 9.5.x-dev, 10.0.0-alpha1, ..., 10.1.x-dev\].
> * You can only install one version of a package, so only one of these can be installed: drupal/core\[8.0.0-beta12, ..., 8.9.x-dev, 9.0.0-alpha1, ..., 9.5.x-dev, 10.0.0-alpha1, ..., 10.1.x-dev\].
> * You can only install one version of a package, so only one of these can be installed: drupal/core\[8.1.2, ..., 8.9.x-dev, 9.0.0-alpha1, ..., 9.5.x-dev, 10.0.0-alpha1, ..., 10.1.x-dev\].
> * You can only install one version of a package, so only one of these can be installed: drupal/core\[8.1.8, ..., 8.9.x-dev, 9.0.0-alpha1, ..., 9.5.x-dev, 10.0.0-alpha1, ..., 10.1.x-dev\].
> * You can only install one version of a package, so only one of these can be installed: drupal/core\[8.7.0-alpha1, ..., 8.9.x-dev, 9.0.0-alpha1, ..., 9.5.x-dev, 10.0.0-alpha1, ..., 10.1.x-dev\].
> * drupal/core-recommended 10.0.x-dev requires drupal/core 10.0.x-dev -\> satisfiable by drupal/core\[10.0.x-dev\].
> * Root composer.json requires drupal/core-recommended ^10 -\> satisfiable by drupal/core-recommended\[10.0.0-alpha1, ..., 10.1.x-dev\].
>
> composer \[update\] failed, composer command failed: exit status 2. stderr=

I'm stumped. I tried removing the lock file, but no difference.

# Answer
> 2 votes
I would start by fixing each issue, starting with “drupal/token\_filter\[1.4.0, ..., 1.x-dev\] require drupal/core ^8 || ^9”.

As far as I know all upgrade guides recommend updating contributed modules first and using readiness reports.

# Answer
> -1 votes
I would recommend doing a `composer update drupal/core-recommended -W` (with all dependencies). Seems the guzzle items aren't marked for update. Also make sure your contributed modules are updated to the latest versions as well. Also a nice `composer why-not drupal/core-recommended:^10` may give more information. Finally if that doesn't work, install drupal/upgrade\_status and run a report which may tell more.

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


# Question
Title: functional test: Schema errors but Schema is correct
I have a settings form in my custom module and functional test of this form.

I added new field to form

```
$form['unblockable_roles'] = [
  '#type' => 'checkboxes',
  '#title' => $this->t('Users cannot block another users with these roles'),
  '#options' => $roles_options,
  '#default_value' => $config->get('unblockable_roles') ?: [],
];

```

Updated schema file:

```
mymodule.settings:
  type: config_object
  label: 'My module settings'
  mapping:
    allowed_roles:
      label: 'Allow send messages for these roles'
      type: sequence
      sequence:
        type: string
        label: 'Role ID'
    unblockable_roles:
      label: 'Users cannot block another users with these roles'
      type: sequence
      sequence:
        type: string
        label: 'Role ID'

```

The "config inspector" module has no errors with new field schema, but phpunit says:

"Drupal\Core\Config\Schema\SchemaIncompleteException: Schema errors for mymodule.settings with the following errors: mymodule.settings:unblockable\_roles missing schema in Drupal\Core\Config\Development\ConfigSchemaChecker-\>onConfigSave() (line 94 of core/lib/Drupal/Core/Config/Development/ConfigSchemaChecker.php)."

The same field "allowed\_roles" works fine.

I cleared caches, stop-start docker, but without success.

if I use "protected $strictConfigSchema = FALSE;" my test is success. Form values successfully saved.

# Answer
> 0 votes
My fault. I use this patch to speedup functional tests. It cause my problem.

# Answer
> 1 votes
I have had this error before when writing functional unit tests, for me it wasn't that the schema was wrong in the custom module settings it was that the schema was wrong and/or missing in the config install files so needed to either change that to match the module or change the module to match what is in config install files. or import the config installs into your module.

---
Tags: forms, 9, testing
---


# Question
Title: Webform File Attachments Uploaded But Not Linked to Submission
I have Webform 6.1.5 running in a D9.5 website, that has lots of other contrib modules.

Using the Webform Attachments sub-module I have some simple forms that require files to be attached to the submission. The files are being uploaded \[to the temporary `_sid_` folder\] but not to the submission folder once the webform is submitted, nor are the files referenced in the submission. If 'preview' is enabled, the files are not visible in the preview.

Conversely, using the Webform 'Test' function, sample file attachments are uploaded and added to the submission, which is the correct behaviour.

I cannot reproduce this behaviour on a vanilla D9.5 installation, so it looks like there's a conflict \[with another module\] that's crept in, and I'm not sure how best to approach this. So I'd welcome any suggestions.

Things I have checked:

* Private and Temporary files folder permissions - all fine
* Private folder path changed from relative to absolute - no change
* Disabled multi-language and translation modules and config (see https://www.drupal.org/project/drupal/issues/2797639 \- now fixed, but you never know).
* Changed permissions (both via Webform Access and core 'View own webform' permission)
* Added (private) file upload to Content type - works fine and is downloadable.
* Looked at other file upload systems - DropzoneJS and Plupload - but additional modules required to work with Webform.
* Installed all the Webform libraries (rather than coming from CDN). No change
* Checked PHP and DB resource settings (max\_allowed\_packet, max\_input\_vars, post\_upload\_size etc) - seem adequate and have added a bit more to check.
* Have enabled Webform 'Debug' handler - file fields in submission are empty
* No JS errors posted in the Console (EDIT: also disabled JS in browser; no change observed)
* Have tried disabling lots of modules, especially those that could have an impact on file handling or forms; however, not much left now and no change observed.
* There's this issue that looks similar (https://www.drupal.org/node/3118815) but there was never any follow up.
* EDIT: also tried system in default front-end and admin themes
* EDIT: Also uninstalled Webform module, then re-installed and created simple form with File Upload field. No change - so clearly not an issue with Webform default config.

I'm not sure where to to insert some breakpoints in the module code. Looking at `webform/src/WebformSubmissionInterface.php` it looks like all the functionality is inherited from Core *ContentEntityInterface* and *EntityOwnerInterface*... or whether this is a JS issue.

# Answer
> -1 votes
Unfortunately, there is no answer.

I ripped the entire site apart, deleting most content and config, leaving just Webform and Core modules enabled, yet the problem persisted. Then I deleted the contents of all /core, /vendor, /libraries and /modules/contrib directories, then rebuilt via Composer. A few updates were pulled down for contrib and vendor files, then the file upload worked correctly.

Thank you for those that helped or suggested ways to tackle this.

---
Tags: webforms, files
---


# Question
Title: Attribute Array to String Conversion Error
I'm getting this error now on most pages within a complex 9.5.3 site running PHP8.1:

> Array to string conversion in Drupal\Core\Template\AttributeArray-\>\__toString() (line 77 of core/lib/Drupal/Core/Template/AttributeArray.php)

The error trace isn't really helping nail this down. Using the suggestion at AttributeArray fails to implode #allowed\_tags to investigate the problem attribute arrays, many of them are toolbar-tab related, but some are flagging up problems with Views embedded in the page, and some are just field-related, for example:

```
0 => string (6) "hidden"
1 => string (22) "contextual-toolbar-tab"
2 => string (11) "toolbar-tab"
3 => boolean false

```

and

```
#markup => string (6) "Argyll"
 #allowed_tags => array (12)
  0 => string (1) "a"
  1 => string (2) "em"
  2 => string (6) "strong"
  3 => string (4) "cite"
  4 => string (10) "blockquote"
  5 => string (4) "code"
  6 => string (2) "ul"
  7 => string (2) "ol"
  8 => string (2) "li"
  9 => string (2) "dl"
  10 => string (2) "dt"
  11 => string (2) "dd"

```

and

```
0 => Drupal\Core\Template\AttributeString#180606 (2)
Properties (2)
  protected value -> string (29) "view-field-photo-table-column"
  protected name -> string (2) "id"

```

I think I've ruled out a theme issue (admin is Claro \> Gin; front end is stable9 \> Custom) and disabled lots of potential problem modules (admin\_toolbar, devel etc), but not certain that it's a theme issue, or a rogue module. With the snippet in `__toString()` errors are flagged up on virtually every page.

But I'm just lost as to how to nail this down, or even where to start looking.

# Answer
Short answer - be wary of using the Shield module https://www.drupal.org/project/shield

If you look through the issue queue there are many problems where module hooks, caches or attributes can become corrupted.

As soon as the module was uninstalled, no errors were observed.
> 0 votes

---
Tags: theming, debugging
---


# Question
Title: which hook to change the node order in a view?
I have a custom view but now I want to put the nodes created by a specific user role on top.

I want to do this using code so I can easily implement this throughout multiple web pages.

I'm thinking to alter the query or to put an array sort before the nodes are rendered.

But I don't know which hook would be useful for this.

**edit:** using hook\_views\_pre\_render as suggested by Jimajamma

```
function vacancies_views_pre_render(&$view) {
  dsm($view->result);
  $view->result = array_reverse($view->result);
  dsm($view->result);
}

```

But that doesn't change the order of the nodes in the view ( putting a `dsm($view);` in the if statement ensures me that it is this view that is called. )

# Answer
> 6 votes
You can use View's prerender hook to modify the view's results anyway you want.

For example,

```
function YOURMODULE_views_pre_render(&$view) {

   if ($view->name=='xyzzy') {

      // modify/sort the $view->result array to your heart's content here
      // for example, reverse it...
      $view->result=array_reverse($view->result);

   }

 }

```

Basically `$view->result` is an array of row results, so, just go through it and grab the rows you want first, then follow that up with the remaining rows.

ADDITION:

I created a quick view and did the above reversing and it certainly reversed the order so I am not sure what you are doing ever so slightly wrong to not see similar behavior on your site.

# Answer
> 1 votes
Since this is still high on the list of search results: in Drupal 9 (unsure of which versions this , the `index` property of each view row determines the order, not the array of rows itself. So, if you get the row objects ordered to your liking, you can do something like this:

```
// Optionally set the array keys to start at zero and count up first.
$my_ordered_results_array = $array_values($my_ordered_results_array);

// Iterate over the rows and set index values.
foreach ($my_ordered_results_array as $key => $row) {
  $row->index = $key;
}

```

# Answer
> 0 votes
I came across this looking for a possible solution using Drupal 10.1, and I got something that seems to be working well. I believe this will also work on Drupal 9, but I have personally not tested it. I combined a couple of the previous solutions together:

```
function vacancies_views_pre_render(&$view) {
  // Reverse the resulting array order
  $newResultOrder = array_reverse($view->result);

  // Now we have the new order so we can set the indexes for each result row.
  $newResultOrder = array_values($newResultOrder);
  foreach ($newResultOrder as $key => $row) {
    // Set index for each result item since it is now in the correct order.
    $row->index = $key;
  }

  $view->result = $newResultOrder;
}

```

I also created a ViewExecutable object that I was able to change the order (in my own case) based upon contextual items in an array. You could replace this with whatever order you need them. This was tested and is working on Drupal 10.1 at the moment:

```
$view = Views::getView('whatever_view_machine_name');

if (is_object($view)) {
  $view->setArguments($argsIfYouNeedThem);
  $view->setDisplay('default');
  $view->preExecute();
  $view->execute();

  // If $resultOrder was built, handle re-ordering.
  // This checks if there was a result order from context (code not shown),
  // but this array could be any array with Node ID values in
  // the order you need the final results to be in.
  if ($resultOrder) {
    $newResultOrder = [];
    // Get the current results.
    $results = $view->result;

    // Loop through the final resulting Node ID order.
    // (from my example, $resultOrder is an array of Node IDs from context).
    foreach ($resultOrder as $newResultNid) {
      // Loop through view results to compare order of IDs.
      foreach ($results as $result) {
        // Get the Node ID so we can compare against our $newResultNid
        $currentResultNid = $result->nid;

        if ($currentResultNid == $newResultNid) {
          $newResultOrder[] = $result;
          break;
        }
      }
    }

    // Now we have the new order so we can set the indexes for each result row.
    $newResultOrder = array_values($newResultOrder);
    foreach ($newResultOrder as $key => $row) {
      // Set index for each result item since it is now in the correct order.
      $row->index = $key;
    }

    $view->result = $newResultOrder;
  }

  // Since I am rendering in a twig template, we are setting a variable
  // for the view results to be passed back.
  $variables['rc_view'] = $view->buildRenderable('default', $args);
}

```

---
Tags: hooks, views
---


# Question
Title: Why does this custom CKEditor plugin produce the toolbarview-item-unavailable error?
I have 2 modules in active development with the purpose of learning how to develop custom plugins for the Ckeditor5 wysiwyg.

On both modules, I am stuck on the following problem. The error pasted below is from the second module :

```
ckeditor5-dll.js?v=35.4.0:5 toolbarview-item-unavailable {item: 'testPlugin'}
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-toolbarview-item-unavailable

```

Clearing indicated my plugin cannot be included in the toolbar.

With the module enabled, my ***testPlugin*** module is visible and added to my active toolbar in the text-formats configuration area as show below:

However, when on a node-edit form the plugin icon is not rendered in the toolbar due to the javascript error included above :

The full code for the second module is located here for your reference **but** I pasted some essential code below for anyone who wants to help or refer to this question in the future:

**testPlugin.ckeditor5.yml**

```
testplugin_embeddedContent:
  provider: testplugin
  ckeditor5:
    plugins:
      - embeddedContent.EmbeddedContent
    config:
#      embeddedContent:
      testPlugin:
        openDialog:
          func:
            name: Drupal.ckeditor5.openDialog
            invoke: false
        dialogSettings:
          height: 75%
          dialogClass: embedded-content-widget-modal
          title: Create embedded content
  drupal:
    label: Test Plugin
    elements:
      - <embedded-content>
      - <embedded-content data-plugin-config data-plugin-id>
    admin_library: testplugin/admin.embedded_content
    class: Drupal\testplugin\Plugin\CKEditor5Plugin\EmbeddedContent
    library: testplugin/embedded_content
    toolbar_items:
#      embeddedContent:
      testPlugin:
        label: My Test Plugin
    conditions:
      filter: testplugin

```

**index.js:**

```
import EmbeddedContent from "./embeddedcontent";

/**
 * @private
 */
export default {
  EmbeddedContent: EmbeddedContent
};

```

**embeddedcontent.js:**

```
import { Plugin } from 'ckeditor5/src/core';
import EmbeddedContentEditing from './embeddedcontentediting';
import EmbeddedContentUI from './embeddedcontentui';

/**
 * Main entry point to the embedded content.
 */
export default class EmbeddedContent extends Plugin {

  /**
   * @inheritdoc
   */
  static get requires() {
    return [
      EmbeddedContentEditing,
      EmbeddedContentUI
    ];
  }

  /**
   * @inheritdoc
   */
  static get pluginName() {
    // return 'embeddedContent';
    return 'testPlugin';
  }
}

```

**embeddedcontentediting.js:**

```
import {Plugin} from 'ckeditor5/src/core';
import {toWidget, Widget} from 'ckeditor5/src/widget';
import EmbeddedContentCommand from './embeddedcontentcommand';

/**
 * Embedded content editing functionality.
 */
export default class EmbeddedContentEditing extends Plugin {

  /**
   * @inheritdoc
   */
  static get requires() {
    return [Widget];
  }

  /**
   * @inheritdoc
   */
  init() {
    this.attrs = {
      embeddedContentPluginConfig: 'data-plugin-config',
      embeddedContentPluginId: 'data-plugin-id',
    };
    const options = this.editor.config.get('embeddedContent');
    if (!options) {
      return;
    }
    const {previewURL, themeError} = options;
    this.previewUrl = previewURL;
    this.themeError =
      themeError ||
      `
      <p>${Drupal.t(
        'An error occurred while trying to preview the embedded content. Please save your work and reload this page.',
      )}<p>
    `;

    this._defineSchema();
    this._defineConverters();

    this.editor.commands.add(
      'embeddedContent',
      new EmbeddedContentCommand(this.editor),
    );
  }

  /**
   * Fetches the preview.
   */
  async _fetchPreview(modelElement) {
    const query = {
      plugin_id: modelElement.getAttribute('embeddedContentPluginId'),
      plugin_config: modelElement.getAttribute('embeddedContentPluginConfig'),
    };
    const response = await fetch(
      `${this.previewUrl}?${new URLSearchParams(query)}`
    );
    if (response.ok) {
      return await response.text();
    }

    return this.themeError;
  }

  /**
   * Registers embeddedContent as a block element in the DOM converter.
   */
  _defineSchema() {
    const schema = this.editor.model.schema;
    schema.register('embeddedContent', {
      allowWhere: '$block',
      isObject: true,
      isContent: true,
      isBlock: true,
      allowAttributes: Object.keys(this.attrs),
    });
    this.editor.editing.view.domConverter.blockElements.push('embedded-content');
  }

  /**
   * Defines handling of drupal media element in the content lifecycle.
   *
   * @private
   */
  _defineConverters() {
    const conversion = this.editor.conversion;

    conversion
      .for('upcast')
      .elementToElement({
        view: {
          name: 'embedded-content',
        },
        model: 'embeddedContent',
      });

    conversion
      .for('dataDowncast')
      .elementToElement({
        model: 'embeddedContent',
        view: {
          name: 'embedded-content',
        },
      });
    conversion
      .for('editingDowncast')
      .elementToElement({
        model: 'embeddedContent',
        view: (modelElement, {writer}) => {
          const container = writer.createContainerElement('figure');
          return toWidget(container, writer, {
            label: Drupal.t('Embedded content'),
          });

        },
      })
      .add((dispatcher) => {
        const converter = (event, data, conversionApi) => {
          const viewWriter = conversionApi.writer;
          const modelElement = data.item;
          const container = conversionApi.mapper.toViewElement(data.item);
          const embeddedContent = viewWriter.createRawElement('div', {
            'data-embedded-content-preview': 'loading',
            'class': 'embedded-content-preview'
          });
          viewWriter.insert(viewWriter.createPositionAt(container, 0), embeddedContent);
          this._fetchPreview(modelElement).then((preview) => {
            if (!embeddedContent) {
              return;
            }
            this.editor.editing.view.change((writer) => {
              const embeddedContentPreview = writer.createRawElement(
                'div',
                {'class': 'embedded-content-preview', 'data-embedded-content-preview': 'ready'},
                (domElement) => {
                  domElement.innerHTML = preview;
                },
              );
              writer.insert(writer.createPositionBefore(embeddedContent), embeddedContentPreview);
              writer.remove(embeddedContent);
            });
          });
        };
        dispatcher.on('attribute:embeddedContentPluginId:embeddedContent', converter);
        return dispatcher;
      });

    Object.keys(this.attrs).forEach((modelKey) => {
      const attributeMapping = {
        model: {
          key: modelKey,
          name: 'embeddedContent',
        },
        view: {
          name: 'embedded-content',
          key: this.attrs[modelKey],
        },
      };
      conversion.for('dataDowncast').attributeToAttribute(attributeMapping);
      conversion.for('upcast').attributeToAttribute(attributeMapping);
    });
  }

  /**
   * @inheritdoc
   */
  static get pluginName() {
    return 'embeddedContentEditing';
  }
}

```

**embeddedcontentui.js:**

```
import { Plugin } from 'ckeditor5/src/core';
import { ButtonView } from 'ckeditor5/src/ui';
import EmbeddedContentIcon from '../theme/icons/embeddedcontent.svg';
import {DomEventObserver} from "ckeditor5/src/engine";

/**
 * Ckeditor5 doesn't support double click out of the box.
 * Register it here so we can use it.
 *
 * @Todo Replace double click with a balloon style popup menu to
 *   edit the embedded content item.
 */
class DoubleClickObserver extends DomEventObserver {
  constructor( view ) {
    super( view );
    this.domEventType = 'dblclick';
  }

  onDomEvent( domEvent ) {
    this.fire( domEvent.type, domEvent );
  }
}

/**
 * Provides the embedded content button and editing.
 */
export default class EmbeddedContentUI extends Plugin {

  init() {
    const editor = this.editor;
    const options = this.editor.config.get('embeddedContent');
    if (!options) {
      return;
    }

    const { dialogURL, openDialog, dialogSettings = {} } = options;
    if (!dialogURL || typeof openDialog !== 'function') {
      return;
    }
    editor.ui.componentFactory.add('embeddedContent', (locale) => {
      const command = editor.commands.get('embeddedContent');
      const buttonView = new ButtonView(locale);

      buttonView.set({
        label: Drupal.t('Embedded content'),
        icon: EmbeddedContentIcon,
        tooltip: true,
      });

      // Bind the state of the button to the command.
      buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');

      this.listenTo(buttonView, 'execute', () => {
        openDialog(
          dialogURL,
          ({ attributes }) => {
            editor.execute('embeddedContent', attributes);
          },
          dialogSettings,
        );
      });

      return buttonView;
    });

    const view = editor.editing.view;
    const viewDocument = view.document;

    view.addObserver( DoubleClickObserver );

    editor.listenTo( viewDocument, 'dblclick', ( evt, data ) => {
      const modelElement = editor.editing.mapper.toModelElement( data.target);
      if(modelElement && typeof modelElement.name !== 'undefined' && modelElement.name === 'embeddedContent'){
        const query = {
          plugin_id: modelElement.getAttribute('embeddedContentPluginId'),
          plugin_config: modelElement.getAttribute('embeddedContentPluginConfig'),
        };
        openDialog(
          `${dialogURL}?${new URLSearchParams(query)}`,
          ({ attributes }) => {
            editor.execute('embeddedContent', attributes);
          },
          dialogSettings,
        );
      }
    } );
  }
}

```

**embeddedcontentcommand.js:**

```
import { Command } from 'ckeditor5/src/core';

/**
 * Creates embedded content
 */
function createEmbeddedContent(writer, attributes) {
  return writer.createElement('embeddedContent', attributes);
}

/**
 * Command for inserting <embedded-content> tag into ckeditor.
 */
export default class EmbeddedContentCommand extends Command {
  execute(attributes) {
    const embeddedContentEditing = this.editor.plugins.get('embeddedContentEditing');

    // Create object that contains supported data-attributes in view data by
    // flipping `DrupalMediaEditing.attrs` object (i.e. keys from object become
    // values and values from object become keys).
    const dataAttributeMapping = Object.entries(embeddedContentEditing.attrs).reduce(
      (result, [key, value]) => {
        result[value] = key;
        return result;
      },
      {},
    );

    // \Drupal\media\Form\EditorMediaDialog returns data in keyed by
    // data-attributes used in view data. This converts data-attribute keys to
    // keys used in model.
    const modelAttributes = Object.keys(attributes).reduce(
      (result, attribute) => {
        if (dataAttributeMapping[attribute]) {
          result[dataAttributeMapping[attribute]] = attributes[attribute];
        }
        return result;
      },
      {},
    );

    this.editor.model.change((writer) => {
      this.editor.model.insertContent(
        createEmbeddedContent(writer, modelAttributes),
      );
    });
  }

  refresh() {
    const model = this.editor.model;
    const selection = model.document.selection;
    const allowedIn = model.schema.findAllowedParent(
      selection.getFirstPosition(),
      'embeddedContent',
    );
    this.isEnabled = allowedIn !== null;
  }
}

```

I would appreciate some help understanind what I'm missing or doing wrong.

Thanks in advance.

# Answer
> 1 votes
I would recommend keeping your class name and plugin name consistent. In `embeddedcontent.js` the class is `EmbeddedContent` but the plugin is `testPlugin`. It looks like you have commented-out lines in your `ckeditor5.yml`that would declare the plugin as `embeddedContent`, try committing to that and removing `testPlugin`.

---
Tags: 9, wysiwyg
---


# Question
Title: page building using a toolbar to select components (drag'n drop, IPE) on creation and edition
Of all the drupal solutions for page building, i do not see any that uses the same UI for creation and edition. Layout builder allows to place and (re)organise entities in layout sections but only once the entity has been created.

I would ideally imagine a toolbar that allows to pick from all the components available ( paragraphs , custom blocks or other type of components) and place them in sections/region while creating a new page. Editind the content would be looking just exactly the same in term of UI (in place editing and toolar available to select the components to add and configure.

Any hints on existing solutions or approaches to implement that ?

# Answer
the module geysir might do the job.

geysir
> 0 votes

---
Tags: layout-builder
---


title: Show tax from shipping?

text:
# Question
Title: Show tax from shipping?
I'm building on Commerce Kickstart 2. The problem is that for shipping it displays only flat price, there is no tax amount calculated seperately.

Is it possible to shipping like:

Express shipping subtotal 10€
Shipping tax 23% 1,23€
Total: 11,23€

Or show shipping as line item so that shipping tax is calculated to product taxes amount?

# Answer
You can do it by using Tax option under store-\> configuration.

Just go and add a tax rate.

Now you can apply tax rate using rules easily on event something like "after saving new commerce order.

And then add action you want to perform.
> 0 votes

# Answer
The way to approach this is to add your tax rate at a calculation in shipping. Set your conditional tax first and then add an additional calculation rule to your shipping. This calculates correctly, but appears as though there's a higher tax on the products.
> 0 votes

# Answer
It's pretty absurd this isn't the default methodology but the commerce price components module solves this glaring problem. https://www.drupal.org/project/commerce\_price\_components

If you install it with Drush it'll install faster and then you can clear your cache right after which you will need to do to use this module. `drush en -y commerce_price_components;drush cc all;`
> 0 votes

# Answer
Did you try configuring a Shipping tax type plugin? (Under admin/commerce/config/tax-types). Make sure to select "Shipping" as the tax type plugin.
> 0 votes

---
Tags: commerce
---


# Question
Title: Creating user programmatically fails with Postgres
Anyone know what's wrong here? After the D8-\>D9 upgrade, a stupidly simple piece of code is not working, has there been a change? It worked before.

```
$params = [
  'name' => $username,
  'pass' => $password,
  'mail' => $email,
  'init' => $email,
];

$user = $this->users->create($params);

$user->enforceIsNew();
$user->save();

```

In D8 this was fine, in D9 I'm getting:

```
Drupal\Core\Entity\EntityStorageException: SQLSTATE[23502]: Not null violation: 7 ERROR:  null value in column "uid" of relation "drupal_users" violates not-null constraint
DETAIL:  Failing row contains (null, 740f7084-de66-4572-8ec7-049376cf5a33, en).: INSERT INTO "drupal_users" ("uuid", "langcode") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1);

```

Research tells me that there was a change from D8 to D9.5 where the UID field is now a serial field instead of an integer using the sequence API.

In Postgres, you either omit the serial field, or use "DEFAULT".

The UID field is not being omitted but it's set to NULL. If I try to force it to be DEFAULT it gets type-cast to 0 (zero) and we get the UID already exists error.

How on earth can I create this user programmatically?

# Answer
> 0 votes
It turned out that there was a database update that hadn't been run on the test site, the one that switched the users.UID column to being serial, instead of int.

# Answer
> -1 votes
Instead of explicitly setting the "uid" value in your code, you can let the database handle it by omitting it from the $params array.

---
Tags: users, 9
---


# Question
Title: Are extra fields added with hook_entity_extra_field_info(). not available on product variation pages?
Is it generally impossible to render an extra field on product variation pages, because of how the variant fields are injected into product pages?

I added an extra field to the product variations with `hook_entity_extra_field_info()`. and I see it in the "Manage Display" Tab like it would appear on any other entity. But I can't output it. It is simply not available in the theme. If I do a {{ dump() }} in the product variation template it is not listed at all.

# Answer
In general, this hook only adds metadata to the entity view mode. You have to add the output in a different hook if the view mode has this field configured:

```
/**
 * Implements hook_ENTITY_TYPE_view().
 */
function mymodule_product_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($display->getComponent('my_extra_field')) {
    $build['my_extra_field'] = [
      '#markup' => 'Extra field content.',
    ];
  }
}

```

Then it will end up in the `content` variable of your theme.
> 1 votes

---
Tags: commerce
---