# Question
Title: Middle part of a page disappears and appears again after flushing all caches
Sometimes middle part of some page at our website may disappear and only header and footer are still displayed. The problem is always solved after flushing all caches.

Our `html.html.twig` loads templates a way like

```
{% include '@themename/header.html.twig' %}
{{ page }}
{% include '@themename/footer.html.twig' %}

```

And our `page.html.twig` loads an appropriate template depenging on the page path like

```
{% set path = path('<current>') %}
{% set pagePath = path|render|render %}
{% if pagePath == '/node' %} {# if homepage #}
{% include '@themename/homepage.html.twig' %}
{% else %}
{% include '@themename/innerpage.html.twig' %}
{% endif %}

```

We are not well familiar with Drupal caching so we don't know how exactly the problem is related to the caching. Maybe it's related somehow to render cache? As we use `path|render|render` in our `page.html.twig`. Or maybe it's related somehow to `index.php` which is appeared sometimes in the address bar?

# Answer
> 1 votes
The page template lists under General Utility Variables the `is_front` variable:

```
{% if is_front %}
  {% include '@themename/homepage.html.twig' %}
{% else %}
  {% include '@themename/innerpage.html.twig' %}
{% endif %}

```

This should solve the problem, even if you visit the page by different URLs. You can avoid that as well, the Redirect module redirects out-of-the-box different paths of a page to a canonical one. Then the path based condition will be predictable, so this would be a second way to solve the problem.

---
Tags: 8, theming, caching
---


title: Get the list of available services

text:
# Question
Title: Get the list of available services
Is there a way to get the list of the available services in Drupal 8?

# Answer
> 20 votes
to Enhance @4k4 answer, because it returns a lot of services names, if you looking for the specified service name, just pass a part of its name

**Drush only method**

```
drush eval "print_r(\Drupal::getContainer()->getServiceIds());"

```

for instances, if you looking for log services

```
drush eval "print_r(\Drupal::getContainer()->getServiceIds());" | grep "log"

```

and if you looking for cache services

```
drush eval "print_r(\Drupal::getContainer()->getServiceIds());" | grep "cache"

```

**Drush with devel module**

Devel module offers a nice shortcut for drush

```
drush devel:services

```

or use its aliases:

```
drush devel-container-services

```

OR

```
drush dcs

```

OR

```
drush devel-services

```

**Drupal console**

```
drupal debug:container

```

So `drush dcs | grep "PART_OF_SERVICE_NAME"` will be a good sample to find a serice

**Update**

in new version you can just do it with `drush dcs PART_OF_SERVICE_NAME`

( thanks @Cameron to mention this in comment)

# Answer
> 23 votes
The module Devel provides a searchable list (/devel/container/service).

For the command line use Drupal Console:

```
drupal debug:container

```

# Answer
> 7 votes
With plain drush, no extra modules required:

`drush eval "print_r(\Drupal::getContainer()->getServiceIds());"`

If you are searching for a something specific, pipe the output into grep to filter the results, e.g. searching for "views"

`drush eval "print_r(\Drupal::getContainer()->getServiceIds());" | grep "views"`

# Answer
> 4 votes
`\Drupal::getContainer()->getServiceIds()` is the REPL friendly way of doing this. Also you can use that on your module code etc..

The services can be also filtered:

```
preg_grep('/cache/', \Drupal::getContainer()->getServiceIds());

```

# Answer
> 2 votes
If you are interested to see the available services during development in PHPStorm you can enable the SymfonyPlugin which autocompletes for you the service names (and does much more other handy stuff)

It works both in **services.yml** and when calling **$container-\>get(...)**.

>

# Answer
> 2 votes
A list of services are available on drupal.org https://api.drupal.org/api/drupal/services/8.9.x

# Answer
> 0 votes
There is the PHPStorm Metadata module which can be used to get autocompletion for all services (core, contrib and custom) in PHPStorm. And it also can give you that list.

> This module allows to export PHPStorm Advanced Metadata in order to get autocomplete functionality and return type information for next calls:
>
> * `Drupal::service()`
> * `ContainerInterface::get()`
> * `EntityTypeManager::getStorage()`

After installing and enabling it, run `drush phpstorm-metadata:generate` and it will generate a file called .phpstorm.meta.php in your Drupal root directory. Inside there is a list of all available services (core, contrib and custom) mapped to their class.

> ```
> // ...
> 'theme_handler' =>  \Drupal\Core\Extension\ThemeHandler::class,
> 'theme_installer' =>  \Drupal\Core\Extension\ThemeInstaller::class,
> 'entity.manager' =>  \Drupal\Core\Entity\EntityManager::class,
> 'entity.memory_cache' =>  \Drupal\Core\Cache\MemoryCache\MemoryCache::class,
> 'entity_type.manager' =>  \Drupal\Core\Entity\EntityTypeManager::class,
> 'entity_type.repository' =>  \Drupal\Core\Entity\EntityTypeRepository::class,
> 'entity_type.bundle.info' =>  \Drupal\Core\Entity\EntityTypeBundleInfo::class,
> 'entity.repository' =>  \Drupal\Core\Entity\EntityRepository::class,
> // ...
>
> ```

# Answer
> -1 votes
Since Drupal 8 used Symfony so you can run command `php vendor/bin/drupal debug:container` and this is equivalent in Symfony `php bin/console debug:container`

---
Tags: 8, symfony-services
---


# Question
Title: How can I remove width and height from the <img> tag?
Does anybody know how to remove width and height from this HTML markup?

```
<img src="/sites/default/files/styles/large/public/2016-03/
dummy-640x480.jpg?itok=9_RdHYGq" alt="mein dummie" typeof="foaf:Image"
class="img-responsive" width="480" height="360">

```

# Answer
> 6 votes
In your theme open file THEMENAME.theme, example in my case THEMENAME is bartik and file is bartik.theme add code below:

```
function bartik_preprocess_image(&$variables) {
  if (isset($variables['attributes']['width']) && isset($variables['attributes']['height'])) {
    unset($variables['attributes']['width']);
    unset($variables['attributes']['height']);
  }
}

```

Clear all cache and see result.

# Answer
> 1 votes
```
/**
 * Implements template_preprocess_image().
 */
function THEMENAME_preprocess_image(&$vars) {
  if ($vars['style_name'] == 'IMAGE_STYLE_NAME') {
    // Remove explicit width & height declaration.
    unset($vars['width'], $vars['height'], $vars['attributes']['width'], $vars['attributes']['height']);
  }
}

```

# Answer
> 1 votes
If you wish to solve this inside a twig template you can use the following:

```
<img{{ attributes.addClass(classes).removeAttribute('width').removeAttribute('height') }} />

```

This should be available since Drupal 8, see following issue: https://www.drupal.org/project/drupal/issues/2325517

---
Tags: theming
---


# Question
Title: How do redirect a user after login to a route that requires the UID?
I know, this seems like a basic question:

In Drupal 9 how do I redirect a user after logging in to a path/route that requires the UID in the path?

I've researched and tried different implementations but none of them support tokens (Rules, Redirect After Login, etc.)

For example, after a user logs in they should land on "/homebox-page/dashboard/UID" \<- numerical value from current user ID.

I was hoping for a simple module to handler this but it looks like I may need to do it through custom code?

# Answer
This should be possible with a few lines of custom code. The user login form redirects already to `entity.user.canonical`, which requires the UID:

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

    if (empty($uid = $form_state->get('uid'))) {
      return;
    }
    $account = $this->userStorage->load($uid);

    // A destination was set, probably on an exception controller.
    if (!$this->getRequest()->request->has('destination')) {
      $form_state->setRedirect(
        'entity.user.canonical',
        ['user' => $account->id()]
      );
    }
    else {
      $this->getRequest()->query->set('destination', $this->getRequest()->request->get('destination'));
    }

    user_login_finalize($account);
  }

```

You could add your own submit handler doing the same, overwriting the redirect. There you can use \Drupal::currentUser() because user\_login\_finalize() in the core submit handler sets this service with the user just logged in.
> 1 votes

---
Tags: redirection
---


title: How can I print a single field?

text:
# Question
Title: How can I print a single field?
I've got a taxonomy page (https://www.dovericaricare.it/becharge) that I'm trying to customize using a twig template.

I don't understand what syntax I should use to print fields like the logo (`{{ fields.field_logo }}` doesn't work and there is nowhere in the dump a field with a full path url for the image) or the value of `field_fornitore`

Here's the dump of the content of the page (you can see it on the page itself too). Can you please suggest how to print values in twig template?

(I already did the same on a node page, but the taxonomy term seems a lot harder)

# Answer
this is the code I used at the end (don't remember how I get it, but I remember that KINT debugger helped me a lot):

```
{# start to cycle #}
{% for immagine in content.field_immagine_colonnine %}
    {% if immagine['#item'].target_id > 0 %}
        <div class="imagetext">
            <img alt="{{ immagine['#item'].alt }}"
                title="{{ immagine['#item'].title }}"
                src="{{ file_url(immagine['#item'].entity.uri.value | image_style('large') ) }}"
                id="{{ immagine['#item'].target_id }}"
            />
            <p class="sottotitoloimmagine">{{ immagine['#item'].title }}</p>
        </div>
    {% endif %}
{% endfor %}
{# end cycle #}

```
> 0 votes

# Answer
Your field\_logo has got a list (array), where is your logo. I would try

`{{ content.field_logo[0] }}`

If you want some helpful forum with more info about references (and entities for nodes as well) look there: https://www.drupal.org/forum/support/theme-development/2015-12-16/entity-reference-values-in-twig-template
> 1 votes

---
Tags: theming, taxonomy-terms, 9
---


# Question
Title: Page Manager fails when accessing structure pages
When I go to Admin/Structure/Pages, the following error occurs:

> InvalidArgumentException: The internal path component 'https://dssm.vegas/civicrm/contribute/transact' is external. You are not allowed to specify an external URL together with internal:/. in Drupal\Core\Url::fromInternalUri() (line 420 of core/lib/Drupal/Core/Url.php).

I either need assistance in removing the error or instruction as to where I can delete the latest page I tried to add to the site without this interface.

# Answer
> 0 votes
After a backup of the database...

First, I searched the MySQL database for records that had both "contribute" & "transact".

Next: Suspecting the **drpl\_router** table, I found one of the two entries, one with "page\_manager" in it and the name of the form created before the crash. Deleted that record. Found similar in the **drpl\_config** table and deleted that.

Reloaded the page, went back to Admin/Structure/Pages and was able to load the page manager.

Hope this helps someone.

---
Tags: nodes, 9
---


# Question
Title: How to migrate files from outside Drupal, with files already where they need to be, creating file entities
I'm doing a migration from a non-Drupal site--so far, for test purposes. I have all the data in CSV files.

Since I'm brand new to migrating into Drupal 9 from outside Drupal, I'm learning this in small, somewhat simple phases.

The source data includes a bunch of records, many of which have attached files. Some files are attached to more than one record. Some records have multiple files attached. "Attached" here means a URL is stored, along with a bit of metadata, like a short description, and a type. In the database, this in a join table to relate files to records.

**What I want to achieve eventually in Drupal:**

All these records migrated in as nodes, the files joined to media and those joined to the correct nodes by entity reference. The creted media entities should have the old meta stuff (description, type) in custom fields.

I gather that the way this should be done is:

1. Migrate the files into file entities
2. Using a migration group (migration\_plus, migrate\_tools, and migrate\_source\_csv modules) use the *same data source* and migration\_lookup to migrate the media entities
3. Migrate the nodes in and use the process plugin entity\_generate and a value\_key of target ID or something to relate the nodes to the right media entities.

The files are already where they need to be on the server, and the paths/URIs are stored in a csv file along with the description and type, a unique ID field and the ID of each related record.

As a starting point, I attempted to import 30 files as a standalone import. The migrate\_files module didn't seem like a good fit, mostly because I can't figure out how to adapt it to a situation where the media entities are going to pull field data from a csv... and the file uri's are stored in a csv also.

So I thought I'd try it with mostly standard.

This was my yaml:

```
uuid: 1bcec3e7-0a49-4473-87a2-6dca09b91abjan-test1
id: fileimptest
label: Test file import
migration_group: default
source:
  plugin: 'csv'
  path: '/srv/imports/filetest1.tab'
  delimiter: "\t"
  enclosure: '"'
  header_offset: null
  ids: [aid]
# not using most of these fields in the file import
# but including because maybe needed for grouping
# and migrate_lookup in the media import?
  fields:
    0:
      name: aid
      label: 'Unique Id'
    1:
      name: title
      label: 'description'
    2:
      name: formflag
      label: 'FormYN'
    3:
      name: newpath
      label: 'path'
    4:
      name: docnum
      label: 'doc number'
    5:
      name: doctype
      label: 'document type'

process:
  uid:
    plugin: default_value
    default_value: 179
  uri: path
destination:
  plugin: entity:file

```

The result was that my 30 test files appeared in the file list under admin/conent with a status of temporary. The links look correct, but clicking them results in 403 access denied (folder permissions are 777 and owned by the webserver). (I am using private file system and have several files uploaded through normal field widgets: this list with status 'permanent.' The links look the same other than subdirectories but open normally when clicked.)

So questions are:

* What am I doing wrong so far?
* Is there a better way? (I'm pretty sure there is, but what?)

(Detail: uid 179 is just a user I created named "importer") I should note that I've read this and this, and lots of examples in the related modules. They have, together, informed what I've come up with so far, to the degree I understand them.)

Edit: "temporary status" just means there are no uses yet, so not important at this point. The only thing that seems wrong with this test import is the access denied issue. The migrate process is missing something necessary to full function of the private file system? **Maybe when using private files, they can only be viewed if 'used' on another entity?** I haven't found info on this or come up with a way to test it yet.

Edit2: per comments and answer below, **the 'temporary' status can be set programmatically during the import, and the access denied is normal under these conditions**: when the imported file is both a) not used anywhere and b) clicked by a user other than the uid on the file.

# Answer
The temporary status is a field on the file entity (`status`), you can set that to `1` during import to make it permanent.

```
process:
  uid:
    plugin: default_value
    default_value: 179
  uri: path
  status:
    plugin: default_value
    default_value: 1

```

File usage is a separate (related) thing and shouldn't come into play here. Those references will be added when you associate the files with content etc.
> 1 votes

---
Tags: files, migrations
---


# Question
Title: Disable theme debugging html comments in particular view?
we are running commerce site, still tweaking some bits, so we have still twig debug set to true, but site is already online.. we have XML feed for exporting commerce products to couple of price comparison sites.. and XML feed is of course marked as invalid, because even in XML views feed are html theme suggestion comments, any chance to turn off those for particular view?

Thank you.

```
<SHOP xmlns="http://www.zbozi.cz/ns/offer/1.0">

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'xmlfeedviews_row' -->
<!-- BEGIN OUTPUT from 'modules/contrib/xmlfeedviews/templates/xmlfeedviews-row.html.twig' -->
<SHOPITEM>
    <PRODUCTNAME>

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'views_view_field' -->
<!-- BEGIN OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->
Náhradní filtry k ionizátorům H2
<!-- END OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->

</PRODUCTNAME>
<DESCRIPTION>

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'views_view_field' -->
<!-- BEGIN OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->
Životnost filtrů je 1000 galonů (3800 litrů). Vyměnit filtry k ionizátoru není složité a zvládnete to sami.

<!-- END OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->

</DESCRIPTION>
<URL>

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'views_view_field' -->
<!-- BEGIN OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->
https://www.fitvoda.cz/nahradni-filtry-k-ionizatorum-h2
<!-- END OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->

</URL>
<PRICE_VAT>

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'views_view_field' -->
<!-- BEGIN OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->
4990.00
<!-- END OUTPUT from 'core/modules/views/templates/views-view-field.html.twig' -->

</PRICE_VAT>
... etc

```

# Answer
No, I don't think you can turn off twig debugging for only some parts of the site. It's either on or it's off.

Anyway, you are risking a lot of trouble making changes to a live site. It's much better to set up a local development environment and make your code changes locally. One cross-platform tool for this is Lando but there are many others as well. Drupal.org has a full guide on local server setups.

Also, the documentation specifically states that Twig debugging can break parts of the site, including views. See this issue.
> 1 votes

---
Tags: views, debugging
---


# Question
Title: Loading a field value within a twig template
I'm building a multi-country website using Drupal 8. The company would like to have each region manage their website independently but still have a "global" site. I'm building a theme which has some hardcoded areas (telephone numbers, copyright notice etc) which I want each region to be able to modify themselves. My thinking is to create a content area for say "copyright".

How do I render a field value for a content entity within a twig theme? Is there a better way to handle this kind of process?

# Answer
> 1 votes
Drupal has some great native concepts for doing just what you're trying to accomplish.

The main one you're looking for is built right in. It's called Blocks. Blocks can arbitrary entities that can be placed in theme regions you define on your site. Most of how Drupal handles rendering content is in some way tied to blocks be it system managed blocks like the "Main Content" block, Menu blocks, and so on.

You can define basic blocks which are just WYSIWYG content and place them in a theme region, but then also restrict them by content type, language, path, etc.

You can also define Custom Block Types which are fieldable like any other entity. You can control their appearance with twig, and set up any simple or complex field design you wish.

Depending on how you are choosing to group content and define what a "Country" is in Drupal, you can add contributed modules like Context to have extremely granular control over what gets rendered where.

Rendering a field in twig templates can be extremely easy, or extremely hard depending on where you are trying to render it. I highly suggest reading through The Drupal theming guide for a general understanding on how it all works.

Drupal templates are broken down into layers.

* **html.html.twig** \- which is the very basic scaffold of a web page
* **page.html.twig** \- which is the base semantic structure of your page(s) and where your regions are placed.
* **region.html.twig** \- which is the wrapper code for your regions where blocks live
* **block.html.twig** \- where blocks get themed - can render fields in here that are created on block entities
* **node.html.twig** \- Nodes are your "pages" of content you create like blog posts, about us content and so on. These can also have fields and are rendered at this level.
* **field.html.twig** \- Individual fields also provide their own templates and can be altered as you wish.
* **And so on**. (there are many other template types, too many to mention here, but you get the idea) See more reading: https://www.drupal.org/docs/theming-drupal/twig-in-drupal/twig-template-naming-conventions

I hope this helps!

PS: As a last note, I would not be building new sites using Drupal 8. Drupal version 8 is end of life. You should be building on Drupal 9. The good news is Drupal 9 functionally is nearly identical to 8 and you should be able to upgrade your existing work to it with little issue.

---
Tags: 8
---


# Question
Title: Changing a node alias to reuse his old url programmatically without be still redirected to the node page
I'm on a old site on drupal 7. I have a node with alias `/url`. Now I need to manage that page url programmatically, so I create an item in a custom module using `hook_menu()` in this way:

```
/**
 * Implements hook_menu().
 */
function MYMODULE_menu() {
  $items = [];

  $items['url'] = [
    'title' => 'New Title',
    'page callback' => 'MYMODULE_url_callback',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  ];

  return $items;
}

```

In the previous node I've changed the alias to `/url-old` but when I go to the page `/url` I've been redirected to `/url-old` and can't reach the new page.

Where is still referenced the relation between `node/<nid>` and his old alias `/url`?

I've the module Pathauto installed. In the aliases list the `/url` link is no more present.

Thanks in advance.

# Answer
> 0 votes
I've found where are defined all node's redirects:

> Configuration \> Search and metadata \> URL aliases.

Needs to remove all occurrence for the new url before to reach the page programmatically.

---
Tags: 7, path-aliases, redirection
---


title: Where are path aliases stored?

text:
# Question
Title: Where are path aliases stored?
I know that, in Drupal 7, path aliases are stored in the *url\_alias* table. Which database table does Drupal 8 use to store path aliases?

# Answer
Prior to Drupal 8.8.0, they were stored in the same table as Drupal 7. From Drupal 8.8.0, path aliases are revisionable entities, whose primary database table is *{path\_alias}* and the revision table is *{path\_alias\_revision}*.
> 2 votes

---
Tags: 8, database, path-aliases
---


# Question
Title: Can I translate a variable using Drupal.t()?
I am using the REST API in Drupal 9 and am using JavaScript template literals to generate some of the data.

For example, to generate a list of products that are pulled from the API, I am using this code.

```
<span class="products">
  ${Drupal.t(object.field_supplier_products)}
</span>

```

This returns what I have under field\_supplier\_products, so for example "Product 1, Product 1, Product 3", but I cannot find the string translations.

This is a multilingual site and these product names need to be translated.

With the following code, I can see the translations.

```
<span class="products">${Drupal.t('Product One')}</span>
<span class="products">${Drupal.t('Product Two')}</span>
<span class="products">${Drupal.t('Product Three')}</span>

```

Is there any possible way or workaround to use `Drupal.t()` with variables?

I am using the Drupal RESTful Web Services Module to have a REST API for a view. I created a view that has all my products.

I have a JavaScript file product.js that is used to generate markup on my products.html.twig file.

```
(function ($, Drupal) {
  if ( document.querySelector('#products-page') ) {
    $.ajax({
      method: 'GET',
      url: '/api/products/'
    }).done(function (data, status, xhr) {
      $.each(data, function (index, object) {
        $('#products .wrapper').append(`
          <div class="col-12 product">
            <span class="products">${Drupal.t(object.field_supplier_products)}</span>
          </div>
        `)
      });
    });
  }
})

```

With the following data, `object.field_supplier_products` returns `"product1"`.

```
{
    "title": "Supplier 1",
    "nid": "1",
    "market_id": "2",
    "product_id": "15",
    "field_supplier_products": product1,
}

```

# Answer
> 1 votes
Th problem is due to the fact that you are attempting to translate a variable, rather than a literal string:

```
Drupal.t(object.field_supplier_products)

```

In Drupal, variables should not be translated, for both security reasons, and to keep the translations table clean. Now, on the server side in PHP if you were to use the `t()` function around a variable, for example `t($color)` it would throw a warning, but the value should still be translatable (I haven't tried/checked in a few years). But if I recall correctly, with JS and the `Drupal.t()` function, it is not possible to translate variables at all. This is because the script Drupal actually parsed for the values by Drupal and re-generated with the translated values, cached with the translated values and this new file is sent to the browser. So no translation actually happens on the browser, the translation is actually enacted by PHP on the server, and a new file is generated before ever sending the file to the browser.

The solution is to ensure that your values are translated in the REST API so that they are already translated when your JS receives them, and will not require use of the `Drupal.t()` function. From your post it appears that the REST endpoint is also a Drupal instance, so to do this on the REST server you would:

1. Set up the REST API server to be a multilingual site, with language detection by URL.
2. Make your request to the API using the multilingual URL for the language to be retrieved.

For example, if your multilingual site differs by path prefix, you will have:

* `http://www.example.com/path/to/restserver` \[primary langauge\]
* `http://www.example.com/[LANGUAGE_PREFIX]/path/to/restserver` (LANGUAGE\_PREFIX language)

Then, your JS would request the REST API from the relevant language path.

I often find it's beneficial to generate the URL on the server side, and pass this PHP generated URL, which will contain the language prefix for the current language, to the JS which then calls URL dynamically.

This is first done by creating a library that adds your JS file, and has a dependency on Drupal settings:

```
example_library:
  js:
    path/to/file.js: {}
  dependencies:
    - core/drupalSettings

```

Then, your render element would attach the library, and pass the URL to the JS file in the library:

```
use Drupal\Core\Url;
$page[
  'some_element' => [
    '#prefix' => '<div id="example_placeholder">',
    '#suffix' => '</div>',
    '#markup' => $this->t('Placeholder'),
    '#attached' => [
      'library' => ['[MODULE]/example_library'],
      'drupalSettings' => [
        'exampleModule' => [
          'ajaxCallbackUrl' => Url::fromRoute('[RESTAPI ROUTE]', [], ['absolute' => TRUE])->toString(),
        ],
      ],
    ],
  ],
];

```

Now, the script `file.js` will have access to the REST API URL with the language prefix, in the `drupalSettings.exampleModule.ajaxCallbackUrl` variable.

file.js:

```
function(drupalSettings) {

  function doSomething() {
    console.log(drupalSettings.exampleModule.ajaxCallbackUrl);
  }
}(drupalSettings));

```

---
Tags: javascript, 9
---


# Question
Title: Programmatically get a full page html rendering of a route/page
We provide our content via APIs. At times we use the Views Restful approach, and at times the JSONAPI.

We need to add an API field on nodes that is a full HTML rendering of that node's page according to the theme (technically I just need ... but I'll take the whole doc if I can get it).

I have tried a number of approaches:

I tried using the renderer service. It renders full html from the html.html.twig template but items such as blocks on the page are missing. I guess it doesn't have all the context it needs.

```
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$content = $view_builder->view($node);
$build = [
  '#type' => 'html',
  'page' => [
    '#type' => 'page',
    '#theme' => 'page',
    '#title' => $node->get("title")->value,
    'content' => $content,
  ],
];
$page = \Drupal::service('renderer')->renderPlain($build);

```

Very similarly I tried using twig\_render\_template. It similarly renders full html but items such as blocks on the page are missing.

```
$markup = twig_render_template(drupal_get_path('theme', 'neato') . '/templates/base/html.html.twig', array(
  'page' => [
    '#type' => 'page',
    '#theme' => 'page',
    '#title' => $node->get("title")->value,
    'content' => $content,
  ],
  // Needed to prevent notices when Twig debugging is enabled.
  'theme_hook_original' => 'not-applicable',
));
$body = (string) $markup;

```

As a separate approach, I tried to make a 'subrequest'. With this approach, I get the rendered HTML but it causes fatal early rendering errors such as "A stray renderRoot() invocation is causing bubbling of attached assets to break."

```
$kernel = \Drupal::service('http_kernel.basic');
$sub_request = \Symfony\Component\HttpFoundation\Request::create("/node/".$value->_entity->id(), 'GET');
$subResponse = $kernel->handle($sub_request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
$html = $subResponse->getContent();

```

I even tried to mimic the full drupal 'bootstrap'

```
$autoloader = require '/app/web/autoload.php';
$sub_request = Request::create("/node/".$node->id(), 'GET');
$site_path = DrupalKernel::findSitePath($sub_request);
$kernel = DrupalKernel::createFromRequest($sub_request, $autoloader, 'prod');
$sub_response = $kernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST);
$html = $sub_response->getContent();

```

I am open to any and all pointers and suggestions. I really appreciate it.

# Answer
We went a similar path to @johnSmith's rec of using file\_get\_contents(). Thanks!

**TL;DR;** When nodes are saved, we use httpClient to make a 2nd request to the site. That response is saved in a field and included in the API. Thx!!

**Details**

* A new field was added to the associated content types. This field will be used to store the rendered page HTML.
* A custom module was written. When nodes of the associated content types are created or updated, a subsequent request is made using httpClient. This request is made to the node page. That HTML response is saved in the new field.

//We have saved the configured domain name in which to make this render request to in Drupal's config.

$config = \Drupal::service('config.factory')-\>getEditable('myApi.static\_server\_settings');

$domain = $config-\>get('myApi.theme\_domain');

//Request this node's rendered page

$nid = $node-\>id();

$client = \Drupal::httpClient();

$request = $client-\>get($domain.'/node/'.$nid);

$render = (string) $request-\>getBody();
* Our API was extended to include this field. As a fallback, when the API runs, if the new field is empty that same subsequent httpClient request is made on the fly.
* We built a batch process that updates the 'rendered page' field for all the content. This can be run if the theme is updated. We may eventually trigger it from our theme-building scripts/gulp/CI stuff.
> 2 votes

---
Tags: 9
---


title: #limit_validation_errors submit problem

text:
# Question
Title: #limit_validation_errors submit problem
I have a problem using #limit\_validation\_errors for a submit button on which I dont want all the validations to run. Here's my custom submit button :

```
$form['actions']['draft'] = array(
     '#type' => 'submit',
     '#value' => 'Save as draft',
     '#submit' => array(''),
     '#limit_validation_errors' => array(
       array('title'), // Validate $form_state['values']['title'].
     ),
);

```

It works perfectly in the sense that it checks the validation on the title field only, but the weird thing is, it does not submit any other field's values when submitted. I wrote a custom submit handler to check that. However, the values are present in `$form_state['input']` but not in `$form_state['values']`.

What I want simply is, this form will submit with just the values given and overlook the validations when this custom submit button is clicked.

FYI : I can get `$form_state['values']` perfectly in my custom validate function.

Any ideas? What am I doing wrong here?

# Answer
> 1 votes
It works as expected - in `$form_state['values']` you have **validated** values, and in `$form_state['input']` you have **raw** values. If you will limit validation to title field only - only this field will be transferred into "values" array.

# Answer
> 0 votes
I had to switch from a `type="submit"` to `type="button"` in order to disable errors + use ajax.

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

    // ...

    // Create Draft Button
    $form['#prefix'] = '<div id="send-emails-manual-send-by-role-wrapper">';
    $form['#suffix'] = '</div>';
    $form['actions']['save_draft'] = [
      '#type' => 'button',
      '#value' => $this->t('Save Draft'),
      '#name' => 'submit__save_draft', // TODO: Make constant
      '#limit_validation_errors' => [],
      '#ajax' => [
        'callback' => [$this, 'ajaxSubmitForm'],
        'wrapper' => 'send-emails-manual-send-by-role-wrapper',
        'method' => 'replace',
        'effect' => 'fade',
      ],
    ];

    return $form;
  }

  /**
   * Submit the form using ajax
   */
  public function ajaxSubmitForm(array &$form, FormStateInterface $form_state) {
    $this->submitForm($form, $form_state);
    return $form;
  }

```

---
Tags: forms
---


title: Why aren't my local tasks shown?

text:
# Question
Title: Why aren't my local tasks shown?
I have the module.routing.yml as

```
entity.node.ssl_check:
  path: '/node/{node}/check-ssl'
  defaults:
  _form: '\Drupal\ssl_check\Form\SslCheck'
  _title: 'Check SSL Cert'
  requirements:
  _permission: 'access check ssl tab'

```

and module.links.task.yml as

```
 entity.node.ssl_check:
  route_name: entity.node.ssl_check
  title: 'Ssl check'
  base_route: entity.node.canonical
  weight: 15

```

Here when I access node/1104/check-ssl/ the form defined in the form controller is loading. But my other need that is to show a 'Ssl check' tab when I visit path /node/1104/ is not there. I have done the tab thing while dealing with Controller but not working with form controller. Please help. I have checked 'Add tab / local task to a node' this but there was nothing dealing with form controller.

# Answer
> 2 votes
Since everything looked just fine in your code, I tried the following in a custom module:

```
#test.links.task.yml
test.node_test:
   title: 'Wooorking'
   route_name: entity.node.canonical
   base_route: entity.node.canonical

```

And this is working like a charm. Also when I added a custom routing, which was pointing to a form controller, it showed up! (although not worked, because I didn't handled the node parameter in the routing configuration)

So the problem lies another where.

So I suggest you to do it step by step way (building your routing and task yml) to understand your problem. Clearing the cache each time when you change something in your YML files. If you found the problem, please post the solution, so also we can learn from this.

# Answer
> 1 votes
Apparently, if there's only one task, it won't appear. You'll watch the links appear if you add 2 or more links.

In other words, this wont appear alone :

```
entity.node.ssl_check:
  route_name: entity.node.ssl_check
  title: 'Ssl check'
  base_route: entity.node.canonical

```

This will show two tabs

```
entity.node.ssl_check:
  route_name: entity.node.ssl_check
  title: 'Ssl check'
  base_route: entity.node.canonical

entity.node.ssl_check2:
  route_name: entity.node.ssl_check
  title: 'Ssl check again'
  base_route: entity.node.canonical

```

# Answer
> 0 votes
Modified the code as

```
 entity.node.ssl_check:
      title: Ssl check
      route_name: entity.node.ssl_check
      base_route: entity.node.canonical
      weight: 15

```

# Answer
> 0 votes
I had copied and pasted my code wrong. Things to check:

* The file name is YOUR\_MODULE.links.task.yml
* The task name is YOUR\_MODULE.some\_task
* The route name is YOUR\_MODULE.some\_route

The last one got me. It appears that if the route does not exist, the local task will silently not show.

---

**File:** *YOUR\_MODULE.links.task.yml*

```
YOUR_MODULE.some_task
  title: 'Example Title'
  route_name: YOUR_MODULE.manual_email
  base_route: YOUR_MODULE.manual_email

```

---
Tags: 8, routes
---


# Question
Title: Node reference field autocomplete and allow multiple selections in views
I recently pdated my Drupal core to 8.9 and suddenly a functionality stops working.

I have a "Recipe" content type, it has a field of "Category" (field\_category) which is Entity Reference: Node.

I tried to create a View and created a filter criteria field\_category, and I want it to be Auto complete and Allow multiple selections.

I know its possible on Entity Reference Taxonomy, but currently its not possible on Entity Reference Node.

I found Views Autocomplete Filters (https://www.drupal.org/project/views\_autocomplete\_filters), but I want it to Allow multiple selections.

# Answer
> 0 votes
I managed to solve my problem using this module:

https://gist.github.com/StryKaizer/ae1cb9abc4844a9e7ac12317a9d84a78

---
Tags: 8, views
---


# Question
Title: How do get a value from field in if/else statement
In a custom **views-view-fields.html.twig** I do print a list field (field\_status) without issues. The values are:

new|New

old|Old

But if i want to do an if/else statement for printing different div containers i do get always printed the div container from else. Does anybody have an idea what i am doing wrong? I tried it too with module Twig Field Value, but i do have the same issues.

```
<div class="card h-100">
    <div class="card-body">
        {% if fields.field_status.content == 'new' %} // |striptags , |raw or a capital value e.g. New do not work , Twig Field Value also do not work: content.field_status|field_value
            <div class="icon medium">
                NEW
            </div>
        {% else %}
            <div class="icon medium">
                OLD
            </div>
        {% endif %}
        <h5 class="card-title">{{ fields.title.content }}</h5>
    </div>
</div>

```

Thanks for helping!

# Answer
> 3 votes
If you want to compare the left part of the field list you need the raw database value from the entity.

You find the entity in the `row` variable of **views-view-fields.html.twig** :

```
{% if row._entity.field_status.value == 'new' %}

```

See Access row value in template\_preprocess\_views\_view\_fields(&$variables)

---
Tags: views, entities
---


# Question
Title: Passing parameters to view blocks in Twig
Running Drupal 8.9.18

I have a string that I want to pass to a Drupal block for use in a contextual filter. In a twig template I have a view that creates a simple list of the terms to use. I extract the string from the result array, map the required string to a variable that I pass as a parameter to another view block:

```
{% set view-output = drupal_block('views_block:view1-block_1') %}

{% for item in view-output.content['#view'].result %}

  {% set qParam = item.taxonomy_term_field_data_name | render | striptags %}
  {% if drupal_block('views_block:view2-block_1', qParam )is not empty %}
    {{ drupal_block('views_block:view-name-block_1', qParam) }}
  {% endif %}

{% endfor %}

```

The expression `item.taxonomy_term_field_data_name | render | striptags` gives me the values I expect from the view output.

I get the following error:

> The website encountered an unexpected error. Please try again later. TypeError: Argument 2 passed to Drupal\twig\_tweak\TwigExtension::drupalBlock() must be of the type array, string given,

Question: how can I pass `qParam` as an array (it's a single value). I've tried using `{% set qParam = qParam|merge(..) %}` inside the for loop but the (..) bit is a mystery to me.

Or is there a better way of nesting queries that I don't know?

Note that I am not conversant with coding in PHP and want to stick with using Twig alone.

Thanks in anticipation for any help

# Answer
following the error-message you probably just use an array with a single value as second argument, e.g

```
{{ drupal_block('xx', {qParam: qParam} ) }}

```
> 2 votes

# Answer
thanks for your help. I'll try that. I've actually found a workaround using a contextual filter to identify a specific path component rather than using a query parameter. This does what I want but I'd be interested to solve the original problem
> 0 votes

---
Tags: views
---


# Question
Title: Using TB Megamenu, how to close one submenu when I open another submenu?
I'm building a couple of (Drupal 8.9.13 and Drupal 9 based) sites where I use TB Megamenu megamenu module (https://www.drupal.org/project/tb\_megamenu) to create the menu. All is working fine on desktop/laptop etc, when I hover over the top menu items the related submenu slides open, when the cursor moves away it folds away again.

On narrow screen/mobile, the menu collapses to a hamburger in header. When I click the hamburger, the menu appears as intended, with the top level (no-clickable) items appearing. When I click each of the top items the related submenu items appear, again as intended.

However, when I then click another submenu trigger, the other submenu opens, but the previously opened submenu stays open as well. Taking up lots of vertical space and pushing parts of the menu off the screen.

What do I need to change to have only ever one submenu open at any one time (i.e. triggering a new submenu closes the one that was opened before)? There is no setting for this in the TB megamenu configuration (drupal module), and no instructions on this in the documentation. I assume I have to add some (java)script either in my theme .js file, or change add something in the TB Megamenu tb-megamenu-frontend.js, most likely an onClick event that runs through all top items with submenus and closes all others but the clicked one?

I had the same issue a long time ago with the Mobile Sliding Menu (see that question and answer. I have tried the javascript that was suggested there (adapting the class names to match my TB menu etc), but it doesn't work here.

I have exactly the same behaviour (of submenus staying open) on all versions of TB megamenu, (from D7 to D8 to D9, various older as well as latest development releases), and would love to find out how to address this..

Many thanks for any help on this!

# Answer
You have to customise how TB Mega Menu works.

In `your_theme.theme` you must add:

```
function yourtheme_js_alter(&$javascript) {
    $javascript['modules/tb_megamenu/dist/js/frontend.js']['data'] = drupal_get_path('theme', 'your theme') . '/js/frontendcustom.js';
}

```

In your js folder of your theme you must add a custom file `frontendcustom.js`. The file is copied from the TB Mega Menu module
> 0 votes

---
Tags: theming, javascript, navigation
---


title: "OR" condition in db_select()

text:
# Question
Title: "OR" condition in db_select()
I am studying the new database layer, and I am glad it is changed to an OOP layer. I need to implement a query with `db_select()`. I found I can add a `WHERE` statement with `$query->condition()`, but by default the conditions are AND'ed together.

How can I OR the conditions together?

```
$query=db_select('users','u')->fields('u',array('uid','title','created','uid'));
$query->join('flag_content','fc' , 'u.uid = fc.content_id');
$query->condition('fc.fid', '5' , '=');
$query->condition('fc.uid', $uid , '=');
//…

```

# Answer
> 23 votes
According to drupal 7 Database documentation the default is ***AND*** condition, but if you want to use ***OR*** condition then use this;

```
$db_or = db_or();
$db_or->condition('n.type', 'event', '=');
$db_or->condition('n.type', 'article', '=');
$query->condition($db_or);

```

# Answer
> 86 votes
That's not correct, the default is AND. To use or, you need to use:

```
$or = db_or();
$or->condition();
$or->condition();
$query->condition($or);

```

But the main conditions on the query are definitely joined with AND.

# Answer
> 31 votes
You can use this For making OR between 2 conditions ByDefault it is AND

```
$query=db_select('users','u')->fields('u',array('uid','title','created','uid'));
$query->join('flag_content','fc' , 'u.uid = fc.content_id');

$db_or = db_or();
$db_or->condition('fc.fid', '5' , '=');
$db_or->condition('fc.uid', $uid , '=');
$query->condition($db_or);

$result = $query->execute()->fetchAll();

```

It is possible to have AND condition within OR suppose you have 3 conditions and if you want it to be like con1 AND con2 OR con3 and even many other cases in this case you can use db\_and like db\_or because when you are trying to use db\_or all the conditions within db\_or takes now in case you want and between those you can use db\_and that is little tedious but its possible to implement it. Here is the example below

```
 $query = db_select('work_details_table','wd');
$query->join('work_table','w','wd.request_id = w.request_id');
$query->fields('w',array('client_id'));
$query->fields('wd');
$query->condition('wd.request_id',$request_id);
if($status == 5 || $status == 6 || $status == 7){
  $query->condition('wd.status',$status);
}elseif($user_type == 'writer'){
  $query->condition('wd.writer_id',$user_id);
  $db_or = db_or();
  $db_and = db_and();
    $db_and->condition('wd.status',2);
    $db_and->isNull('wd.editor_id');
  $db_or->condition('wd.status',4);
  $db_or->condition('wd.status',1);
  $db_or->condition($db_and);
  $query->condition($db_or);
}else if($user_type == 'editor'){
  $query->condition('wd.editor_id',$user_id);
  $db_or = db_or();
  $db_and = db_and();
    $db_and->condition('wd.status',2);
    $db_and->isNotNull('wd.editor_id');
  $db_or->condition('wd.status',3);
  $db_or->condition($db_and);
  $query->condition($db_or);
}
//-----------------------------------------------------------------------------------------
$completed_sku = $query->execute()->fetchAll();

```

This will give you an idea how the complex and or condition can be handled in Drupal PDO queries .

# Answer
> 11 votes
Simple example:

```
$nodes = db_select('node', 'n')
->fields('n')
->condition(
 db_or()
   ->condition('uid', 1)
   ->condition('status', 0)
 )
->execute()
->fetchAll();

```

# Answer
> 1 votes
By default there is AND condition, for OR condition need to add db\_or() inside the condition.

```
$query = db_select('soccer_team"', 'n');
$query->fields('n',array('stid','title'))//SELECT the fields from node
        ->fields('n',array('title'))//SELECT the fields from user
            ->condition(
             db_or()
            ->condition('title','%ace%','LIKE')
            ->condition('title','%alb%','LIKE')
            )
        ->orderBy('title', 'ASC');

```

# Answer
> 0 votes
The db\_or() solution won't work when you are building a complex query where you want most of the conditions to be conjoined with AND's and just one or some OR condition(s).

I ran into a case like this where I had conditions already, and I didn't want them to be OR conditions. I was able to use the **where() method** instead of condition to add another clause that included an OR. Here's an example similar to the query I used with the where method there near the end:

```
$query = db_select('users');
$query->join('user_join', NULL, 'users.uid = userid');
$query->join('field_data_account', NULL, 'appid = entity_id');
$query->leftJoin('users_roles', 'roles', 'users.uid = roles.uid');
$query->condition('account_target_id', $form['#account_id']);
$query->condition('userid', $lab_user->uid);
$query->where('appid <> :app_id OR rid = :rid', array(
    ':app_id' => $form['#app_id'],
    ':rid' => $role->rid,
))->fields('users')->countQuery();
$result = $query->execute()->fetchField();

```

# Answer
> 0 votes
For Drupal 8 you can use e.g.:

```
// Use only records with ACCEPTED or REJECTED action.
$orCondition = $query->orConditionGroup();
$orCondition->condition('action', 'ACCEPTED');
$orCondition->condition('action', 'REJECTED');
$query->condition($orCondition);

```

# Answer
> 0 votes
db\_or() is deprecated for Drupal 9: https://api.drupal.org/api/drupal/core%21includes%21database.inc/function/db\_or/8.8.x

Following the deprecation notice, this code should be used:

```
use Drupal\Core\Database\Query\Condition;

$or = new Condition('OR');
$or->condition();
$or->condition();
$query->condition($or);

```

---
Tags: 7, database
---


title: How can I run a SQL query from a file?

text:
# Question
Title: How can I run a SQL query from a file?
I have a module that will be used as a location finder, and it needs to create a table on install that will hold zip codes and their location. That's easy to do. However, I also need to populate that table. Seeing as it's quite a large dataset, and I already have it in a `.sql` file, I would like to be able to run that file instead of embed the query into the module\_install function.

I looked over the documentation for `db_query()`, but I don't see a way to run a file.

Is this doable, or do I need to pull the database username and password out and run it manually?

# Answer
You can use `drush sql-connect` for this, so you don't need to enter any credentials and/or use mysql's command line:

```
`drush sql-connect` < my-sql-file.sql

```

The tildes tell your shell to replace the command `drush sql-connect` with the command's output. Therefore, when you run this line in your terminal, bash will actually see something like:

```
mysql --database=dbname --host=localhost --user=username --password=password < my-sql-file.sql

```

Check out Drush's documentation for much, much more.
> 6 votes

# Answer
I'm not aware of any way to "run a file", but you could edit your `.sql` file to only contain INSERT statements, then add functionality in your module\_install() function to execute your statements, rather than embedding all of the statements in the module.install file.

Maybe something like this would work (having not seen how your SQL file is formatted:

```
function my_module_install() {
  // Get the contents of the .sql file.
  $sql = file_get_contents(drupal_get_path('module', 'my_module') . '/module.sql');
  // Split into individual statements based on new lines.
  $statements = preg_split('/[\n\r]+/', $sql);

  foreach ($statements as $query) {
    db_query($query);
  }
}

```

You will of course still have to define the schema (which you should do anyway) in the .install file, but this would at least allow you to keep the data out of your code.
> 2 votes

# Answer
I think a better long term solution would be to divorce the act of schema creation with populating the data. For one thing, zip codes do change, and you may want to eventually update the module to support other postal code systems.

I would create your schema in the install file, and then implement a `hook_requirements()` that checks whether the table has any data in it, and outputs a warning if there are no rows.

Then, make a settings form for your module. Add a `$form['zipcodes']['#type']['file']` to it. In the submit handler, you can process the file to populate the zipcode table. This will likely need to use batch processing, though. Inserting nearly 100,000 records will take a while.

You could also make a custom drush command to do the same thing, perhaps even downloading it from a remote location automagically.
> 0 votes

# Answer
The Drupal Database class extends PHP PDO class, so you can use `Database::getConnection()->exec(file_get_contents('/path/to/my/file.sql));` to execute arbitrary SQL file, despite the exec method not being in the corresponding Drupal documentation.
> 0 votes

# Answer
Here is what worked for me in Drupal 9:

```

function MY_MODULE_install() {
  \Drupal::messenger()->addStatus(__FUNCTION__);
  $container = \Drupal::getContainer();
  /** @var \Drupal\Core\Database\Connection $database */
  $database = $container->get('database');
  $database = \Drupal::database();
  // Get and insert the contents of the CSV file.
  $modulePath = \Drupal::service('module_handler')->getModule('MY_MODULE')->getPath();
  $csv = file_get_contents($modulePath . '/data/my.csv');
  $statements = preg_split('/[\n\r]+/', $csv);
  array_pop($statements); // remove that last pesky EOL
  foreach ($statements as $query) {
    list($field1, $field2, $field3) = explode(',', $query);
    $anItem = [
      'field1' => trim($field1,"'"),
      'field2' => trim($field2, "'"),
      'field3' => trim($field3, "'"),
    ];
    $database->insert('MY_TABLE')->fields($anItem)->execute();
  }
}
```
> 0 votes

---
Tags: database
---


# Question
Title: Existing pages not editable for admin with all permissions
You know the drill. User of various CMSs but new to Drupal and inherited a site running version 8.6.10. New pages (nodes?) can be created but once something is created, nothing on/under the Edit tab is editable. In watching various Drupal tutorials, it appears most users with the correct permissions can simply click on a page from Content, click the Edit tab and edit the content boxes on the page. This site does not behave that way and I'm not sure if it is by design (permissions and/or review/publishing processes) or if there is an issue elsewhere within the site/admin.

Where can I start to learn more or troubleshoot this? I want to edit page body copy and publish to the live site. Hoping there is something very easy missing from this equation. I have watched a handful of editing pages in Drupal videos and no one has this mystery block preventing all text and sidebar options like redirects, menu settings non-toggable. It's like the entire page is simply a screenshot.

FYI - there was a "Content permissions need to be rebuilt. Rebuild Permissions" message across the entire web admin. The Rebuild Permissions link was eventually clicked and ran complete in about 90 seconds. Was hoping that was the issue but nothing miraculously became editable.

Any leads on related issues? Where to begin for basic site edits/publishing?

Thank you.

# Answer
It's possible we may need more details here. The site may have some sort of altered edit workflow in place that differs from Drupal's native behaviour which is similar to what you are used to.

Normally you can visit {website url}/admin/content in the backend, or visit a published page on the front end and click the "edit" link to edit content.

Cases where this isn't the case are pages on the site which are not "entity" in nature. (eg dynamically generated or code-generated pages/routes)

Unfortunately without knowing more about the site's setup it will be difficult to speculate. I would check for any modules that alter the edit workflow, or permissions structure. If a site uses something like Groups you may need to be a member of the group to alter that content.

It may also be possible that your user's role does not have sufficient permissions to edit content of that content type. In this case try editing the same content with the user/1 (First user on the site which has unalterable super administrative rights on the site, if you have access to it, or reach out to whomever has user modification abilities to alter your user role)

If your user has permission to edit permissions for users under { website url}/admin/people/permissions scroll down to (or ctrl+f) and find the permission that states

```
<your content type>: Edit any content
(and)
<your content type>: Edit own content

```

And make sure your user role has those options checked. Failing that ensure that your user role has the more permissive "Administer content" permission enabled. (this will override all other content edit permissions unless altered by another module)

You can try a couple of basic tests as well. If you know the node ID (numerical ID assigned to all nodes created) and manually construct the edit url to see if it's just something on the theme (admin/front end) that is hiding the edit buttons. The URL pattern used here is

```
website.tld/node/{THE NODE ID}/edit

```

Example:

```
website.tld/node/123/edit

```

You can check to see if the "Tabs" Block under {website url}/admin/structure/block is placed in a useable theme region and visible. This would allow you to edit the content from the front end if logged in as an appropriately privileged user.

On the back end admin area you can check the data view (under {website url}/admin/structure/views) the drives the {website url}/admin/content page to ensure that the "Content: Operations links (Operations)" field is placed in the view. Without that the edit/operations buttons will not appear in that view if you have permissions to view them.

This is just pure speculation, of course, not knowing how your website was constructed, or what custom code/contributed modules are being used.

Hope this helps.
> 1 votes

---
Tags: nodes, wysiwyg
---


# Question
Title: In Drupal 7 With Latest CKEditor, Media upload button not working
If i do install Wysiwyg \+ CKEditor 3.6.6.1 ( 2013.02.20) \+ Media module in Drupal 7 then the upload functionality works on ckeditor. Here is my screenshot: But, if i install CKEditor Drupal 7 Module \+ Media Module then the upload functionality do not working on ckeditor. Here is my screenshot: So, how i can enable the Upload section in Media Module? Thanks

# Answer
I found the solution:
in order to use the upload plugin, the user has to either have the **Edit media** or the Administer media permission.
> 5 votes

# Answer
There is a settings page for controlling media in wysiwyg that allows you to configure this.

It is at admin/config/media/browser

The setting in question is "Enabled browser plugins". Check the "Upload" box.
> 0 votes

# Answer
There's also a permission called 'Add and upload new files' under 'File Entity' which might help people. This added the missing Upload tab to the generic (non-CKEditor) media browser for me…

(Note you don't need the plupload module just for this - that's a fancy widget, whereas changing the permission just adds a standard Drupal file upload field.)
> 0 votes

---
Tags: 7, wysiwyg, media
---


# Question
Title: for D8, How to skip (don't update) some fields from existing entity during import if this field already has a value
How to skip (don't update) some fields from existing entity during import if this field already has a value? That for Drupal 8 with modules (migrate, migrate\_plus and migrate\_tools)

example of an yml I would like:

```
process:
  uid:
    -
      plugin: migration_lookup
      migration: users
      no_stub: true
      source: uid
  field_telephone: phone
  field_user_country: pays
  field_adresse/given_name: prenom
  field_adresse/family_name:
    -
      plugin: skip_on_notempty  \--> do not exist
      method: process
      source: \--> actuel value of 'field_adresse/family_name', How to get that ?
    -
      plugin: get
      source: nom

```

# Answer
To import only a single field, or possibly multiple, use "overwrite\_properties".

> overwrite\_properties: If the migration has specified a list of properties to be overwritten, clone the row with an empty set of destination values, and re-add only the specified properties.

```
destination:
  plugin: 'entity:node'
  overwrite_properties:
    - field_name

```

Source: Drupal\migrate\Plugin\migrate\destination
> 22 votes

# Answer
I'm a bit late to the party, but want to leave a comment for future readers of this question:

Obviously, there's no plugin in core or migrate\_plus that allows skipping a migration, if the destination of an update is not empty. So we created a process plugin, that does exactly that:

```
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipProcessException;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Skips migration updates, if the destination field is not empty.
 *
 * This process plugin is intended for content entity migrations. It prevents
 * field values from being overwritten, if the migration performs an update
 * (the destination entity exists) and the target field is NOT empty.
 *
 * Available configuration keys:
 * - method: (optional) What to do, if the destination field is not empty.
 *   Possible values:
 *   - row: Skips the entire row. (Default behavior.)
 *   - process: Prevents further processing of the input property.
 *
 * Example usage:
 *
 * Skip updating the entire destination entity, if its
 * 'field_ignore_if_not_empty' field is not empty; otherwise use the source
 * value from 'field_in_source'.
 *
 * @code
 * process:
 *   field_ignore_if_not_empty:
 *     plugin: skip_on_destination_not_empty
 *     source: field_in_source
 *     method: row
 * @endcode
 *
 * @MigrateProcessPlugin(
 *   id = "skip_on_destination_not_empty"
 * )
 */
class SkipOnDestinationNotEmpty extends ProcessPluginBase implements ContainerFactoryPluginInterface {

  /**
   * The destination entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $entityStorage;

  /**
   * The migration.
   *
   * @var \Drupal\migrate\Plugin\MigrationInterface
   */
  protected $migration;

  /**
   * {@inheritdoc}
   *
   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
   *   The migration.
   * @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage
   *   The destination entity storage.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $entity_storage) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityStorage = $entity_storage;
    $this->migration = $migration;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
    // Check, whether the migration is empty.
    if (empty($migration)) {
      throw new MigrateException('SkipOnDestinationNotEmpty plugin can only be used with a migration context.');
    }

    // We need to know the destination entity type, which we can get from the
    // migration's destination plugin ID, if it's a content entity
    // destination plugin ('entity:[entity_type_id]').
    $destination_plugin = $migration->getDestinationPlugin();
    $destination_plugin_id = $destination_plugin->getPluginId();
    $entity_type_id = NULL;
    if (strpos($destination_plugin_id, static::DERIVATIVE_SEPARATOR)) {
      [, $entity_type_id] = explode(static::DERIVATIVE_SEPARATOR, $destination_plugin_id, 2);
    }

    // If we didn't find an entity type, we should stop here.
    if (empty($entity_type_id)) {
      throw new MigrateException('SkipOnDestinationNotEmpty plugin can only be used with content entity migrations.');
    }

    // If the entity storage doesn't exist, we stop here as well.
    $storage = $container->get('entity_type.manager')->getStorage($entity_type_id);
    if (empty($storage)) {
      throw new MigrateException("SkipOnDestinationNotEmpty plugin can't initialize the entity storage for {$entity_type_id}.");
    }

    // Inject the entity storage into the constructor.
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $migration,
      $storage
    );
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    // Determine the destination entity ID. We use the migration's ID map for
    // update migrations, or an entity ID value provided in the migration
    // process instructions.
    $id_map = $this->migration->getIdMap();
    $destination_ids = $id_map->lookupDestinationIds($row->getSourceIdValues());
    $destination_id_values = $destination_ids ? reset($destination_ids) : [];
    $entity_id = reset($destination_id_values) ?: $row->getDestinationProperty($this->entityStorage->getEntityType()->getKey('id'));

    // Whether a target entity ID exists and the entity can be loaded.
    if (!empty($entity_id) && ($entity = $this->entityStorage->load($entity_id))) {
      // Whether the entity has the destination field and it's not empty.
      if ($entity->hasField($destination_property) && !$entity->get($destination_property)->isEmpty()) {
        // Whether process skipping has been configured.
        if (!empty($this->configuration['mode']) && $this->configuration['mode'] == 'process') {
          throw new MigrateSkipProcessException("Skipped processing $destination_property on {$this->entityStorage->getEntityType()->id()} {$entity->id()} due to destination field is not empty.");
        }
        // Skip the row.
        else {
          throw new MigrateSkipRowException("Skipped updating {$this->entityStorage->getEntityType()->id()} {$entity->id()} due to $destination_property field is not empty.");
        }
      }
    }

    // Return the not altered value.
    return $value;
  }

}

```

Now, this plugin skips, if the entire destination field is not empty, and it can be used on the first level of the field process only.

It would yield strange results, if used on a field property, as it uses the `transform` process plugin method to determine the field name via the `$destination_property` parameter, which reflects the field property name on the second level (e.g. `target_id`, `value`, `summary`, ...).

BUT you can easily adapt it to do some different checks on the destination field. E.g., checking certain field properties. All you have to do is altering the line

```
if ($entity->hasField($destination_property) && !$entity->get($destination_property)->isEmpty()) {

```

to your needs.

Please also note, that this plugin does NOT support multilanguage entities and destination languages. That wasn't required for our task at hand, but you should be aware of it.
> 0 votes

---
Tags: migrations
---


# Question
Title: Retrieving nodes tagged by multiple terms
Let's say I have an articles content type, and a field\_tags reference field (with multiple values referencing a "tag" vocabulary)

To retrieve articles referencing, say, "tag1" or "tag2", I do this:

```
jsonapi/node/article?
&filter[tags][condition][path]=field_tags.id
&filter[tags][condition][operator]=IN
&filter[tags][condition][value][]=id-of-tag1
&filter[tags][condition][value][]=id-of-tag2

```

That gives me all articles that have either tag1 or tag2.

However, How can I get all articles that have both tag1 **and** tag2?

# Answer
I have tried as follow

/jsonapi/node/article?filter\[field\_tags.meta.drupal\_internal\__target\_id\]=5&filter\[field\_tags.meta.drupal\_internal\__target\_id\]=6

you can see in the screen shot only 1 node filtered which has both 5 & 6 term id.
> 0 votes

# Answer
You can use condition grouping and have like below :

```
?filter[tag-group][group][conjunction]=AND

&filter[tagA-filter][condition][path]=field.tags.id
&filter[tagA-filter][condition][value]=id-of-tag1
&filter[tagA-filter][condition][memberOf]=tag-group

&filter[tagB-filter][condition][path]=field.tags.id
&filter[tagB-filter][condition][value]=id-of-tag2
&filter[tagB-filter][condition][memberOf]=tag-group

```

I have not tried that but I think you can even use a code like this:

```
?filter[tagA-filter][condition][path]=field.tags.id
&filter[tagA-filter][condition][value]=id-of-tag1
&filter[tagB-filter][condition][path]=field.tags.id
&filter[tagB-filter][condition][value]=id-of-tag2

```

just notice that in this case two different key is used for conditions
> 0 votes

---
Tags: taxonomy-terms, services
---


title: Load node entities by owner

text:
# Question
Title: Load node entities by owner
I want to load entities by their owner. This is what I have so far:

```
\Drupal::logger('migrate_users')->notice("Hello start");
$userStorage = \Drupal::entityTypeManager()->getStorage('user');

$query = $userStorage->getQuery();
$uids = $query
  ->condition('status', '1')
  ->condition('type', 'student')
  ->execute();

$users = $userStorage->loadMultiple($uids);

// help regarding this line
$entities = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadByProperties([
      'type' => 'article',
      'user' => SOME_USER,
    ]);

\Drupal::logger('dssi_migrate_users')->notice("done");

```

What do I need to pass in for `SOME_USER`?

# Answer
You are only using the wrong property name for passing the user ID.

The following would work:

```
$entities = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadByProperties([
      'type' => 'article',
      'uid' => SOME_USER_ID,
    ]);

```

If you wish to fetch entities from several users, just use an array:

```
$entities = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadByProperties([
      'type' => 'article',
      'uid' => [uid1, uid2, uid3],
    ]);

```

`loadByProperties()` method use buildPropertyQuery() to pass the values to the query, which use a "IN" condition.
> 2 votes

# Answer
What you are looking for is `IN` operation and I think `loadByProperties` method only acts on `Equals` operation so, use `getQuery` method instead and you can attach as many conditions as you want, like below:

```
$nodeQuery = \Drupal::entityTypeManager()->getStorage('node')->getQuery();
$entities = $nodeQuery->condition('bundle', 'article')->condition('uid', $uids, 'IN')->execute();

```
> 0 votes

---
Tags: users, database, 9
---


# Question
Title: Why is the Aggregator module not creating a block
I am using the Aggregator module that is part of Drupal 9 core. I am following the docs on drupal.org: https://www.drupal.org/docs/8/core/modules/aggregator/overview

After I create a feed and update it, I understand that a custom block should automagically be created. But I cannot find any new blocks under /admin/structure/block. Am I missing something?

# Answer
> 1 votes
Once added a feed to the Aggregator module, and once the feed is updated, visiting /admin/structure/block shows *Aggregator feed* as one of the possible blocks.

>

Click on the *Place block* button for the region where you want the block to appear. The dialog box that appears will show a list of blocks implemented by modules; one of them is the *Aggregator feed* block. Click on the *Place block* button shown for that block; a new dialog will appear to config the block.

>

The *Select the feed that should be displayed* field allows you to select the feed to show in the block, while the *Number of news items in block* field allows to select how many articles will appear in that block.

Once I clicked on the *Save block*, I saw the block in the region I selected.

>

---
Tags: blocks, feeds
---


# Question
Title: What is the difference/purpose of 'content' and 'elements' keys, in preprocess?
I'm using `hook_preprocess_node` and looking at `$variables`. I can see there's two similar keys: `content` and `elements`. I see that there's a comment in the core code:

```
  // Helpful $content variable for templates.

```

next to code that copies all `elements` keys into `content`... I'm unsure *why* it's helpful, *how* it's different, and *when* one would use `elements` or `content` to achieve a particular goal.

This is a general question, but my task at hand is that I have two separate taxonomy term reference fields and I wish to combine them, alphabetically by term name, into one list for presentation.

# Answer
> 2 votes
`elements` is the variable name defined in theme\_hook() to hold the renderable elements (for the node this is the entity build array). Preprocess is then responsible to prepare variables for rendering, like `content`.

If your goal is to modify the template output then check first which variables are actually printed. In a node template it doesn't make sense to change `elements` in preprocess, any changes you make will be discarded. You can however do this in the build process, for example in hook\_entity\_view\_alter().

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


# Question
Title: Render two taxonomy fields in one alphabetical list
I have two term reference fields: colours and tags.

I have a poppy, it has tags: *pretty* and colours: *red*, *green*.

I want html like:

> This flower is: green, pretty, red

i.e.

* I want to take the terms from two fields and merge them into one collection.

## I tried in Twig:

I started in twig. I could combine the terms but I couldn't sort them.

```
{% set alltags = content.field_tags['items']|merge(content.field_colours['items']|keys|map(i => content.field_colours[i])) %}
{{ alltags }}

```

## I tried in pre process

I then moved to PHP in a `mytheme_preprocess_node()` function. I thought I could sneak a few of the *colours* terms in under the *tags* field... It seemed to add them to the object OK, but none of the colour ones were output.

```
/** @var Drupal\Core\Field\EntityReferenceFieldItemList */
$coloursTags = $variables['content']['field_colours']['#items'] ?? NULL;
if ($coloursTags && $coloursTags->count()) {
  $tags = $variables['content']['field_tags']['#items'];
  foreach ($coloursTags as $item) {
    /** @var Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item */
    $tags->appendItem($item->getValue());
  }
}

```

I have since found a couple of ways that work, which I'll post in an answer so as to attract better answers than mine!

# Answer
> 0 votes
I found a couple of ways to achieve it, posting here, but I'm open to better/cleaner ways. I'm especially unhappy in my answers with the way to access the tag name - seems so overly complicated trying to get the raw name?!

Both code blocks live in a `mytheme_preprocess_node()`:

## Answer 1: create a new variable with all the tags in it:

```
<?php

  $allTags = [];
  $addTags = function($fieldName) use (&$allTags, $variables) {
    if (isset($variables['content'][$fieldName])) {
      foreach (\Drupal\Core\Render\Element::children($variables['content'][$fieldName]) as $i) {
        $allTags[]= $variables['content'][$fieldName][$i];
      }
    }
  };
  $addTags('field_colours');
  $addTags('field_tags');
  usort($allTags, function ($a, $b) {
    $tagA = $a['#taxonomy_term']->name->getValue()[0]['value'];
    $tagB = $b['#taxonomy_term']->name->getValue()[0]['value'];
    return strcasecmp($tagA, $tagB);
  });
  $variables['content']['allTags'] = $allTags;

```

Then in Twig for the node template: `{{ allTags }}`.

## Answer 2: mix the tags from the colour field into the tags field in the render array

```
<?php

  $allTagsTemp = [];
  foreach (\Drupal\Core\Render\Element::children($variables['content']['field_tags']) as $i) {
    $tag = $variables['content']['field_tags'][$i];
    unset($tag['#weight']);
    unset($variables['content']['field_tags'][$i]);
    $allTagsTemp[] = $tag;
  }
  foreach (\Drupal\Core\Render\Element::children($variables['content']['field_colours']) as $i) {
    $tag = $variables['content']['field_colours'][$i];
    unset($tag['#weight']);
    unset($variables['content']['field_colours'][$i]);
    $allTagsTemp[] = $tag;
  }
  usort($allTagsTemp, function ($a, $b) {
    $tagA = $a['#taxonomy_term']->name->getValue()[0]['value'];
    $tagB = $b['#taxonomy_term']->name->getValue()[0]['value'];
    return strcasecmp($tagA, $tagB);
  });
  $variables['content']['field_tags'] += $allTagsTemp;

```

Then in Twig `{{ field_tags }}`.

---
Tags: theming, 9
---


# Question
Title: Add only one input filter to a textarea using form api
I have created a custom form, in which I have one textarea field with a wysiwyg. Here is the code

```
$form['text'] = array(
    '#type' => 'text_format',
    '#default_value' => variable_get('text'),
    '#title' => t('text'),
    '#format' => NULL,
  );
  return system_settings_form($form);

```

So it returns me a textarea field with a format dropdown. Which I don't required. I need only to use the `filtered_html` and the format dropdown should not appear.

# Answer
> 1 votes
There are several way to achieve this, you can use the Hide Formats module:

> Hide Formats allows you to collapse the "text format" or "input format" dropdowns to clean up the UI.

or Better Formats module:

> Better formats is a module to add more flexibility to Drupal's core input format system. Features 8.x & 7.x (needs more testing for a stable release)
>
> * Set allowed text formats per field.
> * Set default order of text formats per field.
> * Hide format tips per role. Hide more format tips link per role.
> * Hide format selection per role per entity.
> * **Currently only works on Field API fields on fieldable entities implementing core style text processing.** The good thing is that is most things in core and contrib.

Or, use the FormAPI to disable it with something like:

```
// hook_form_alter function
function CUSTOM_MODULE_form_alter(&$form, &$form_state, $form_id) {
    // We want this on a specific node type
    if ($form_id == 'NODE_TYPE_node_form') {
        $form['#after_build'][] = 'CUSTOM_MODULE_NODE_TYPE_node_form_after_build';
    }
}

// afterbuild function
function CUSTOM_MODULE_NODE_TYPE_node_form_after_build($form) {
    // We want this on a specific field
    $form['YOUR_FIELD']['und']['0']['format']['#access'] = FALSE;
    return $form;
}

```

**Also** you can try this (I didn't test it but it may work):

```
$form['text'] = array(
    '#type' => 'text_format',
    '#default_value' => variable_get('text'),
    '#title' => t('text'),
    '#format' => "full_html",
    'format'=>array('#access'=> false),
  );

```

# Answer
> 0 votes
This is the correct way:

```
$form['somename']['somesuffix'] = array(
  '#type' => 'textarea',
  '#title' => t('somename'),
  '#description' => '',
  '#default_value' => '',
  '#rows' => 6,
);
$form['somename']['format'] = filter_form(FILTER_FORMAT_DEFAULT, NULL, array('somename', 'format'));

```

---
Tags: 7, forms, input-formats
---


# Question
Title: How to get Commerce price without any adjustments
I'm trying to show "Buy for XX USD more and get free shipping", I know how to get `$cart->get('total_price')->getValue()[0]['number']` but it is including any adjustments including shipment, I need just price of all items in a cart without any adjustments.

Using devel I found out that shipment value is stored in `$cart->get('adjustments')->getValue()[0]['value']`, but I don't know how to get to protected `amount->number` (see picture), any help? ) MY variable `$PriceWithoutAdjustments = $cart->get('adjustments')->getValue()[0]['value'];`)

Or even better, how to get price without adjustments?

Many thanks

# Answer
You cannot work with those classes like with drupal´s fieldable entities

There is this nice little hint in your debug output that shows which class is used e.g

Drupal\commerce\_order\Adjustment

So i dont know commerce plugin but i can look into the source, i just searched for the classes in the online available source-code

and see that Adjustment has the method `getAmount`

```
$priceWithoutAdjustments->getAmount();

```

which will return of type Drupal\commerce\_price\Price

which has a method `->getNumber()`

which seems to be what you are looking for :)
> 0 votes

---
Tags: commerce
---


# Question
Title: Entity reference link: add reference from Entity B to Entity A
I have created 2 Content entities. Entity A has an "Entity Reference Field" with multiple values to Entity B. This all work as expected.

What I want to achieve is, to create a link from Entity B page, that when the user clicks on it, it will be added (appended) to Entity A "Entity Reference Field".

What's the best way to get this done?

* *(I know I can use the Flag and Flag lists module, but there are limitations to it like it will be impossible/difficult to make these lists public/anonymous. After trying Flag lists out, it also didn't feel like a very Drupal native approach.)*
* *(Getting a list of referenced items etc. is an other challenge, but my biggest problem is to get the linking approach working first.)*

# Answer
The direction I'm trying to take is, to add the reference with:

```
$node->{$target_field}[] = $id;

```

But I'm struggling to figure out how to create this custom form that will be displayed on the node view.
> 0 votes

---
Tags: entities, 9
---


# Question
Title: How do I translate view's page path alias that has a dynamic path?
I have a view that has a dynamic path and I want to create a path alias for each language installed on my site. Following the answer on How do I translate view's page path alias? I'm able to create a path alias when no dynamic path is involved in the view, but when a contextual filter with dynamic path is in the view I can't find how to create the path alias.

The view is a simple view like this:

So, how do I translate view's page path alias that has a dynamic path like `/jobs/%` ?

# Answer
> 3 votes
Views pages generate routes including route parameters for contextual filters. So you could add for each language a duplicate page, set a language specific path and inherit all other properties from the master display.

But as the routing system is not language specific this has some shortcomings. You get multiple language prefix/route path combination, which is not good for SEO and makes it difficult to build outgoing links.

Language specific path handling is outside of the routing system. The standard tool for this is path aliasing, so you would need to set for each dynamic value and language combination an alias in the lookup table. Don't know if you can generate them with Pathauto, but I wouldn't recommend it anyway in this case, because the path has a clear pattern you can easily transform in a custom path processor to match the internal view's page display route.

# Answer
> 2 votes
For the moment the only solution that is working for our team is implementing the Inbound and Outbound Processor plugins to allow you to interfere with the process of processing incoming and outgoing URLs.

You can check an example in the PathProcessorAlias page and there is a good article in Russian named Drupal 8: Inbound and Outbound Processor (The automatic translation of Google Chrome is working fine for this article)

Another good article talking about how this works is How to hide Order ID from commerce checkout process in Drupal 8

# Answer
> 1 votes
Even this is an old post, I'm still struggling with this use case in many projects. As depicted in previous answers and comments the solution is both, a combination of path alias (core) and a path processor plugin. The Translate Views Path module provides the proper path processor plugin, so you can go and add the path alias for your language using *%* wildcard as usual.

The only caveat is, for example, if you are using term's name (and probably any other entity) as your argument. If so, you must also include the **Taxonomy term: Translation language** condition to properly match the translated term name and remove the criteria validation from the context filter in order to work, since the validation criteria and the context filter use the entity original language instead the one selected by the user.

---
Tags: views, 8
---


# Question
Title: Order of drush commands for automated deployment?
What order should the following drush commands be ran?

* config-import
* updatedb
* entity-updates

Also, I see entity-updates fail a lot due to field\_delete\_data\* tables existing. How can I delete them as part of my automated deployment?

# Answer
Drush 10.3.0 now provides a `deploy` command to standardize how Drupal deployment works. This command performs the following:

> ```
> drush updatedb --no-cache-clear
> drush cache:rebuild
> drush config:import
> drush cache:rebuild
> drush deploy:hook
>
> ```

Database updates always come before configuration import! Support for automatic entity updates has been removed from Drupal core (change record) and `entup` has been removed from Drush core. Whenever an entity type or field storage definition needs to be created, changed or deleted, it has to be done via `hook_update_N()`.

---

Here is the updated deployment routine I'm happiest with.

```
drush state:set system.maintenance_mode 1
drush cache:rebuild
git pull
composer install --no-dev
drush deploy
drush state:set system.maintenance_mode 0
drush cache:rebuild

```

---

This also means you have to run two releases if you want to uninstall and remove a contrib module. First release to deploy the updated config that disables the module. Second release to deploy the updated composer.json and lock file after you removed it with Composer.

To make real consecutive releases possible you might want to pass the current release's commit SHA1 to the deployment script and then replace `git pull` with a more exact routine (where `$1` is the SHA1):

```
# If not empty 1st argument passed to the script, do:
if [ -n "$1" ]; then
  git reset --hard "$1"
else
  git pull
fi

```

Otherwise the consecutiveness can not be guaranteed when you push two new releases at once or within a short period. As then the first release's triggered `git pull` will simply pull the latest changes (from the second release), where instead it should pull only the changes included in the first release. See the full sample repo `leymannx/drupal-circleci-behat`.

Credit for this `git` snippet goes to CircleCI. This is how they are doing it in their containers.
> 38 votes

# Answer
The sequence of commands should be:

```
updatedb (which runs update hooks)
config-import

```

You do not want to run entity-updates because it is deprecated, see https://www.drupal.org/node/3034742. Instead, rely on update hooks (hook\_update\_N) to properly modify any database schema or necessary configurations.

It is imperative that updatedb is the first command run that boots Drupal after code has been changed. You can see https://www.drupal.org/project/commerce/issues/3100553 for some commentary on what issues might arise when that is not done.

# Example Deployment Script

Here is an example deployment script that has had a lot of review and discussion behind it, but consider it a starting point. It's likely there will be adjustments you would want to make. It does assume you're deploying an artifact (notice that composer install is not run on deployment).

```
drush sset system.maintenance_mode TRUE
# Create a restore point by taking backups of anything that is not in the code repository: database, media, cache
# Checkout the code you are deploying
drush updb
drush cim sync -y || drush cim sync -y
drush cim sync -y
drush sset system.maintenance_mode FALSE
drush cr

```

You can see https://www.bounteous.com/insights/2020/03/11/automate-drupal-deployments/ for a deeper explanation behind this. See also https://github.com/drush-ops/drush/pull/4359/ which is a PR to include a deploy command in Drush.

I mentioned the script above is a starting point, I've documented some variations that you might want to apply to that script (or any deploy script you use) that might be helpful: https://www.bounteous.com/insights/2020/03/12/automated-drupal-deployment-and-rollback-recipes/
> 4 votes

# Answer
Here is our CI script, quite the same :)

```
drush cr
git pull
composer install
# drupal console enforce modules are enabled before any config is installed
drupal config:import:single --directory="config/sync" --file="core.extension.yml"
drush cr
drush -y updb
drush cr
drush -y cim
drush cr

```

the config:import:single was helpfull when diffrent developers where creating modules without requiring the correct dependencies in their .info.yml
> 3 votes

# Answer
If you need to import custom translations too make sure to run a drush cim afterwards importing as some of the lables are translated in config and some in the po files.

At moment our update job looks like this after a git pull. And make sure if you are on dev to export your changes before pulling with drush cex ;-) :

```
composer install --no-interaction -d /var/www/html/
drush updatedb -y
drush cr -y
drush cim -y

drush locale:check -y #make sure to switch this to local only in settings.php in production
drush locale:update -y
drush locale:import de ../translations/custom-translations.de.po --type=customized --override=all -y
drush locale:import de ../translations/custom_other_translations.de.po --type=customized --override=all -y
drush cr -y

drush cim -y
drush cr -y

```
> 2 votes

# Answer
Use `drush deploy`, it calls eveything in needed order + as bonus you can use https://www.drush.org/latest/commands/deploy\_hook/ which will allow you to manage content changes with new updated/imported structure.
> 1 votes

---
Tags: 8, drush, deployment
---


# Question
Title: Display metatag description of nodes in taxonomy term views
In Taxonomy term views, where are displayed shorten nodes I want to display node's metatag description instead body summary, but it doesn't work. I'm using Metatag module with it's submodule Metatag: Views. Views looks like this:  Please help

# Answer
THANK YOU Clive. I implement patch from this two files, this MetatagViewsFormatter.php and this MetatagFormatter.php from here Provide field formatter to output meta tags on-page, e.g. for use with Views (D9) and it works! Now I have in views metatag field this options:
> 0 votes

---
Tags: views, 9, meta-tags
---


title: Managed file in theme config not saving

text:
# Question
Title: Managed file in theme config not saving
In my theme settings under 'admin/appearance/settings/mytheme' I am trying to add an image field.

I have added the following to mytheme.theme

```
function mytheme_form_system_theme_settings_alter(&$form, Drupal\Core\Form\FormStateInterface $form_state) {
  $form['mytheme_settings']['footer_info']['footer_image'] = array(
    '#type' => 'managed_file',
    '#title' => 'footer image',
    '#name' => 'footer_file',
    '#default_value' => theme_get_setting('footer_image', 'mytheme'),
    '#upload_location' => 'public://'
  );
}

```

This creates a file field in the theme settings page. When I upload the field is saved in my public files

I am now trying to render that file in to a twig template.

I add the following to mytheme.theme to delacre the variable

```
function mytheme_preprocess_page(&$variables) {
  $variables['footer_image'] = theme_get_setting('footer_image','mytheme');
}

```

Then add `{{ footer_image }}` to a template, however the file does not get rendered.

How do I call the file I have uploaded in to my custom theme template. Thanks

Edit.

After searching more, I have discovered the file gets uploaded but the file is getting deleted.

After finding this link it is suggested I sent the file location which I already have done.

# Answer
`hook_form_system_theme_settings_alter()` needs to also add a submission handler, to handle the managed file. In Drupal core, the only hook doing that is implemented by a test module, but the code is the same that a normal module should use. (I didn't show all the form elements added from the hook; the code comes from `test_theme_settings_form_system_theme_settings_submit()`.)

```
function test_theme_settings_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) {
  $form['custom_logo'] = [
    '#type' => 'managed_file',
    '#title' => t('Secondary logo.'),
    '#default_value' => theme_get_setting('custom_logo'),
    '#progress_indicator' => 'bar',
    '#progress_message' => t('Please wait...'),
    '#upload_location' => 'public://test',
    '#upload_validators' => [
      'file_validate_extensions' => [
        'gif png jpg jpeg',
      ],
    ],
  ];

  $form['#submit'][] = 'test_theme_settings_form_system_theme_settings_submit';
}

function test_theme_settings_form_system_theme_settings_submit(&$form, FormStateInterface $form_state) {
  if ($file_id = $form_state->getValue(['custom_logo', '0'])) {
    $file = File::load($file_id);
    $file->setPermanent();
    $file->save();
  }
}

```

Without setting the managed file as permanent, it would be soon deleted.
> 1 votes

---
Tags: 8
---


# Question
Title: Display custom module block in page content
I have created a custom module providing a block.

The block is available in the block library under "Block Layout" (`/admin/structure/block`).

On the other hand, I have a custom content type with an "Entity reference revisions" field that allows me to add any kind of content to a page. I can select "Add Drupal Block" in this field but my custom block either:

1. Shows up in the list if it's placed in the block layout (but then it appears twice on the page)
2. Doesn't show at all in the list if it's not placed in the block layout

Am I misunderstanding something or doing something wrong ? Thanks!

# Answer
You've created a custom block plugin in a custom module and now you need to configure it? Then the question is where to store the configuration when you don't want to use the block layout.

This could be the Layout Builder as commented or a smaller, more targeted module like https://www.drupal.org/project/block\_field.

The "Entity reference revisions" field is usually used together with Paragraphs. Then "Add Drupal Block" adds a paragraph type, in which you could use the mentioned field module. This module can be used as a stand-alone node field as well if the only purpose of this field is to place the block.
> 2 votes

---
Tags: blocks
---


# Question
Title: How to provide an array of values from a context provider
I'm looking into building a custom Context Provider, specifically to provide "groups of the current user". I'm building this for another plugin, a Condition plugin, whose purpose is to filter things (e.g. Blocks) based on the current user's group roles.

I'm aware that the following issues and patches exist, which does get me somewhere:

However, both patches only ever deal with *a single group*, i.e. the context provider only picks out essentially the first group a user belongs to, and the condition plugin is provided one group for evaluation. What I'd like to do is have the the context provider provide multiple groups (all the groups the user belongs to) and have the condition plugin accept multiple groups.

But how do I provide and consume an array of values as context value?

Most examples for context provider and plugins consuming context values only operate on single values. I've not seen examples on how to provide an array (of groups in this case).

# Answer
Let's start with this:

> Most examples for context provider and plugins consuming context values only operate on single values.

While that's true, recognize that the "single value" being provided is an object, not a primitive type. In the case of the Group context provider, that "single value" is an Entity object of type 'group'. The entity itself contains all the usual data - id, label, description, created date, author, base fields, etc. So it's wrong to think of it as one number only.

To provide an array of values, you need to return an object that represents a data structure instead of an Entity. The core Typed Data API defines a variety of datatypes, of which the Map type is probably the best for your purpose. Map holds a collection of values, similar to a familiar associative array in PHP.

So the outline of the solution is to create your own context provider by copying the existing Group context provider, modify your copy so that instead of creating an Entity context definition you create a Map context definition, then add the values you want to provide to your Map.

If you need more functionality, you can create your own datatype (I recommend subclassing Map for this) and provide an object of that datatype instead of an Entity or a Map.

You can find a short example of how to write your own Context Provider here: https://www.drupal.org/docs/contributed-modules/rules-essentials/for-developers/providing-global-context-variables
> 3 votes

---
Tags: 9, plugins
---