# Question
Title: Template preprocess to generate Font Awesome markup for menu links
In Drupal 9, I need the ability to prepend Font Awesome icons to menu links.

I have attached Font Awesome 5 JS and CSS assets to my theme via `*.libraries.yml`.

If I open a menu link in the DOM inspector and edit the markup of a link from this:

```
<ul class="clearfix nav">
  <li class="nav-item">
    <a href="#comments" class="nav-link nav-link-comments">Comments</a>
  </li>
</ul>

```

to this:

```
<ul class="clearfix nav">
  <li class="nav-item">
    <i class="fas fa-comment"></i><a href="#comments" class="nav-link nav-link-comments">Comments</a>
  </li>
</ul>

```

The Font Awesome JavaScript detects the empty `<i class="fas fa-comment"></i>` element, and the result looks exactly like what I want it to look like.

However, it's been very tricky to add that markup to the link element programmatically.

I can do it with JavaScript DOM manipulation in a Drupal behavior, but I'd prefer to prepare the markup in Twig and preprocess.

After trying and rejecting a couple of other modules, I am now looking at `menu_link_attributes`.

It's very easy to add the class `.fa-comment` to this menu link:

```
<ul class="clearfix nav">
  <li class="nav-item">
    <a href="#comments" class="fa-comment nav-link nav-link-comments">Comments</a>
  </li>
</ul>

```

I'm looking at an old forum thread which explains a template preprocess approach to matching classes starting with `fa-`, and using that value to generate `<i>` tags with the needed classes. This approach may have worked with Drupal 7.

The `THEME_menu_link()` preprocess function does not seem to work in D8 and D9, so I am trying to rewrite it using `THEME_preprocess_links()`. But when I drop a `dump($variables)`; in this function, I do not see all the menu links.

While I'm looking for a different template preprocess function, I thought I'd describe the issue here, in case it's something you've encountered before.

**NOTE:** This question is technically a duplicate, but the old one never got answered so I think I'm safe to ask it again.

# Answer
I went with this expedient solution:

https://github.com/gnikolovski/link\_alter

The developer has a blog post about his approach:

http://dev.studiopresent.com/blog/back-end/altering-menu-links

The crux of it (because link-only answers are discouraged) can be boiled down to this:

> In Drupal 8 you can use the `hook_link_alter(&$variables)` hook to alter menu links. \[...\]But, there is no easy way to identify this menu link. You cannot tell which menu contains this link, so unless you want to alter all links on your site, using this hook to precisely target menu links is a bad idea.
>
> Unless, you somehow add an identifier.
>
> Fortunately, you can easily do just that and make all this more dynamic. You can use `form_alter()` hook to alter menu link edit form, and add something like this:

Thanks to @sonfd for the tip in the comment, which might be even better:

https://www.drupal.org/project/fontawesome\_menu\_icons

Since I already solved my problem and I'm on a deadline, I might not check that module out right away. But it is good to know that it exists!
> 0 votes

---
Tags: theming, navigation, 9
---


title: Add awesome font icon to menu item

text:
# Question
Title: Add awesome font icon to menu item
In my menu I want to add icons. Now when I look for a way to do this, I found a module called Menu Link Attributes. When I configure this on all my menu items, I can't only get it working when using the link function in twig. Now this is not a the expected way of working. Because in the module I add the class names of a awesome font icon. So I need to find a way to manually place the class in my twig file.

The module settings looks like:

```
attributes:
  class:
    label: ''
    description: ''

```

I treid using the {{ item.attributes }} in my menu.html.twig file but this is always empty.

Can someone help me on this? How can I place the class attribute in a custom i tag?

# Answer
> 1 votes
There is a module available specifically for this use case, namely using Font Awesome icons as menu items: https://www.drupal.org/project/fontawesome\_menu\_icons

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


title: "block_name" not found

text:
# Question
Title: "block_name" not found
I installed the Twig Tweak module.

```
{{ drupal_block('block_name') }}

```

doesn't work. In Drupal logs I get the error

> The "block\_name" was not found

"block\_name" I get from the config url of the block config page

```
admin/structure/block/manage/block_name?destination=/de/admin/structure/block

```

Do I do anything wrong?

# Answer
> 3 votes
You need to use:

```
{{ drupal_entity('block', 'MY_BLOCK_ID') }}

```

The Rendering blocks with Twig Tweak guide walks through the three common block types and how to render them.

Block plugins, i.e. custom blocks defined with an annotation

```
{{ drupal_block('MY_BLOCK_ID') }}

```

Block configuration entities, i.e. blocks configured at */admin/structure/block* (what it looks like you're trying to do)

```
{{ drupal_entity('block', 'MY_BLOCK_ID') }}

```

Block content entities, i.e. blocks managed at */admin/structure/block/block-content*

```
{{ drupal_entity('block_content', 'MY_BLOCK_ID') }}

```

# Answer
> 2 votes
You don't need to place the block in Block Layout. Twig Tweak creates a block instance on the fly.

Use the block plugin ID. You find the ID in the annotations of the plugin class. For example the core branding block:

```
* @Block(
 *   id = "system_branding_block",

```

If the block is derived from block content the UUID is added after a colon, for example: `block_content:4124d2132-5ed1-4a12-add1-144e210da157`

More info https://git.drupalcode.org/project/twig\_tweak/-/blob/3.x/docs/blocks.md#block-plugin

---
Tags: theming, blocks, 9
---


# Question
Title: Filtering on child properties in GraphQL
I am using GraphQL to get a list of upcoming events. I am having trouble finding the correct way to filter on the date `value` which is a child of my date field.

The query, which works:

```
query getUpcomingEvents {
  nodeQuery(
    filter: {
      conditions: [
        {operator: EQUAL, field: "type", value: ["ain_event"]},
        {operator: EQUAL, field: "status", value: ["1"]}
      ]
    }
  )
  {
    entities {
      entityLabel
      ...on NodeAinEvent {
        fieldAinEventLocation
        fieldAinEventDate {
          startDate
          endDate
        }
        fieldAinLink {
          uri
        }
      }
    }
  }
}

```

I get this response:

```
 {
  "data": {
    "nodeQuery": {
      "entities": [
        {
          "entityLabel": "EAA AIRVENTURE",
          "fieldAinEventLocation": "OshKosh, WI",
          "fieldAinEventDate": {
            "startDate": "2021-07-26 12:00:00 UTC",
            "endDate": "2021-08-01 12:00:00 UTC"
          },
          "fieldAinLink": {
            "uri": "http://www.eaa.org/en/airventure"
          }
        },
        {
          "entityLabel": "FlightSimExpo",
          "fieldAinEventLocation": "San Diego, CA",
          "fieldAinEventDate": {
            "startDate": "2021-09-24 12:00:00 UTC",
            "endDate": "2021-09-26 12:00:00 UTC"
          },
          "fieldAinLink": {
            "uri": "http://www.flightsimexpo.com/"
          }
        },
        {
          "entityLabel": "Sun 'n Fun",
          "fieldAinEventLocation": "Lakeland, FL",
          "fieldAinEventDate": {
            "startDate": "2020-03-31 12:00:00 UTC",
            "endDate": "2020-04-05 12:00:00 UTC"
          },
          "fieldAinLink": {
            "uri": "https://www.flysnf.org/"
          }
        }
      ]
    }
  }
}

```

I tried adding this, to no avail:

```
{operator: GREATER_THAN_OR_EQUAL, field: "fieldAinEventDate.startDate", value: ["2021-07-25 12:00:00 UTC"]}

```

# Answer
> 1 votes
Found the answer - apparently the fields are referenced differently in the filter conditions. This works:

```
{operator: GREATER_THAN_OR_EQUAL, field: "field_ain_event_date", value: ["2021-07-25 12:00:00 UTC"]}

```

# Answer
> 0 votes
The important info here comes from a comment in the issue @Kevin referenced.

> You can only query the fields available on the entity.

This is because your query is eventually converted to an entityQuery. You must reference fields and their properties as Drupal understands them, not how they're shown when returned from a GraphQL query.

---
Tags: 8
---


title: Schedule cron jobs using Ultimate Cron

text:
# Question
Title: Schedule cron jobs using Ultimate Cron
In one of my modules I would like to create two different cron jobs to handle two different procedures. What I did was to use the Ultimate Cron module, and by implementing the cron api, to schedule one of my cron jobs.

My problem is that in /admin/config/system/cron/jobs only the default from the hook\_cron appears and not from the hook\_cronapi. This is what I wrote.

```
/**
 * Implements hook_cron().
 */
function MODULENAME_cron() {
  //code
}

/**
 * Implements hook_cronapi().
 */
function MODULENAME_cronapi() {
  $items = array();

  $items['generate_excel_files'] = array(
    'title' => 'Table Excel Generate',
    'callback' => 'generate_excel_files_callback',
    'scheduler' => array(
      'name' => 'crontab',
      'crontab' => array(
        'rules' => array('0 3 * * *'),
      ),
    ),
  );

  return $items;
}

function generate_excel_files_callback(){
  //code
}

```

# Answer
Apparently cron api dosn't work with Drupal 8 at this time. What I did to fix my issue was to create one new module to handle only the cron job that I wanted. Then from the UI of Ultimate Cron I would add the rule to schedule my cron job.

```
use Drupal\MODULENAME\Controller\ClassName;

/**
 * Implements hook_cron().
 */
function NEW_MODULENAME_cron() {
 generate_excel_files_callback();
}

function generate_excel_files_callback(){
 $obj = new ClassName();
 $obj->generateXLSX();
}

```
> 2 votes

# Answer
In reply to "but the cron is not running on the scheduled time." From what I understand, the cron will still only run if a request is sent. So any request to any page. If no request are received from the server, the cron will never run, regardless of the time you set. If a request is received, it will check the time lapsed since the last time cron ran and compare with your set value to decide if it needs running again.
> 1 votes

---
Tags: 8, cron
---


# Question
Title: Can I omit the fieldset label in a confirmation email?
Using the Webform module 8.x, I would like that the email sent with the webform\_submission\_values doesn't include the fieldset labels.

How can I achieve this?
Alternatively, is there a way to not send the Page label in the email?

In my case, page label and fieldset label are the same. The confirmation email shows the same value twice.

# Answer
You could check out the hook preprocess\_webform\_confirmation. There you can strip out what you want from the confirmation message.

There is a quite good example over here: https://agileadam.com/2020/04/overriding-a-webform-confirmation-message-in-drupal-8/
> 0 votes

---
Tags: webforms
---


# Question
Title: correct way to access node-revision change property in twig
I have a Drupal 8.9.17 website. My theme (based on Garland) includes in `templates/page.html.twig`:

```
{% if node %}
[...]
Last updated {{ node.changed.value|format_date('custom', 'D M d Y') }}
[...]
{% endif %}

```

This displays the property when viewing nodes at: `/node/<nid>`

However, when attempting to view revisions at `/node/<nid>/revisions/<vid>/view`, format\_date() fails with "null timestamp" error so I assume that the revision is not being properly loaded.

What is the correct way to access the property so it works at both routes?

# Answer
> 1 votes
For information shown for a node, I prefer the *node.html.twig* template, as it doesn't require to first check the page is rendered for a node. The *node.html.twig* template already has the following lines.

```
{% if display_submitted %}
  <footer>
    {{ author_picture }}
    <div{{ author_attributes }}>
      {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
      {{ metadata }}
    </div>
  </footer>
{% endif %}

```

If I wanted to change the way the date is rendered, or which date is shown, without removing the other information shown in the template file, I would replace those lines with the following ones.

```
{% if display_submitted %}
  <footer>
    {{ author_picture }}
    <div{{ author_attributes }}>
      {% trans %}Last updated on {{ node.getChangedTime()|format_date('custom', 'D M d Y') }}{% endtrans %}
      {{ metadata }}
    </div>
  </footer>
{% endif %}

```

For the Garland theme, which is now a contributed theme, the part to change is the following one.

```
{% if display_submitted %}
  <span class="submitted">{{ date }} — {{ author_name }}</span>
{% endif %}

```

You can either replace those lines with the following lines, or the next ones, if you just want to change the date format.

```
{% if display_submitted %}
  <span class="submitted">{% trans %}Last updated on {{ node.getChangedTime()|format_date('custom', 'D M d Y') }}{% endtrans %}</span>
{% endif %}

```

```
{% if display_submitted %}
  <span class="submitted">{{ node.getChangedTime()|format_date('custom', 'D M d Y') }} — {{ author_name }}</span>
{% endif %}

```

As the documentation for the *node.html.twig* template says, not all the node properties and methods are accessible via `node`; only the methods whose names start with *get*, *has*, or *is* are available, together a few common methods such as `id`, `label`, and `bundle`.

---
Tags: 8, theming
---


# Question
Title: Ajax form inside custom system.404 route controller doesn't work
I need to display custom logic in 404 pages so I have overridden the route controller of the system.404 route like this:

```
class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('system.404')) {
      $route->setDefault('_controller', '\Drupal\mymodule\Controller\myController::on404');
    }
  }
}

```

So let's say I am currently at the path **/non-existing-path** and the on404 callback renders my custom content just fine. Problem is I am also rendering a form that contains an Ajax element (a button), which doesn't work because apparently the Ajax request is made towards the following path:

*/system/404?q=non-existing-path&destination=non-existing-path&\_exception\_statuscode=404&ajax\_form=1&\_wrapper\_format=drupal\_ajax*

which, not unexpectedly, returns a Status Code: 404 Not Found

What am I missing?

--

So far I've tried intercepting the NotFoundHttpException with my own listener and changing it to a HttpException(200) in hopes I could turn a 404 page into a 200 but I am at a loss after that and it seems like an overkill.

# Answer
## Ajax form inside custom system.404 route controller does work

For example a node form returned from the controller:

```
<?php

namespace Drupal\mymodule\Controller;

use Drupal\node\Entity\Node;

class MyController extends ControllerBase {

  public function on404() {
    $node = Node::create(['type' => 'article']);
    return $this->entityFormBuilder()->getForm($node);
  }

}

```

The node form is fully functional including complex Ajax operations like opening the media browser.

## Status code 404 or 200

> Problem is I am also rendering a form that contains an Ajax element (a button), which doesn't work because apparently the Ajax request is made towards the following path:
>
> /system/404?q=non-existing-path&destination=non-existing-path&\_exception\_statuscode=404&ajax\_form=1&\_wrapper\_format=drupal\_ajax
>
> which, not unexpectedly, returns a Status Code: 404 Not Found

This is not true, a request for `/system/404` returns a 200 status code when called outside of an exception handler, for example in an ajax request. The `system.404` route is a normal route which is executed by the exception handler in a sub-request. The 404 status is added later and not part of this route.
> 0 votes

---
Tags: 8, ajax
---


# Question
Title: setError or setRebuilld methods breaks validation form
```
<?php

namespace Drupal\my_custom_module\Form;

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

/**
 * Class DefaultForm.
 */
class DefaultForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'default_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['test'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Test'),
      '#maxlength' => 64,
      '#size' => 64,
      '#weight' => '0',
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

    $form_state->setErrorByName('test', 'error');
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $form_state->setErrorByName('test', 'error');
    parent::validateForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $form_state->setRebuild(TRUE);
  }

}

```

When using `setError`, `setErrorByName` or `setRebuild` methods, wether it be in validateForm or submitForm, it breaks my form by giving me a *Allowed memory size of XXX bytes exhausted* error when I submit the form.

Problem is, I don't see anything in the logs except thousands of "404" errors, as if I've something that trigger an infinite loop.

In the example, I have both `setErrorByName` and `setRebuild`, but it happens even with only one of them.

Can you think of anything that can trigger this error ?

# Answer
> 0 votes
Ok, I just found out what was triggering the bug.

Turns out that it was from an other custom module, where one of my Controller was returning a 404 exception. I still don't know how or why, but when (and only when) submitting a form, the 404 exception was triggered.

Sorry to have made you waste your time if you have tried to understand this issue.

---
Tags: 8, forms
---


title: A specified library is missing

text:
# Question
Title: A specified library is missing
On a custom theme "foobar" (based on Olivero) this error message occured. This custom theme is a copy of drupals 9.2.2 olivero's theme.

> Drupal\Core\Asset\Exception\InvalidLibrariesExtendSpecificationException: The specified library "foobar/cke-dialog" does not exist. in Drupal\Core\Asset\LibraryDiscoveryCollector-\>applyLibrariesExtend() (line 154 of core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php).

My custom theme lives in `web/themes/custom/foobar` in `foobar.libraries.yml` I have defined the library:

```
cke-dialog:
  css:
    component:
      css/components/cke-dialog.css: {}

```

I did **cleared all cache** and the path to the library is correct.

I don't see what I'm missing here

# Answer
If you run into this error after installing a custom theme:

> The specified library "foobar/foobar" does not exist.

"*Drupal\Core\Asset\Exception\InvalidLibrariesExtendSpecificationException: The specified library "foobar/cke-dialog" does not exist. in Drupal\Core\Asset\LibraryDiscoveryCollector-\>applyLibrariesExtend() (line 154 of core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php).*"

You might have a *custom module* enabled with the same **machinename**

***Solution:***

1. uninstall custom theme/module
2. Rename the **machinename** of custom theme/module
> 2 votes

---
Tags: theming
---


# Question
Title: Composer require installation profile constraint match error
I am trying to download this install profile https://github.com/UH-StudentServices/student\_guide

I added it to composer.json like this

```
"repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "vcs",
            "url": "git@github.com:UH-StudentServices/student_guide.git"
        }
    ],

```

Then I did `composer require` and I got following error

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

  Problem 1
    - Root composer.json requires uh-studentservices/student_guide ^1.62 -> satisfiable by uh-studentservices/student_guide[v1.62].
    - uh-studentservices/student_guide v1.62 requires drupal/block_access dev-8.x-1.x#1cd59ba6856c897afae2551feaa8e6b7f312489c -> found drupal/block_access[dev-1.x, 1.0.0-alpha1, 1.0.0-beta1, 1.x-dev (alias of dev-1.x)] but it does not match the constraint.

```

I know that the module version should be dev-1.x and not dev-8.x-1.x. I am wondering what should I do. May be I can clone the install profile and edit the composer.json, but How can I include it in composer.json locally?

# Answer
It is necessary to add to the `repositories` key in composer.json *all* of the repositories specified by the project because it seems some are not registered with Packagist.

```
"repositories": [
        {
            "type": "composer",
            "url": "https://asset-packagist.org/"
        },
        {
            "type": "vcs",
            "url": "https://github.com/larowlan/block_access"
        },
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "package",
            "package": {
                "name": "rubaxa/sortable",
                "version": "v1.4.0",
                "type": "drupal-library",
                "dist": {
                    "url": "https://github.com/RubaXa/Sortable/archive/1.4.0.zip",
                    "type": "zip"
                }
            }
        },
        {
            "type": "vcs",
            "url": "https://github.com/UH-StudentServices/video_embed_unitube"
        },
        {
            "type": "vcs",
            "url": "https://github.com/UH-StudentServices/uh_courses_embed"
        },
        {
            "type": "vcs",
            "url": "git@github.com:UH-StudentServices/student_guide.git"
        }
    ],

```

Notice that although the profile will install, you will see:

```
 Cannot apply patch 2795115-6-and-2860399-1 (patches/google_analytics_reports.patch)!

```

That is because there is a patches directory in the parent project that you will not have. I think that if you copy the patches to your own project, the patch may apply.
> 1 votes

---
Tags: 8, composer
---


# Question
Title: Display Block to retrieve information from Order Item's Product Variant and display rating & review inside product page
I am working on an e-commerce website development. I have the conventional Products -\> Product Variants which goes through Order and payment gateway workflow. However, there is something different in this conventional scenario.

I have setup Product -\> Product Variation to categorise the different type of fabrics which fall under a same style.

We have different kinds of fabric which we source from vendors in lots. It so happens that we do not get the same colour, pattern every time and so our Product and Product Variant will be obsolete once we have exhausted the stock.

For this reason, I have setup Taxonomy as per the product classification in our case and I am tagging each product variant with appropriate taxonomy.

This is my Taxonomy hierarchy for example:

And I have made provision to tag this Taxonomy to my Product Variant and this is how it looks:

Now, I would want the user to leave a rating and review for the Product variant after he/she places an order with us. I have added FiveStar rating module and jEditable modules (this is used to edit the field by user in display mode) so that user will be able to Rate and add a Review in "Order Item" as I want the user to be able to rate and review each line item which he/she buys from us. This is how it looks:

It's all fine until now. But now I want to create a Block which will be placed below the product variant selected by user and it should do the following:

1. Place a block below in the Product Variation Page.
2. Fetch all Order Items (within Orders) placed by all users for the same taxonomy which is being shown in the Product Variant Page.
3. Display the User Name, User profile picture, rating and review left by the user from the above fetched order item which contains the same taxonomy information.

I seem to be completely lost in this last step of fetching ratings & reviews by users on previously placed orders on the same taxonomy as the product variation which is being viewed by the user currently. I have tried to see if there is a module which I am trying to achieve but could not find any. Also tried to see how I can build blocks to achieve this but I seem to be lost. Do I need to do some custom coding to achieve this or is it possible to fetch this relationship somehow? Am I missing something?

Thanks!

# Answer
This is what I would try:

Create product block view, add 5 star rating field.

Under advanced (located in the far right).

Add relationship of tax term field.

Add relationship of user.

Add contextual filter of term ID (select provide default value, tax term id from url)

Add contextual filter of user ID (select provide default value, user ID from logged in user).

Place view block, and check a product page.
> 0 votes

---
Tags: 8, views, commerce, taxonomy-terms, blocks
---


# Question
Title: Is the module fully compatible with Drupal 9?
If I create a new project and install The *Commerce Core* module using Composer following the instructions given from the drupalcommerce.org documentation, it would install Drupal 8 by default, not Drupal 9.

I know there are ways to work around this and install Commerce Core on top of Drupal 9. Is it fully compatible with Drupal 9?

# Answer
The project maintainers have marked it as compatible with Drupal 9 (see the project page), so yes, it should be considered compatible, and any issues encountered should be raised as bug reports.
> 1 votes

# Answer
If you followed the instructions given on Installing, those are the instructions to install Drupal 8 and the *Commerce Core* module. That doesn't mean the module isn't compatible with Drupal 9, but that the instructions haven't been updated for Drupal 9.

If `composer create-project drupalcommerce/project-base mystore --stability dev` install Drupal 8, it should be sufficient to force Composer to use the *9.x-dev* version, with `composer create-project drupalcommerce/project-base mystore "9.x-dev" --stability dev`. (The package version is given after the directory where the project is created.)
> 0 votes

---
Tags: commerce, 9
---


# Question
Title: Set a Data Value from Text field to Term Reference field
Node has two fields:

1. Text field
2. Term reference field (autocomplete?)

The `Text field` is old and already has 500 nodes with 500 unique values.

The `Term reference field` is new and needs to contain same data.

So e.g. one node has `Text field` value of `123`, the `Term reference field` also needs somehow to have it set to `123`?

In Rules `Set a value data` only lets you copy content from term reference field into text field, but not vice versa.

Or on page save it does save a new term based on text field to the taxonomy vocabulary, but the term itself does not show up/gets saved in the node/its term field?

Rule in the making:

Under `Actions` we select `Set a data value` and in first screen we select our Taxonomy term reference field that needs to be modified:

And then on a next screen we are stuck, because we cannot select the source for data selector which is a Text field but all available options are only other Term reference fields.

The missing field is added under `Conditions` with `Entity has field` (the `node:field-enter-product-name-`)

# Answer
> 2 votes
This works for D7

> Term reference field (autocomplete?)

in rules, widget does not affect, you just set values, but leave it as autocomplete, a select list cosumes more resourses

> The Text field is old and already has 500 nodes with 500 unique values.

Unique values, this means one unique taxonomy term for each node.

> The Term reference field is new and needs to contain same data.

Your taxonomy term title value it will hold the field value

Your events on node: new/update are ok

On your conditions i can't tell mutch, img is not complete, i sugest to include 'field data value IS empty' on your node taxonomy term rerefence field. This will avoid to create duplicate terms and updating same node twice.

Steps:

1.- In actions secction add an accion

2.- create a new entity (term must exist to be assigned as TR to a node by rules)

3.- select from dropdown: taxonomy term

4.- for term name select node title, avilable in data selector mode

5.- select your taxonomy vocavulary

6.- change (optional) variable name and hit save

7.- add another accion: save entity, the new term

8.- add aonther accion: set a data value

9.- now select your updated node and drill down to find term reference field

10.- and set node field value with the term reference you just created

11.- save node, done

EDIT:

Steps to buit a component:

this way you can call it from node/new event or from a VBO to update all old nodes

a.- add a component of type RULE

b.- in parameters seccion add parameter type: node, label: product node, machine name:product\_node, save settings

c.- on conditions add: entity has field (your product node): select your term reference field

d.- add another condition: your term reference field is empty

do all accions steps explainded above in rule, now you can call your component any where.

---
Tags: 7, views, entities, rules
---


title: Display Node Local Tasks Menu on View

text:
# Question
Title: Display Node Local Tasks Menu on View
I have a view that shows registrations for an Event (Content Type). This tab is shown in the /node/{node}/edit:

This registrations tab refers to the view, which I have inserted in the routing.yml:

```
events.registrations:
  path: '/node/{node}/registrations'
  defaults:
    _entity_view: 'registrations.page_1'
  requirements:
    _custom_access: '\Drupal\events\Access\EventsRegistrationsAccess::checkAccess'
    node: \d+
  options:
    parameters:
      node:
        type: entity:node

```

And inserted additionally, events.links.task.yml:

```
entity.node.registrations:
  route_name: events.registrations
  base_route: entity.node.canonical
  title: 'Registrations'
  weight: 20

```

Then the view displays the following:

Question: How can I show the menu navigation for the node (same as the first image) on the route '/node/78/registrations' which only shows the view without navigation?

# Answer
This was too complicated to attach a navigation menu on a view, instead I used controller that loads a block display from the view programmatically and the navigation was automatically attached.
> 0 votes

---
Tags: 8, views, nodes
---


# Question
Title: Editing media for content editor results in a 404
We have a custom role, location\_editor, which is assigned to users who can only manage media and one content type.

These are the role's media permissions.

>

And if the user now tries to enter any valid media edit url (for example `/media/35/edit` \- which does exist and was created by him), the result is a 404. The admin user can edit it just fine. The user can also access `/media/35/delete` without problems.

I tried to debug the stack already, and for example the MediaAccessHandler is correctly called and returns a accessAllowed().

Is there any right I might miss in the configuration?

Is there a good way to debug this, to find the reason why Drupal considers this a 404 error for this specific role?

# Answer
My colleague managed to find the solution by great intuition (aka "pure luck"). It turned out, that our additional module Rabit Hole is causing side effects here:

Enabling **"Bypass Rabbit Hole for Media"** for the `location_editor` role solved the issue.

His debugging skills are noteworthy thou:

1. he checked issues on drupal.org and as there was nothing about 404 on edit he assumed that it must be something on our side
2. the code was actually clean
3. it must be something funny, probably a side effect of a contrib module
4. he checked the `composer.json` for unusual modules that might have something to do with access check -\> bingo :)

Many thx!
> 0 votes

---
Tags: media, 9
---


# Question
Title: Programmatically verify a taxonomy term has been added to a node
I'm currently checking the node type and status, using the following code.

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

foreach ($query as $nid) {
  // …
}

```

I need to know whether a taxonomy term has been added to a node. I don't need to know the name or ID of that term, which is a taxonomy term from the *Group Required* vocabulary.

What code should I use to achieve this?

# Answer
> 2 votes
Since you know that your tag will always be in one specific field, you can use the exists() method on your query to only fetch ids of entities where that field has a value, i.e. is not empty.

For example:

```
$entity_ids = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->getQuery()
  ->condition('type', 'content_page')
  ->condition('status', 1)
  // Check if field has a non empty value
  ->exists('MY_TAXONOMY_REF_FIELD')
  // exists('MY_FIELD') is equivalent to condition('MY_FIELD', NULL, 'IS NOT NULL')
  ->execute();

```

Then, load your entities:

```
$entities = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadMultiple($entity_ids);

```

---
Tags: 8, nodes, taxonomy-terms
---


title: Checkbox Ajax call back giving me error

text:
# Question
Title: Checkbox Ajax call back giving me error
New to drupal 7, following code should work fine according to my knowledge can someone help me why ajax give me error in console ? and what the solution

**Code**

```
function user_activity_tree_structure_showoptional_form($form, &$form_state, $base_nid) {
      $form['enablecond'] = array(
        '#type' => 'checkbox',
        '#title' => "Checkbox  ",
        '#ajax' => array(
        'callback' => 'ajaxcall_func',
        'progress' => 'false',
      ),
    );
    return $form;
}

function ajaxcall_func(&$form, $form_state)
{
    setcookie("checkbox_1",$form['enablecond']["#value"]);
    return null;
}

```

**Console Error**

```
js_Y5H_CdmZpIvEir8-B6htnqHb6_vJBznC3jPygHLV6dE.js:495 Uncaught TypeError: Cannot read property 'Drupal' of undefined
at Object.attach (js_Y5H_CdmZpIvEir8-B6htnqHb6_vJBznC3jPygHLV6dE.js:495)
at Object.<anonymous> (js_UYCsqqVg9hDgzN1bjf7T6Fy66IJRk810uQF1qy9Lgo4.js:61)
at Function.each (js_H_BqcoIBkzDSvN9rxK_RAvqVRCfKG3dcLloVRen-E84.js:4)
at Object.Drupal.attachBehaviors (js_UYCsqqVg9hDgzN1bjf7T6Fy66IJRk810uQF1qy9Lgo4.js:59)
at Drupal.ajax.success (js_Y5H_CdmZpIvEir8-B6htnqHb6_vJBznC3jPygHLV6dE.js:2127)
at Object.success (js_Y5H_CdmZpIvEir8-B6htnqHb6_vJBznC3jPygHLV6dE.js:1858)
at Object.c.success (js_Y5H_CdmZpIvEir8-B6htnqHb6_vJBznC3jPygHLV6dE.js:111)
at c (js_H_BqcoIBkzDSvN9rxK_RAvqVRCfKG3dcLloVRen-E84.js:4)
at Object.fireWith [as resolveWith] (js_H_BqcoIBkzDSvN9rxK_RAvqVRCfKG3dcLloVRen-E84.js:4)
at k (js_H_BqcoIBkzDSvN9rxK_RAvqVRCfKG3dcLloVRen-E84.js:6)

```

# Answer
There was actually a conflict between Drupal 7 - contributed module -\> navbar -\> js -\> displace.js with fancytree.js.

Just answering this question so that you should make sure that any third party library shouldn't conflict with core and contributed modules js libraries.
> 0 votes

---
Tags: 7, ajax
---


# Question
Title: What code is equivalent to this SQL query?
I have a SQL query that works just fine on its own.

```
SELECT timestamp FROM accesslog
WHERE uid = 1
AND path = 'mypath'
AND timestamp > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 4 WEEK));

```

I am trying to write the code to execute the equivalent query for Drupal 7. With the following code, I get all the values for the user.

```
$ts = 'UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL '.$interval.'))';
$query = db_select('accesslog', 'a');
$query->addField('a', 'uid');
$query->addField('a', 'path');
$query->addField('a', 'timestamp');
$query->condition('a.uid', $uid);
$query->condition('a.path', $path);
$query->condition('a.timestamp', $ts, '>');
$result = $query->execute();

```

This code throws an exception.

```
$result = db_query("
SELECT timestamp
FROM accesslog
WHERE uid = :uid
AND path = :path
AND timestamp > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL :interval))",
array(':uid'=>$uid,
      ':path'=>$path,
      ':interval'=>$interval))->fetch();

```

> PDOException: SQLSTATE\[42000\]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 3: SELECT timestamp FROM accesslog WHERE uid = :uid AND path = :path AND timestamp \> UNIX\_TIMESTAMP(DATE\_SUB(NOW(), INTERVAL :interval)); Array ( \[:uid\] =\> 237 \[:path\] =\> meplus \[:interval\] =\> 4 WEEK ) in check\_page\_visited\_in\_time\_interval()

I'm guessing the issue is with the `timestamp >` part, but I am not sure how to get that part done.

What code should I use to execute that query?

# Answer
Instead of the above one try the following query,

```
$date = date_create();
date_modify($date, '-4 week');
$interval =  $date->format('U');

$result = db_query("
SELECT timestamp
FROM accesslog
WHERE uid = :uid
AND path = :path
AND timestamp > :interval",
array(':uid'=>$uid,
      ':path'=>$path,
      ':interval'=>$interval))->fetchAll();

```
> 1 votes

# Answer
For code that works with MySQL, PostgreSQL, and SQLite, I would do what the Statics module does in `statistics_cron()`: Instead of depending on the date and time functions supported from the database engine, I would calculate the timestamp on the PHP side. (I assume the intent is getting all the pages the user visited in the last 4 weeks.)

```
$query = db_select('accesslog', 'a');
$uid_alias = $query->addField('a', 'uid');
$path_alias = $query->addField('a', 'path');
$timestamp_alias = $query->addField('a', 'timestamp');
$result = $query->condition($uid_alias, $uid)
 ->condition($path_alias, $path)
 ->condition($timestamp_alias, REQUEST_TIME - 2419200, '>=') // 4 weeks are 2419200 seconds.
 ->execute();

```
> 0 votes

---
Tags: 7, database
---


# Question
Title: What is the correct way to load a JavaScript library?
I am trying to display form data as a line chart. I am running Drupal 9 in Lando. I am using Charts 5.0.x w/ the Highcharts submodule. I installed the Highcharts JS library using composer. This is the relevant code.

### .libraries.yml

```
highcharts:
  js:
    /libraries/highcharts/highcharts.js: {  }
  dependencies:
    - core/jquery

```

### .module

```
function stats_degrees_theme() {
  return [
    'mychart_template' => [
      'variables' => ['chart_var' => NULL],
    ],
  ];
}

```

### .routing.yml

```
stats_degrees.render_form:
  path: '/statistics/stats-degrees'
  defaults:
    _title: 'Engineering and Physical Science Degrees Earned by Members of Underrepresented Groups'
    _form: '\Drupal\stats_degrees\Form\StatsDegreesForm'
  requirements:
      _permission: 'access content'

```

### .html.twig

```
{# stats_degrees/templates/mychart-template.html.twig #}
{{ attach_library('stats_degrees/highcharts') }}

<div id='container' style='width:100%;height:100%;'>
  {{ chart_var | raw }}
</div>

```

### Submission handler

```
public function submitForm(array &$form, FormStateInterface $form_state) {
   $form_state->setRebuild();
  }

```

### Form builder

```
 if ($form_state->isRebuilding()) {
   // get the form data and build the chart
    // get twig template
      $form['#theme'] = 'mychart_template';
      $form['#attached'] = array(
        'library' => array('stats_degrees/highcharts')
      );
      $form['#chart_var'] = $rendered_chart;
  }

```

The template is rendered without chart. When I look at the HTML markup, I see the rendered chart code in chart\_var and this is in the console.

> Uncaught ReferenceError: Highcharts is not defined at js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:4396
> js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:128 Uncaught TypeError: $(...).highcharts is not a function at HTMLDivElement.
> \[anonymous\] (js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:4373
> at Function.each (js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:2)
> at S.fn.init.each (js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:2)
> at Object.attach (js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:4370)
> at js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:139
> at Array.forEach ()
> at Object.Drupal.attachBehaviors (js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:136)
> at js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:365
> at HTMLDocument.listener (js\_fLkad5FjTCYgrjWIVyhfUxVUTz4-TXopB2EJOzHz820.js:353)

When I drill down into the error I see it is failing here.

```
(Highcharts)})(function(w){(function(b){function r(b,a){this.init(b,a)} var v=b.CenteredSeriesMixin,u=b.each,n=b.extend,q=b.merge,g=b.splat;n(r.prototype,{coll:"pane",init:function(b,a){this.chart=a;this.background=[];a.pane.push(this);this.setOptions(b)},setOptions:function(b){this.options=q(this.defaultOptions,this.chart.angular?{background:{}}:void 0,b)},render:function(){var b=this.options,a=this.options.background,c=this.chart.renderer;

```

Am I loading the Highcharts library correctly?

# Answer
It looks like what's happening is you need to add 'charts\_highcharts/highcharts' as a dependency, like so:

```
highcharts:
  js:
    /libraries/highcharts/highcharts.js: {  }
  dependencies:
    - core/jquery
    - charts_highcharts/highcharts

```

(If this doesn't work, try 'charts\_highcharts/charts\_highcharts' instead of 'charts\_highcharts/highcharts')
> 0 votes

---
Tags: theming, javascript, charts
---


# Question
Title: What is the token for the file download link of a media entity?
Using the *linked\_field* module and the *\[paragraph:field\_pbpresentation\_file:entity:url\]* token, I get the edit link for the media entity, not the link to download the file itself.

What token should I use for the download link?

# Answer
> 0 votes
You probably want the URL of the file entity, not the media entity.

You have to find out the field name of the file field in the media entity. If you are using a core preinstalled media type it could be for example `field_media_file`. Then you can access the file entity and the URL:

```
[paragraph:field_pbpresentation_file:entity:field_media_file:entity:url]

```

---
Tags: 8, media, paragraphs
---


# Question
Title: How do I debug overridden twig templates?
How do I debug the template overrides. The debugger stops on page.html.twig but doesn't stop on sub templates such as

web/themes/custom/localtheme/templates/field--paragraph--field-pbcrossfade-image--crossfade-banner.html.twig

The page.html.twig breaks here

The debugger does not break in the sub template.

# Answer
I don't think `{{ breakpoint }}` is a valid twig function to have a PHP pause.

If you have the module devel installed, you can use `{{ devel_breakpoint() }}`

Otherwise you can use `{{ drupal_breakpoint() }}` if you have Twig Tweak installed.

Documentation : https://www.drupal.org/docs/contributed-modules/twig-tweak-2x/cheat-sheet#s-drupal-breakpoint
> 0 votes

---
Tags: theming, debugging
---


# Question
Title: How to get access to a $form in hook_entity_view_display_alter?
In Drupal 9, I added a `views_add_to_cart_form` view mode to be able to render a product entity with only the Variations field formatted as add to cart form being displayed. That all works as expected, but I am trying to remove the quantity widget on the commerce add to cart form **for that specific view display** by using `unset($form['quantity']);`.

I am not sure if it is better to bring the view display information into a form\_alter, or if it would be cleaner to get the form information in a hook\_entity\_view\_display\_alter.

I was trying something like this in the form alter, but felt like it was not at all the right way to go about it

```
$display = \Drupal::service('entity_display.repository')->getViewDisplay('commerce_product', 'simple_product', 'views_add_to_cart_form');
if (isset($display)) {
  unset($form['quantity']);
}

```

(I realize my `if (isset($dsiplay)) {` won't cut the mustard...)

It seems like it would be better to use hook\_entity\_view\_display\_alter and get the necessary $form stuff in there:

```
/**
 * Implements hook_entity_view_display_alter().
 */
function MY_entity_view_display_alter(\Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, array $context) {
  if ($context['entity_type'] == 'commerce_product' && $context['view_mode'] == 'views_add_to_cart_form') {
    // Get access to the $form_id and unset($form['quantity']);
  }
}

```

So how do I get access to `&$form, FormStateInterface &$form_state, $form_id` stuff inside hook\_entity\_view\_display\_alter?

# Answer
> 0 votes
As a rule of thumb if the hook doesn't provide you the object you need, it means you are most likely at the appropriate place to execute your code.

Considering your question, I think you should be using `hook_form_alter` with `$form_id === add_to_cart_form` or something close to that. (https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21form.api.php/function/hook\_form\_alter/8.8.x)

Then you can do the `unset` there.

A better practice would be to give `#access = FALSE` instead of unsetting the element `$form['quantity']['#access] = FALSE;`

---
Tags: forms, commerce, 9
---


title: Trigger an action programmatically

text:
# Question
Title: Trigger an action programmatically
I have defined an action and want to trigger it from a hook.

We do **not** want to use the Rules module, because it is still buggy with Drupal 8. So, we cannot use `rules_invoke_component()`.

What is the correct way to trigger an action? Do I need to construct a new `Action` object? Do I need a service? Is there documentation on that anywhere?

# Answer
> 3 votes
This works:

```
$action = \Drupal::entityTypeManager()
  ->getStorage('action')
  ->load('send_mail');
if ($action) {
  $action->execute($entity);
}

```

# Answer
> 2 votes
You have to pass $entity in as an array - try

```
$action = \Drupal::entityTypeManager()
  ->getStorage('action')
  ->load('send_mail');
if ($action) {
  $action->execute([$entity]);
}

```

---
Tags: 8, hooks, actions
---


title: Add rows to form tableselect with AJAX

text:
# Question
Title: Add rows to form tableselect with AJAX
I would like to:

1.) Add rows to a tableselect form element when a user clicks on a button.

2.) See which rows are selected when a user clicks on another button.

Part one is complete (I've only included relevant code):

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

  //Tableselect
  $header = [
    'first_name' => $this->t('First Name'),
  ]

  $form['results'] = [
    '#type' => 'tableselect',
    '#title' => $this->t('Select contact to add to message list'),
    '#header' => $header,
    '#options' => [],
    '#multiple' => TRUE,
    '#empty' => $this->t('No users found'),
    '#prefix' => '<div id="search-results">',
    '#suffix' => '</div>',
  ];

  //This button adds rows to tableselect
  $form['button_one'] = [
    '#type' => 'button',
    '#value' => $this->t('Search'),
    '#ajax' => [
      'callback' => '::contactSearch',
      'wrapper' => 'search-results',
      'effect' => 'fade',
    ],
  ];

  //This button displays $form_state in a kint
  $form['button_two'] = [
    '#type' => 'button',
    '#value' => $this->t('Debug'),
    '#ajax' => [
      'callback' => '::debugSearch',
      'wrapper' => 'search-results',
      'effect' => 'fade',
    ],
  ];

  //This is for kint
  $form['debug'] = [
    '#type' => 'container',
    '#attributes' => [
      'id' => ['debug-out'],
    ],
  ];

}

/**
 * Ajax callback for button one
 */
public function contactSearch(array &$form, FormStateInterface $form_state) {

  //The AJAX callback replaces the tableselect with one that has more rows.
  $header = [
    'first_name' => $this->t('First Name'),
  ];

  $rows = [
    1 => 'Ben',
    2 => 'Sarah',
    3 => 'Steve',
  ];

  $form['results'] = [
    '#type' => 'tableselect',
    '#title' => $this->t('Select contact to add to message list'),
    '#header' => $header,
    '#options' => $rows,
    '#multiple' => TRUE,
    '#empty' => $this->t('No users found'),
    '#prefix' => '<div id="search-results">',
    '#suffix' => '</div>',
  ];

  //This seems to be necessary specifically for tableselect
  $form['results'] = Tableselect::processTableselect($form['results'], $form_state, $form);
  $response->addCommand(new ReplaceCommand('#search-results', $form['results']));
  return $response;

}

/**
 * Ajax callback for button two
 */
public function debugSearch(array &$form, FormStateInterface $form_state) {

  //Show current state of tableselect in a kint
  $response = new AjaxResponse();
  $debugOut = @Kint::dump($form_state->getValue('results'));
  $response->addCommand(new ReplaceCommand('#debug-out', $debugOut));
  return $response;

}

```

What I expect:

I expect button one to update $form so that when I click on button two, $form\_state-\>getValue('results') will return which rows are selected.

What happens:

The button 2 AJAX function doesn't register any change to the tableselect element.

Visually, the tableselect changes as I expect after clicking button one: the extra rows are added. But the AJAX callback for button 2 doesn't see any change.

I need to know which rows are selected AFTER the tableselect has been updated.

# Answer
> 1 votes
On this DA issue there is a comment:

> You can't change elements on callback or validateForm(), you need to put it on buildForm() method.

Which is what I was doing. I was adding rows to $form inside the AJAX callback.

So, I create a method called by buildForm() that evaluates the number on rows based on values in $form\_state:

```
    $form['search_results']['results'] = [
      '#type' => 'tableselect',
      '#title' => $this->t('Select contact to add to message list'),
      '#header' => $header,
      '#options' => $this->getRows($form_state),
      '#multiple' => TRUE,
      '#empty' => $this->t('No users found'),
      '#prefix' => '<div id="search-results">',
      '#suffix' => '</div>',
    ];

```

My understanding is that the AJAX callback will call buildForm() again, which will call my getRows() method.

The new rows in tableselect returned using this approach are available in $Form and $form\_state will show which are selected.

---
Tags: forms, ajax
---


# Question
Title: Add ThirdPartySettings to individual paragraphs of a certain bundle?
I want to add configuration settings to Paragraph entities in a specific bundle in Drupal 8. Theres potentially a lot of options and the need to change/update them over time, so I figure the best way is through ThirdPartySettings and not adding more fields to it. I am going to use these values to influence certain aspects of the render and for search queries.

I can see where you can add settings to the bundle itself, but how do you provide them for each paragraph instance on a node via a config schema?

I see this in the Paragraphs config schema dir:

```
paragraphs.paragraphs_type.*:
  type: config_entity
  label: 'Paragraphs type config'
  mapping:
    .....

```

But `paragraphs.paragraphs_type.*.third_party.foo...` would add it to the bundle, right?

# Answer
A paragraph is a content entity, which doesn't support third party settings. Third party settings are just for config entities.

The solution is just to use fields, awkward as it might seem.
> 1 votes

---
Tags: 8, entities, paragraphs
---


title: how was text format deleted?

text:
# Question
Title: how was text format deleted?
I migrated a drupal 6 site to drupal 8. It still needs the php module. I have a text format with the "PHP evaluator" filter enabled.

Overnight, this text format disappeared.

I was asleep. Only the adminstrator role has "administer text formats and filters" permission but I have no reason to believe an administrator deleted it manually.

How else could this have got removed?

---

I recovered by:

* backed up the site;
* `drush cex`
* copy `filter.format.php_code.yml` from a backup
* `drush cim`
* flushed all caches

It is rather worrying that this could have happened. I can't immediately see anything relevant in the logs (but not sure where to look). Is there a good way to create audit logs to record administrator actions?

# Answer
I have managed to replicate the issue on a backup.

1. revert to known working snapshot
2. visit https://example.org/admin/config/content/formats \- **PHP format is present**
3. visit https://example.org/admin/modules/uninstall
4. select "help topics" (experimental module that comes with core)
5. select "uninstall"
6. flush all caches
7. visit https://example.org/admin/config/content/formats \- **PHP format is missing**

~~This seems like a bug in core's module uninstall process.~~ Appearances are deceptive. It appears the fault actually lies with the PHP module: #3016061: Text format with system name "php\_code" is deleted when you view admin/modules/uninstall
> 0 votes

---
Tags: 8
---


title: Media name as link to file

text:
# Question
Title: Media name as link to file
I have a "Document" media bundle, and I have a custom view mode called "Embed".

In that view mode, I have removed everything except the `media name` property and my `document` file field.

For `media name` the only format available is `plain text`, with an option to "Link to Media". This provides a link like `media/2`, where you can click on a link to download the file.

For my `document` field, I get `Generic file` (the file name with a link to it), `RSS enclosure`, `Table of files`, and `URL to file`.

Does anyone have a simple way to generate a link like `Generic file` but show the `media name` instead of the file name? e.g. `Handbook` vs `handbook__2017_fin_updated_some_other_rubish_26.pdf`

# Answer
> 1 votes
**How I did this**

As per @Berdir's suggestion, I have done this in the theme. However, instead of hijacking the output in the media (which is perfect for control based on the media display mode), I have chosen to set the filename.

Unfortunately, I couldn't find a way to get the media entity from the file, so I use `template_preprocess_media` which has both the media entity and the file entity, and then the `setFilename()` method.

Loosely:

```
file = $variables['elements']['#media']->field_file->entity;
$file->setFilename($variables['name']);

```

For improved accessibility, you should "show" the file size and type, and while this available here, it felt cleaner to do this in `file-link.html.twig` where a bunch of other nice things are added to the attributes for you.

# Answer
> 4 votes
This is not possible with just the formatter configuration, someone would need to create a "Link to file with entity label" formatter, which would also not be that complicated.

But you can do it quite easily directly in a media template, the name would be something like `media--document--embed.html.twig` and the content then looks like this:

```
<div{{ attributes }}>
  <a class="document-link" title="{{ name }}" href="{{ file_url(elements['#media'].field_document.entity.uri.value) }}" target="_blank" rel="noopener">{{ name }}</a>
</div>

```

I also included a target and noopener rel here, but that's of course up to you.

# Answer
> 2 votes
```
function template_preprocess_media(array &$variables) {
  $media = $variables['media'];
  $name = $media->getName();
  if (!empty($name)) {
    $mediaArray = $media->toArray();
    if (!empty($mediaArray['field_media_file'][0]['target_id'])) {
      $fileId = $mediaArray['field_media_file'][0]['target_id'];
      $file = \Drupal\file\Entity\File::load($fileId);
      $file->setFilename($name);
    }
  }
}

```

# Answer
> 1 votes
The best way to implement this is not to set filename. Instead, you should set the #description of the file. In the following example, I have a media of a bundle called "file" and in it, I have a file field called "field\_media\_file". Then I set the description of each file to be the media name.

```
if ($variables['media']->bundle() == 'file' && !empty($variables['content']['field_media_file'])) {
    foreach (Element::children($variables['content']['field_media_file']) as $delta) {
      $variables['content']['field_media_file'][$delta]['#description'] = $variables['name'];
    }
}

```

# Answer
> 0 votes
This module seems like it does what you are asking (BTW had the same question which led me here): https://www.drupal.org/project/link\_plain\_text\_formatter

# Answer
> 0 votes
You can also do a file link preprocess function that can look up the media entity for the file and and then set the link text accordingly. Replace "field\_media\_file" with your media entity's field name. If you want to do this for more than one media type, you'll have to expand it accordingly as well.

```
function template_preprocess_file_link(array &$variables) {
  $file = $variables['file'];
  $result = \Drupal::entityQuery('media')
    ->condition('bundle', 'document')
    ->condition('field_media_file.target_id', $file->id())
    ->execute();
  if (!empty($result)) {
    $media = \Drupal::entityTypeManager()->getStorage('media')->load(reset($result));
    $variables['link']->setText($media->label());
  }
}

```

---
Tags: 8, files, media
---


# Question
Title: How to make custom views exposed filter work with AJAX
I don't know how to make my custom exposed filter work with AJAX:

I have a view that has a contextual filter that filters for Node creation date by year. This filter gets filled via a query parameter like '?year=2021'.

Via the code below I have created a custom exposed filter form element to allow the user to select a year.

This works great unless AJAX is activated. How can I make this work with AJAX enabled?

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (isset($form['#id']) && $form['#id'] == 'views-exposed-form-news-page-1') {

    $years = ['all' => t('- All -')];
    for ($i = date('Y'); $i >= '1997'; $i--) {
      $years[$i] = $i;
    }

    $form['year'] = [
      '#title' => new TranslatableMarkup('Year'),
      '#type' => 'select',
      '#options' => $years,
      '#size' => NULL,
      '#default_value' => 'all',
    ];

  }
}

```

# Answer
> 0 votes
Not sure if this will be helpful in your circumstance, but I was following this tutorial (https://www.flocondetoile.fr/blog/filter-content-year-views-drupal-8) and ran into the same issue that others did - it doesn't work with AJAX.

The solution was to avoid creating a contextual filter, and instead create a regular exposed filter based on (in my case) the node date field via the views admin UI. The same alter hook was used to edit the select values on that filter instead of the contextual filter.

We did have to edit the alter hook code from the tutorial. This:

```
$options['all'] = new TranslatableMarkup('- All -');

```

Becomes:

```
$options[''] = new TranslatableMarkup('- All -');

```

and this:

```
  $form['y'] = [
    '#title' => new TranslatableMarkup('By year'),
    '#type' => 'select',
    '#options' => $options,
    '#size' => NULL,
    '#default_value' => 'all',
  ];
  $form['#submit'][] = '_plb_di_year_filter_submit_year';

```

becomes this:

```
  $default_year = $form_state->getUserInput()['field_year_value'];
  $form['field_year_value'] = [
    '#title' => new TranslatableMarkup('By year'),
    '#type' => 'select',
    '#options' => $options,
    '#size' => NULL,
    '#default_value' => '',
    '#value' => $default_year,
  ];

```

---
Tags: 8
---


# Question
Title: How to alter page title "Create X" to "Add X" for all X?
In Drupal 7, there was `drupal_get_title()`and `drupal_set_title()`. They're history.

I want to alter the page title "Create X" to "Add X" for all X, and I think `hook_preprocess_page_title()` in my .theme-file is the right place to do it. (If you disagree, please say so.)

I.e. I want it to be 'Add X' for any 'X' when it originally was 'Create X'. For example: 'Create article' should become 'Add article'. And if the title is 'Bar Article', I should be left as is.

Basically, I want to sniff the title string and if it starts with 'Create ', alter it to 'Add '. This is so far I've gotten, and this is obviously incomplete:

```
/**
 * Implements hook_preprocess_page_title().
 */

```

First attempt:

```
function mytheme_preprocess_page_title(&$variables) {
  $request     = \Drupal::request();
  $route_match = \Drupal::routeMatch();
  $title       = \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
}

```

Second attempt, based upon suggestion by 4k4:

```
function mytheme_preprocess_page_title(&$variables) {
  $title = $variables['title'];
  if ($title instanceof TranslatableMarkup) {
    $title = $title->getUntranslatedString();
    $title = str_replace('Create', 'Add', $title);
    $variables['title'] = t($title);
  }
  else {
    $variables['title'] = Markup::create(str_replace('Create', 'Add', $title));
  }
}

```

The titles I want to change come from Drupal core and they are translatable, so its the `instanceof TranslatableMarkup` branch that gets executed, but I agree with having a fallback in case they're not, is a good idea.

However, while a good start, this is not a complete solution. It changes the rendered title of the add article form from "Create article" to "Add @name".

I've upvoted the answer by 4k4, as it goes much further towards a solution than my first attempt, but it is still not complete.

I don't want to use the **String Overrides** module for this for several reasons, mostly because this theme should work across translations without requiring extra configuration when deployed.

# Answer
> 1 votes
> I want to alter the page title "Create X" to "Add X" for all X, and I think hook\_preprocess\_page\_title() in my .theme-file is the right place to do it. (If you disagree, please say so.)

You can only change the title displayed in the body tag, not the title metatag in the html tag.

> $title = \Drupal::service('title\_resolver')-\>getTitle($request, $route\_match-\>getRouteObject());

This gets you only the title from the route definition or callback, not a title set by `#title` in the rendered output.

> $title is not a string. The string is somewhere in there, but how do I extract it to see what it starts with?

It's a markup object. Either a plain one or a translatable one. See How do you edit content of a Drupal\Core\Render\Markup instance via a preprocess function in Drupal 8? or How do I change text on the submission button in the node form?

> How do I actually change it in the context of a preprocess hook. I.e. what is equivalent of drupal\_set\_title() in this context?

In a preprocess hook you can only change variables which the template is displaying, in this case:

```
$variables['title'] = 'Foo title';

```

If it contains HTML markup to avoid autoescaping:

```
$variables['title'] = \Drupal\Core\Render\Markup::create('<i>Foo</i> title');

```

If it is translatable:

```
$variables['title'] = t('Foo title');

```

Code example:

```
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Render\Markup;

/**
 * Implements hook_preprocess_page_title().
 */
function mymodule_preprocess_page_title(&$variables) {
  $title = $variables['title'];
  if ($title instanceof TranslatableMarkup) {
    $title_untranslated = $title->getUntranslatedString();
    $title_replaced = str_replace('Create', 'Add', $title_untranslated);
    $variables['title'] = t($title_replaced, $title->getArguments());
  }
}

```

---
Tags: theming, 9
---


# Question
Title: How do I fix this error about a missing class?
I'm using the Commerce Canada Post module.

The code in the src/Plugin/Commerce/ShippingMethod/CanadaPost.php file uses a `CanadaPost\Rating` class which isn't defined that namespace and it causes an error.

The src/Api/RatingService.php file contains the following code.

```
/**
 * Returns an initialized Canada Post Rating service.
 *
 * @param array $api_settings
 *   The Canada Post API settings.
 *
 * @return \CanadaPost\Rating
 *   The rating service class.
 */
protected function getRequest(array $api_settings) {
  $config = $this->getRequestConfig($api_settings);

  return new Rating($config);
}

```

How do I fix this error?

# Answer
> 2 votes
The CanadaPost\Rating class is not part of the *Commerce Canada Post* module, rather it's part of a dependency, the PHP Canada Post API, that should be installed into your vendor directory by composer in the thejacer87/php-canadapost-api subdirectory.

If it's not there, then my best guess is that you tried to install Commerce Canada Post without using composer. Install it, the Commerce Canada Post module, with composer and the dependency will be installed and it'll resolve your error.

See Download contributed modules, themes and their dependencies using Composer on drupal.org for how to install a module with composer.

```
composer require drupal/commerce_canadapost

```

---
Tags: commerce
---


# Question
Title: Specify the theme when creating content / importing content via Feeds
I want to force all content to be created using my primary site theme. I want to do this because I am using a renderer in `MYMODULE_node_presave()` like this:

```
function MYMODULE_node_presave(NodeInterface $node) {
  $renderer = \Drupal::service('renderer');

  $content_type = $node->getType();
  if ($content_type == 'page') {
    $viewmode_render = $node->get('field_text_main_to_render')
      ->view('rendered_output');
    $processed_display = $renderer->renderPlain($viewmode_render);
    $node->set('field_text_main_display', "$processed_display");
    $node->field_text_main_display->format = 'processed';
}

```

My site uses Bartik as the main theme and Seven as the admin theme.

Under Appearance settings (/admin/appearance), I have checked the preference *Use the administration theme when editing or creating content*. This ensures that nodes are rendered in Bartik upon creation in the UI.

However, when I resave nodes on `/admin/content`, the nodes are re-saved with Seven, instead of Bartik. So I added a `ThemeNegotiator`:

```
/**
 * Select the correct theme for various routes.
 */
class ThemeNegotiator implements ThemeNegotiatorInterface {

  /**
   * {@inheritDoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    return $this->negotiateRoute($route_match) ? TRUE : FALSE;
  }

  /**
   * {@inheritDoc}
   */
  public function determineActiveTheme(RouteMatchInterface $route_match) {
    return $this->negotiateRoute($route_match) ?: NULL;
  }

  /**
   * Select the theme for special cases.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The currently matched route.
   *
   * @return bool|string
   *   The theme name to use (string) or false (bool).
   */
  private function negotiateRoute(RouteMatchInterface $route_match) {
    $route_name = $route_match->getRouteName();
    // Admin content page must use node render theme.
    // Why: "Save content" action will use the theme of this page.
    if ($route_name === 'system.admin_content') {
      return 'bartik';
    }
    else {
      return FALSE;
    }
  }

}

```

Now, when I run a bulk node resave on `/admin/content`, nodes are rendered correctly with Bartik.

Next, I installed the Feeds module. Now, when I import nodes via CSV using Feeds, they are rendered using Seven, not Bartik. I want to force these nodes to also be rendered using Bartik, but I don't know how to do that. (For example, if there was a way to use `negotiateRoute` in the `ThemeNegotiator`, that would be fine, but I don't know how to set that up.) Any ideas?

# Answer
Content can be rendered in any theme, and is rendered in the current theme at any given time. You do not save content as belonging to a theme. Rather, if you want different themes to show content, you can try the Switch Page Theme module.
> 0 votes

---
Tags: feeds, 9, theme-negotiation
---


# Question
Title: Custom html.html.twig for a display mode
While using display suite in drupal 8.6.2 Is it possible to have a custom `displaymode-html.html.twig` that replaces the default `html.html.twig`?

So far I have tried enabling the view mode dev hints in `themename.yml` but it doesn't seem to be showing me anything for `html.html.twig`

# Answer
I'm not used to Display Suite but I'd recommend you to have a look at hook\_theme\_suggestions\_alter() in order to build your own twig template suggestions based on specific conditions that you can set using the `$variables` variable values.
> 0 votes

---
Tags: 8, theming, display-suite
---


# Question
Title: Downloading xlsm is disabled for anonymous user: What function is responsible for this access control?
We have a D7.8 site with Panopoly 7.x-1.81. No access control modules.

A standard filefield is used for uploads and functions perfectly for the usual set of mime types.

We recently extended the list of allowable extensions in the field definition to include .xlsm

Our xlsm files are code-signed and certified by a Microsoft-approved cert provider.

We can upload the xlsm files no problem, and logged-in users can see the download link.

\**However, anonymous users do not see the download link.

We are not sure what function could be deciding to block display of this filetype.\**

Can anyone suggest possible avenues for investigation?

# Answer
Thanks guys, we found an answer for this one. We needed to add the proper MIME Type for xlsm: 'application/vnd.ms-excel.sheet.macroEnabled.12' Hope that helps!
> 0 votes

---
Tags: 7, files
---


# Question
Title: View with multiple blocks, how to specify which is shown?
I have a view that is placed as a block below my main content. Within that view I have block "displays". each having a different contextual filter for their id from url.

The problem is when the view is displayed, it only shows one of the Displays, how do i specify which is shown ?

# Answer
> 0 votes
When you place a block, it give you option to select between the different named variants (displays) within the view.

---
Tags: 8, views, blocks
---


# Question
Title: How to create automatic url alias for taxonomy/term/%tid/feed
How can I set automatic URL aliases for taxonomy feeds?

Say I have a term with `tid=1`, named `holidays`, with a system URL of `/taxonomy/term/1` that is accessible by the URL alias `/holidays`. Then I want the rss feed for that term to be accessible on the URL alias `/holidays/feed` or `/holidays/rss.xml`. That sounded rather easy when I first thought about it, but it seems that pathauto is not supporting that (or I missed it). I know I can create the alias manually, but given a number of X terms on the site, I'd rather use a pattern for automatic generation.

The only issues about this topic that I could find are both outdated:

Anything I missed or any contrib module I didn't see that provides this functionality?

# Answer
> 2 votes
Based on suggestions by @4k4 in the comments section of the question I have solved this problem by implementing a custom PathProcessor.

I'll share the bare minimum code for making this work in form of a custom module (called `term_feed_alias` for the purpose of this example) for which you need 3 files.

`term_feed_alias.info.yml`

```
name: 'Term feed alias'
description: 'Provides automatic aliases for taxonomy term feeds'
version: '8.x-1.0'
core_version_requirement: ^8.8 || ^9
type: module
dependencies:
  - 'path_alias:path_alias'

```

`term_feed_alias.services.yml`

```
services:
  term_feed_alias.path_processor:
    class: Drupal\term_feed_alias\PathProcessor\PathProcessorFeedAlias
    arguments: ['@path_alias.manager']
    tags:
      - { name: path_processor_inbound }
      - { name: path_processor_outbound }

```

The service tags can also receive a priority, see https://www.drupal.org/docs/8/api/services-and-dependency-injection/service-tags This might be needed to integrate the alias logic correctly with other services like translations for example. Also see first comment by @4k4.

`scr/PathProcessorFeedAlias.php`

```
<?php

namespace Drupal\term_feed_alias\PathProcessor;

use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\path_alias\AliasManager;
use Symfony\Component\HttpFoundation\Request;

/**
 * Provide a path processor to handle aliases for taxonomy term feeds.
 */
class PathProcessorFeedAlias implements InboundPathProcessorInterface, OutboundPathProcessorInterface {

  /**
   * The alias manager that caches alias lookups based on the request.
   *
   * @var \Drupal\path_alias\AliasManager
   */
  protected $aliasManager;

  /**
   * Constructs a new PathProcessorFeedAlias instance.
   *
   * @param \Drupal\path_alias\AliasManager $alias_manager
   *   The alias manager.
   */
  public function __construct(AliasManager $alias_manager) {
    $this->aliasManager = $alias_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function processInbound($path, Request $request) {
    $args = explode('/', trim($path, '/'));
    if (end($args) == 'feed') {
      array_pop($args);
      $system_path = $this->aliasManager->getPathByAlias('/' . implode('/', $args));
      return $system_path && strpos($system_path, '/taxonomy/term/') === 0 ? $system_path . '/feed' : $path;
    }
    return $path;
  }

  /**
   * {@inheritdoc}
   */
  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
    $args = explode('/', ltrim($path, '/'));
    if ($args[0] == 'taxonomy' && $args[1] == 'term' && end($args) == 'feed') {
      array_pop($args);
      $alias = $this->aliasManager->getAliasByPath('/' . implode('/', $args));
      return '/' . $alias . '/feed';
    }

    return $path;
  }
}

```

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


# Question
Title: How can I use contextual filters to display a block with field values from a single related entity?
I've found various recipes/threads with the scenario where have a content type A node and want to display in a sidebar block, all the related content type B nodes, with the relationship based on an entity reference field on content type B. Example and another

I've attempted to adapt these instructions to my situation, without success. My case is sort of flipped.

Content type: Resource
Content type: Source
Entity reference field: On the Resource content type, named source\_select

So I have a bunch of Resource nodes that have a single source selected for each.

**What I want to do:**

On each Resource node, I want to show info from fields of its one related Source in a sidebar block.

**What happens:**

For every combination of configuration options I've been able to think of or draw from other threads, etc., I get an empty block.

One example:

View display: block
View filter: published = yes
Contextual filter: Content: Source (field\_select\_source)
Provide default: enabled
Default type: Content ID from URL

I feel like I'm missing something obvious--and I've successfully built working contextual filter blocks before in D7, but I don't have any of those sites operating now and can't remember what the secret was and can't seem to crack it again now.

# Answer
> 0 votes
You want to create a view of Source nodes, then set a contextual filter for the Resource ID. This way, when you are on a Resource page, the Resource ID will be in the URL. The contextual filter will use this to limit the Source nodes (which your View is showing) to any sources referenced by that Resource, which in your case will be a single Source node. Then you can display the Source node either as a teaser (or create a custom view mode and use that), or you can display fields.

# Answer
> 0 votes
Pieces fell into place after a short nap.

**Here's how you do it...**

Concepts:

The contextual filter will be to display in the sidebar bock the same Resource node (matches the NID) loaded as a full node.

A relationship is needed to display field data for the related Source. In this situation, you don't contextual filter on the Source at all.

For me, it worked best to set them up in that order.

1. Settings to get the current node filtered into a sidebar Views block:

Provide default value: enabled
Type: "Content ID from URL"

Save the View.

At this point, I did a bit of testing by putting a nid in the "Preview with contextual filters" field below the View. Worked as expected.

2. Settings for Relationship to Source.

Relationship: Content referenced from field\_select\_source (important: This is not the same as the "Content using..." option)
Require this relationship: enabled (this may not be necessary, but made sense to me and works)

Apply and save the view.

3. Add fields from Source and choose the "field\_select\_source: Content" in the Relationship dropdown for each field.

Add the block to sidebar region for Resource nodes. That's it.

Result: Each Resource has a sidebar block showing Source information.

Edit: Jaypan's answer posted while I was writing this. It sounds more like how to display Resources while viewing the Source, which is the flipside of the relationship. But maybe that can work also.

---
Tags: views, nodes, 9
---


title: Change paragraph object for rendering

text:
# Question
Title: Change paragraph object for rendering
I have a paragraph type with a node ref field that, if you leave it empty, is supposed to show a random node using some defined logic.

I have the code to do the query and get the node, and ideally I'd want to put it on the paragraph object in some pre-render hook so that the paragraph can render normally using its usual config. Something like this (warning: pseudo-codish):

```
function mymodule_paragraph_view($build, $paragraph, $display, $view_mode) {
  if (!is_my_paragraph_type($paragraph)) return;

  if (!$paragraph->field_mynoderef->isEmpty()) return;

  $node = getRandomNode();
  $paragraph->set('field_mynoderef', $node);
}

```

This is setting the value correctly, but it seems it's too late in the render process for it to affect the rendered output (i.e. it doesn't actually show the node). I've also tried doing that on the `$build['#paragraph']` object, which contains the same paragraph, with similar results. **How can I make this work?**

BONUS: How to make it so it caches the output using a time-based configuration (e.g. expire after 60 seconds, so every minute it will show a different node and it won't run the query logic on every request).

# Answer
You need to build the loaded node into a renderable array, and add it to the `$build` array.

```
$node = getRandomNode();

$entity_type = $node->getEntityTypeId();
$view_mode = 'teaser';
$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$build['field_mynoderef'] = $view_builder->view($node, $view_mode);

```

Your question on caching is not related to this issue and should be separated into a separate question. Drupal Answers is a Q&A site with the format of one question to one answer, and adding the answer to that question would dilute this topic.
> 1 votes

---
Tags: 8, hooks, paragraphs
---


title: How to recreate the user_picture field?

text:
# Question
Title: How to recreate the user_picture field?
On Drupal 8 there is by default a user\_picture field for the user's photo. When I started my site several months ago, I deleted this field because I did not use it.

Today I need this field, so I created an image type field.

**MY PROBLEM :** I installed some modules that use the user's photo, but it can not be found because the user\_picture is the default

If I create a user\_picture field it automatically adds field\_ in front of the machine name.

Is it possible to restore the default field with the correct machine name ?

# Answer
> 8 votes
Instead of importing configuration as suggested previously, you could as an alternative, programmatically re-create the field. Here is some code that does that.

```
<?php

use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;

// Create the user profile field and instance.
FieldStorageConfig::create([
  'entity_type' => 'user',
  'field_name' => 'user_picture',
  'type' => 'image',
  'translatable' => '0',
])->save();
FieldConfig::create([
  'label' => 'User Picture',
  'description' => '',
  'field_name' => 'user_picture',
  'entity_type' => 'user',
  'bundle' => 'user',
  'required' => 0,
])->save();

```

Assuming the code above is placed in a file called `recreateUserPicture.php` that is stored in your docroot, you can run the following Drush command:

```
drush scr recreateUserPicture.php

```

Best of luck!

N.B.: An alternative answer (since the importing of configuration from the standard profile has a problem with having the field being available in Views UI).

# Answer
> 5 votes
This can be handled using the install configuration that the standard profile holds. Easiest way would be using drupal's console, that would mean following these steps (from inside your docroot):

1. `drupal config:import:single --file=core/profiles/standard/config/install/field.storage.user.user_picture.yml`
2. `drupal config:import:single --file=core/profiles/standard/config/install/field.field.user.user.user_picture.yml`
3. `drupal update:entities`

In case you can't work on the terminal using drupal console, you can import these two configuration from the administrative interface. This can be found under the `admin/config/development/configuration/single/import` URL (relative to your host's name). From there, you need to import twice, one time the file storage configuration (contents of core/profiles/standard/config/install/field.storage.user.user\_picture.yml) and the second would be the file configuration (contents of core/profiles/standard/config/install/field.field.user.user.user\_picture.yml).

Hope this helps, good luck!

# Answer
> 0 votes
I was facing the same issue, according to the tips above, wanted to go a save way, for me the following solution helped:

1. `drush cex` to export my actual configuration into Yaml files
2. compared them with the original files (by searching (..vendor/drupal/core/profiles/standard/config/install) --\> by using the grep command in linux e.g. `grep -Ril 'user_picture' /vendor/drupal/core/profiles/standard/config/install`
3. edited the following files of my exported configuration Yaml files:

```
+------------+--------------------------------------------+-----------+

| Collection | Config                                     | Operation |

+------------+--------------------------------------------+-----------+

|            | field.storage.user.user_picture            | Create    |

|            | field.field.user.user.user_picture         | Create    |

|            | core.entity_view_display.user.user.default | Update    |

|            | core.entity_view_display.user.user.compact | Update    |

|            | core.entity_form_display.user.user.default | Update    |

+------------+--------------------------------------------+-----------+

```
4. `drush cim` to reimport the modified and added files
5. `drush cr` to clear cache

Tip: maybe its already enough to copy the two files: field.storage.user.user\_picture and field.field.user.user.user\_picture and to your config export directory (after a fresh export) and do an import, because the difference within the core files was just a missing dependency.

---
Tags: 8, theming, entities, installation
---


title: Base fields vs Config fields?

text:
# Question
Title: Base fields vs Config fields?
I have an entity and I am not sure what I should use. On the one hand, configuration fields are easier to use via the UI, why should I consider base fields?

By using base fields everything is stored in the same table, would there be any kind of performance improvement if I have many entities?

I can't find anywhere where it is explained why to opt for one or the other. Thank you very much

# Answer
> 1 votes
Your question contains already the key points to consider. It's not only easier to configure fields in UI, it's also easier to deploy the changes. If you change a base field in a module you need to write an update hook.

On the other hand, if changes to the fields are unlikely and you expect a very high number of entities then use base fields like core for the alias entity.

---
Tags: 8, entities
---


# Question
Title: Let anonymous user download pdf off his own webform submission
I have configured entity\_print with webform for D8 and can download a submission as pdf from the submission view.
Now I tried to let anonymous users fill out a form and added a link to the pdf on the confirmation page. I checked the show own submissions for guests on the permission page of that webform.
But when I try to access the pdf with the submited data I get a permission denied message.
http://mywebsite/print/pdf/webform\_submission/15?view\_mode=html seems not to do the trick.

The use case just is: Display a confirmation page with the submitted values to the user and let the user download it as pdf. Any hints on that?

Meanwhile I found this Thread: https://www.drupal.org/project/entity\_print/issues/2896424 Which says adding
`{{ content[0]['#webform_submission'].data.FIELD_NAME }}`
too the template should work. While Fieldname should be the name of the entityPdf/Attachment field. But adding it to my webform-confirmation.htmltwig template does not return anything.

This too points in the same direction: https://www.drupal.org/project/webform/issues/3198932 This seems to be a solution. After Doing the following:

1. Add permissions for anonymous users - "Webform submission: Use all print engines"
2. Enable "Allow users to view a submission using a secure token"
3. Add Link to submission with token \[webform\_submission:token-view-url\]
4. Submit Webform as anonymous and click on link -\> Download PDF

Maybe there is still a even more neat solution...

Okay meanwhile - the so called secure token isn't expiring so it es more like a everyone how knows the link not so secure token :-(

# Answer
Okay after playing around with several options, best way in my eyes is:

* install entity print and wktmltopdf
* give guest users access to their own submissions (/admin/people/permissions)
* give guest users access to use any print engine (/admin/people/permissions)
* add a confirmation message like "Thank you for contacting us, you can download your submited data here (at /admin/webform/manage/kontakt/settings/confirmation)
* The href to the PDF looks like this: /print/pdf/webform\_submission/\[webform\_submission:sid\]

The access to the data will no longer be posibble after session timeout. So there shouldnt be a concern with data security.

The Secure token method mentioned above would fail in cases where data security plays a role, as the token never times out and could easily be obtained from browser istory.
> 3 votes

---
Tags: webforms, 8
---


# Question
Title: How can I build a render array that results in a string rather than a Drupal\Core\Render\Markup object?
I'd like to use Twig Tweak's `drupal_view()` to render a view in my paragraph template. I have a couple entity reference fields on the paragraph and need the IDs of the referenced entities passed as contextual filter arguments.

I built a *Contextual Filter String* field formatter to format the contextual filter string with the hope that it could be passed directly as the argument's value. The formatter will return `all` if the reference field is empty, otherwise it will return the referenced entity IDs as a string with AND/OR separators, e.g. `1,2,3` for AND or `1+2+3` for OR.

Inside my template, I'm attempting to render the view with the following twig:

```
{% set arg1 = content.field_arg1|render %}
{% set arg2 = content.field_arg2|render %}

{{ drupal_view('my_view', 'my_display', arg1, arg2) }}

```

But this does not work!

Rather than strings, my arg variables are actually Drupal\Core\Render\Markup objects so the arguments are not passed correctly to the view.

After researching, I've found that I can workaround this issue by filtering my arg variables with a php filter that returns a string. For example, using the trim filter works:

```
{% set arg1 = content.field_arg1|render|trim %}
{% set arg2 = content.field_arg2|render|trim %}

{{ drupal_view('my_view', 'my_display', arg1, arg2) }}

```

If possible, I would like to build a render array that doesn't require any fancy footwork in the template to pass the values to the `drupal_view()` function. I.e. a render array where I can pass `content.field_arg1` or `content.field_arg|render` directly as the arguments. Is this possible?

Render arrays I've tried that did not work:

```
$inline_template = [
  '#type' => 'inline_template',
  '#template' => '{{ contextual_filter_string }}', // also tried with |trim filter here
  '#context' => [
    'contextual_filter_string' => '1+2+3',
  ],
];

$markup = [
  '#markup' => '1+2+3',
];

$plain_text = [
  '#plain_text' => '1+2+3',
];

```

Note: not shown in the above render arrays is cache metadata (tags) for the entities referenced in the field.

**Yes, there are alternate ways to get these field values and pass them to `drupal_view()`, however that's not what this question is about.** I would like to use a Field Formatter to return a render array (I think I have to return a render array) that results in a string ready to be passed directly to `drupal_view()`. This allows me to configure the format of the argument in the UI without touching code. I suspect this is impossible.

Some alternative approaches that I've considered:

* I could preprocess my paragraph and add these filter strings to the `$variables` array.
* I could build my own twig function to generate these contextual filter strings.
* I could get the values directly from the entity in my template, e.g. `paragraph.field_arg1.target_id` as Les Lim answered, but this doesn't work cleanly for multi-value fields.

**Edit:** It seems that this is impossible so accepting Les Lim's answer as the best alternative.

# Answer
> 7 votes
**Original response, assuming you only need a single value from each field:**

Instead of using the rendered field output that you get with items in the `{{ content }}` array, you should probably use raw values directly from the entity. Raw values are much more likely to be what your Views arguments are looking for in the first place.

In Drupal 8/9, if the raw entity is available to the Twig template (and it is for Paragraph templates), you can use Entity API notation to get exact raw values from your entity:

```
{% set arg1 = paragraph.field_arg1.target_id %}
{% set arg2 = paragraph.field_arg2.target_id %}

```

**Addendum, for needing multiple raw field values joined together**

After re-reading the question, I realize you need all the raw values from a field joined together with a string. The contrib module Twig Field Value gives you handy generic tools for exactly this purpose. In this case, you would use its `field_raw` filter:

```
{% set arg1 = content.field_arg1|field_raw('target_id')|safe_join('+') %}
{% set arg2 = content.field_arg2|field_raw('target_id')|safe_join(',') %}

```

**Edit: Join multiple raw field values without Twig Field Value (thanks 4k4 for the tip)**

You don't actually need Twig Field Value to get the `target_id` values from a multiple-value field - you can extract multiple values from a raw entity field using Twig's built-in `column` filter.

```
{% set arg1 = paragraph.field_arg1|column('target_id')|safe_join('+') %}
{% set arg2 = paragraph.field_arg2|column('target_id')|safe_join(',') %}

```

---
Tags: theming
---


title: View Bulk Operation with custom action

text:
# Question
Title: View Bulk Operation with custom action
I have a custom action to update some table values base on node content selection. My custom actions are listed correctly on bulk update select box. But I can perform operation some random node content only. Any thoughts!! why It's allow actions to perform on some contents only.

View Bulk Operation: https://www.drupal.org/project/views\_bulk\_operations

Tried Version: 8.x-3.13 , 4.0.0-rc1

```
<?php

namespace Drupal\custom_user\Plugin\Action;

use Drupal\node\Entity\Node;
use Drupal\views_bulk_operations\Action\ViewsBulkOperationsActionBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Entity\ContentEntityInterface;

/**
 * Content moderation publish node.
 *
 * @Action(
 *   id = "notification_read",
 *   label = @Translation("Update Notification As Read"),
 *   type = "node",
 *   confirm = TRUE
 * )
 */

class NotificationRead extends ViewsBulkOperationsActionBase {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function execute(ContentEntityInterface $entity = NULL) {
    $nid = $entity->id();
    $uid = \Drupal::currentUser()->id();
    if ($nid) {
      $connection = \Drupal::database();
      $connection->delete('notifications')
      ->condition('entity_id', $nid)
      ->condition('entity_uid', $uid)
      ->execute();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
   \Drupal::logger('test')->warning(print_r("test", TRUE));
   if ($object instanceof Node) {
    return True;
  }

  return FALSE;
}
}[![enter image description here][1]][1]

```

# Answer
This line means that you can only use your action on Nodes, and not any other entity type:

```
*  type = "node",

```

Remove this line, clear your registry, and you will be able to apply your action to other entity types as well.
> 0 votes

---
Tags: views, nodes, 9
---


title: What is the route for a specific node?

text:
# Question
Title: What is the route for a specific node?
I want to override the `user.login` route that points to the default login page.

I.e. I want that a user who presses the default "Log in" link for the site to be directed to a *node* that provides some help (where the user can click on a link and arrive at the standard log-in form).

Say that the path I want to redirect to is `/node/42`. How can I find out what route to return for a specific node?

I believe that the right place to do this in Drupal 9 is to override the `getRouteName()` function the in the `LoginLogoutMenuLink` class. So I'm trying to create something like this.

```
public function getRouteName() {
  if ($this->currentUser->isAuthenticated()) {
    return 'user.logout';
  }
  else {
    return '- What to put here? - ';
  }
}

```

I've searched a lot, and some people say that the route for nodes are `entity.node.canonical`. But that does not solve it for me. I think that the route for a *specific* node also need to have the `nid` in there somewhere.

# Answer
> 6 votes
Unless something is overriding the routing, the route for all nodes is `entity.node.canonical`.

The route needs a route\_parameter, `node`, to pass the nid.

For example, you could create a link to a node's page with Link::createFromRoute() like:

```
$my_link = Link::createFromRoute('My link text', 'entity.node.canonical', [
  'node' => 123,
]);

```

As @4k4 pointed out, you'll need to create the LoginLogoutMenuLink class's `getRouteName()` and `getRouteParameters()` methods.

```
public function getRouteName() {
  if ($this->currentUser->isAuthenticated()) {
    return 'user.logout';
  }
  else {
    return 'entity.node.canonical';
  }
}

public function getRouteParameters() {
  // Not sure if this is the best conditional to use here.
  if ($this->getRouteName() == 'entity.node.canonical') {
    return [
      'node' => 123,
    ];
  }

  return parent::getRouteParameters();
}

```

---
Tags: routes, 9
---


title: Field Type: Text vs. Long text

text:
# Question
Title: Field Type: Text vs. Long text
What are the differences between 'Text' and 'Long text' in Drupal 7?

If it is simply database character length, is it better to be cautious and default to using Long text in situations where the domain of possible entered values is not precisely known?

# Answer
> 21 votes
The differences are laid out in text.module.

1. `text` fields are stored as varchar with a maxlength of 255 characters, and their default widget is a simple text input.
2. `long text` fields are stored as longtext, with a maximum length of 4 GiB (maximum characters depending on the encoding), and their default widget is a textarea
3. `text with summary` fields are like `long text` fields, except that text processing is enabled by default. That is, summary text can be included along with the main text, and the content will be processed through input filters. The default widget is a "textarea with summary"

Generally, long text and text with summary fields are used for, well, long text— anything longer than a few words or a few dozen characters: body text, lengthy embedding code, data tables, and so on. Ordinary text is better suited to short snippets of text: a personal name, a company tagline, a favorite color.

I think it would be rare that your data would be suitable to either type. If you're storing a biography for a user profile, for example, you would have a clear idea as to whether it is expected to be a narrative of several paragraphs or simply a short personal motto.

# Answer
> 1 votes
There are three more types of text that a text field can be set for:

4. Text plain (stored as varchar)
5. Text plain long (stored as longtext)

Use these for the most secure outward facing fields. Plain text provides a secure, generic text format that can be used by all roles, including an anonymous user. It has no html formatting tags whatsoever (no bold, no italic, ...)

6. List (Text)

List text is for key|label lists, as described in Drupal 7 documentation.

---
Tags: 7, entities
---