# Question
Title: "Can't migrate source field body of type text_with_summary configured with plain text processing."
I am trying to migrate a Drupal 7 site to Drupal 8, but I get the following error message.

> Can't migrate source field body of type text\_with\_summary configured with plain text processing. https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text

I read the linked documentation page and changed the body field in every content type to filtered, but the error persists.

How can I resolve this issue?

# Answer
> 1 votes
The reason this is happening is because of 1 of 2 reasons:

1. Your text and long text fields have both plain and filtered text processing.
2. Your text with summary fields have plain text processing.

The easy way to make this go away is to set them all to filtered text during the migration. You can do this in the hook\_migrate\_prepare\_row() function via:

```
/**
* Implements hook_migrate_prepare_row().
*/
function YOUR_MODULE_migrate_prepare_row(Row $row, MigrateSourceInterface $source, MigrationInterface $migration) {
  // Do various tasks based on the migration id.
  switch ($migration->id()) {
    case 'upgrade_d7_field':
    case 'upgrade_d7_field_instance':
      $type = $row->getSourceProperty('type');
      switch ($type) {
        case 'text':
        case 'text_long':
        case 'text_with_summary':
        $instances = $row->getSourceProperty('instances');
        foreach ($instances as $key => $instance) {
          if (isset($instance['data'])) {
            $data = unserialize($instance['data']);
            if (isset($data['settings']['text_processing'])) {
              // Set all text processing to filtered text.
              $data['settings']['text_processing'] = 1;
              $instance['data'] = serialize($data);
              $instances[$key] = $instance;
              $row->setSourceProperty('instances', $instances);
            }
          }
        }
        break;
      }
      break;
  }
}

```

Also look into the class Drupal\text\Plugin\migrate\field\d7\TextField for more details as to why the migration is throwing errors.

---
Tags: 8, migrations
---


# Question
Title: How to set the href with the pathname of the current page in it?
Inside a view I have a block for which there is a field called Global Perspective.

Inside the block override , I have rewrite rules which overrides teh out of the field with custom text.

```
<div class="featured-media-tag">
{% if field_is_global_perspective__value %}
    <a href="{{ path('view.global_memos.page_1', {'global_perspective' : 1}) }}" class="media-link">Global Perspectives</a>
{% else %}
    <a href="{{ path('view.global_memos.page_1') }}" class="media-link">Global Memos</a>
{% endif %}
</div>

```

This gives me the relative path, i.e `/global-memos?global_perspective=1` for the a tag. When I click on my local the link it directs to `mylocal.sj/global-memos?global_perspective=1` but the issue is on production i have my site homepage as `example.com/mysite` .

So when I click on the a tag on production, it is going here `example.com/global-memos?global_perspective=1` , but expected is for it to go here `example.com/mysite/global-memos?global_perspective=1`.

I have tried to write a preprocess but failed at it. function subtheme\_preprocess\_views\_view\_fields(&$variables) {

```
  // Retrieve an array which contains the path pieces.
  $current_path = \Drupal::service('path.current')->getPath();

  // The hostname of the site
  $host = \Drupal::request()->getHost();

  if($host == "example.com") {
    $variables['pathname_id'] = "/councilofcouncils";
  }

}

```

and then tried to add the pathname\_id to the rewrite rules like this Global Perspectives

# Answer
You can try `{{ url('<current>') }}`. I could not find any documentation for this but it seems to work. For example, based on your code above, I can add the current URL like this in a Twig template:

```
<a href="{{ url('<current>') }}" class="media-link">
 {{ 'Global Memos'|t }}
</a>

```

If I am on a page with the url, `example.com/councilofcouncils`, the twig code above will render as:

```
<a href="http://example.com/councilofcouncils" class="media-link">
Global Memos
</a>

```
> 0 votes

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


# Question
Title: upgrade_status - unexpected error about PHP version
I'm doing preparatory work for upgrading a site from D8 to D9...

The Drupal dev site (macOS 10.14.6 served with Laravel Vagrant) is running PHP 7.3.28, both on command line and php-fpm, and I'm seeing the correct version with php --version and at */admin/reports/status*

And yet, whenever I scan my custom modules via the upgrade\_status UI, I consistently get:

```
PHPStan command failed:

/Users/wt/Sites/sitename/vendor/bin/phpstan analyse --error-format=json -c /tmp/upgrade_status/deprecation_testing.neon /Users/wt/Sites/sitename/web/modules/custom/snape 2> /tmp/upgrade_status/phpstan_error_output

Command output:

Empty.

Command error:

Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 7.3.0". You are running 7.1.33. in /Users/wt/Sites/sitename/vendor/composer/platform_check.php on line 24

```

If I run phpstan manually using the first command, it works (though annoyingly the JSON output is truncated).

I've been going through this question as well.

* adding `"config": { "platform-check": false }` doesn't work
* adding `"config": { "platform": { "php": "7.4" }` doesn't work

I've checked the user PHP is running as; it's me, the same as via CLI. I've also done `which php` version on a bunch of other possible users and they all go to */usr/local/bin/php*, which has the correct PHP version.

I've installed drupal/core-dev and phpunit to try and avoid any issues with the upgrade\_status module. I have the latest version of it.

It runs correctly on production (Debian 10).

# Answer
> 1 votes
Run `composer -vvv about`. Find the line that looks like:

"Running X.X.X (XXXX) with PHP X.X.XX on XXXX".

This will tell you what php composer is using. If this is different, you sometimes need to force the php version you want to use either via bashrc or some other method. For example, I have a site hosted on a cpanel server with multiphp, and have this in a my .bashrc file:

```
alias php="/usr/local/bin/ea-php74"
alias composer="php /opt/cpanel/composer/bin/composer"

```

Note: On that same cpanel server, we were able to solve this globally by setting the system php to php 7.4. Along with that, we made sure to add this to each composer project, so even if the system PHP is higher, we can tell composer what deps to install:

```
"config": {
  "platform": {
    "php": "7.4"
  }
},

```

---
Tags: composer, 9
---


# Question
Title: Add a class the the form element (tag) of the search block form
How do I add a class to the form element of the search block form?

I mean, add a class to this element:

```
<form action="/search/node" method="get" id="search-block-form" accept-charset="UTF-8" data-drupal-form-fields="edit-keys"></form>

```

I've tried:

```
function mytheme_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'search_block_form') {
    $form['#attributes'] = array('class' => array('abc'));
  }
}

```

and

```
function mytheme_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'search_block_form') {
    $form['#attributes']['class'][] = 'abc';
  }
}

```

I've tried:

```
function mytheme_preprocess_form(&$variables) {
  if ($variables['element']['#form_id'] == 'search_block_form') {
    $variables['element']['#attributes'] = array('class' => array('xyz'));
  }
}

```

I've looked into altering `core/modules/system/templates/form.html.twig`, which does not look like the way to go.

I'm using the Bootstrap theme as my base.

# Answer
> 0 votes
you can use the prefix and suffix tag like

```
$variables['element']= ['#prefix' => '<div class ="abc">',
                        '#suffix' => '</div>']

```

# Answer
> 0 votes
Use a preprocess hook to add class to a specific form:

```
function THEME_preprocess_form(&$variables) {
  if ($variables['element']['#id'] === 'views-exposed-form-search-page-1') {
    $variables['attributes']['class'][] = 'your-custom-class';
  }
}

```

---
Tags: 8, forms
---


# Question
Title: Making an HTTP subrequest causes CurrentRouteMatch to have the wrong route
For complicated and unpleasant reasons\[\*\], I want to embed entity data from the JSONAPI module inside JSON returned from a REST module resource.

I am trying to do this by making an HTTP subrequest to the JSONAPI module route within the REST module resource class.

Like this:

```
    $kernel = \Drupal::service('http_kernel');

    $current_request = \Drupal::request();

    $request = Request::create('/jsonapi/paragraph/' . $paragraph->bundle() . '/' . $paragraph->uuid->value);
    $request->setSession($current_request->getSession());

    $response = $kernel->handle($request, HttpKernelInterface::SUB_REQUEST);
    $json = $response->getContent();
    $data = json_decode($json, TRUE);

```

I get the data I want and it's great!

However, the main request to the REST resource endpoint crashes with this:

> Symfony\Component\Serializer\Exception\NotEncodableValueException: Serialization for the format "api\_json" is not supported. in Symfony\Component\Serializer\Serializer-\>serialize() (line 112 of /var/www/vendor/symfony/serializer/Serializer.php).

This is because in Drupal\rest\EventSubscriber\ResourceResponseSubscriber-\>getResponseFormat(), `$route = $route_match->getRouteObject();` is the JSONAPI module route from the subrequest, and not the route from the main request.

What am I doing wrong with my subrequest?

\[\*\] Enormous amount of custom code powering a REST resource for a decoupled front end. I want to change it to using JSONAPI but it's a massive change with huge repercussions on the frontend. To change over incrementally to JSONAPI, I want to switch some paragraph types to the JSONAPI format. Could call the JSONAPI module's PHP code directly, but that's not a public API and so future versions of Drupal could break it. Making a subrequest is using the API and so more maintainable.

# Answer
After running the subrequest the request stack is quite a mess, it still contains the subrequest while the route match stack was cleaned up. If you then get the current route match this will return a newly created route match based on the json api request.

A quick fix would be to clean up the request stack by hand, including a check so that the code still works when the core issue is fixed:

```
$current_request = \Drupal::request();

$request = Request::create('/jsonapi/node/page/UUID', 'GET', [], $current_request->cookies->all(), [], $current_request->server->all());
$request->setSession($current_request->getSession());

$response = $kernel->handle($request, HttpKernelInterface::SUB_REQUEST);
if (\Drupal::request()->getPathInfo() !== $current_request->getPathInfo()) {
  \Drupal::requestStack()->pop();
}

```

BTW your subrequest probably needs more metadata from the main request. I've added cookies and server headers to the code example.
> 2 votes

# Answer
I've since discovered that jsonapi\_extras module provides the exact same functionality -- getting the JSONAPI representation of an entity by making a subrequest. That seems to avoid the problem by using the `http_kernel.basic` service to mak the subrequest. It looks like that doesn't keep a request stack, so bypasses the problem of multiple requests being kept track of?
> 1 votes

---
Tags: http-request
---


# Question
Title: Send email after updating a field on a webform
I have a webform with a set of fields. When the form is submitted, a website admin needs to update a field on the form based on some criteria. I need to send an email to the sender only if the value of that field equals something.

I have tried implementing this with Rules:

1. Event: After a webform submission has been updated.
2. Conditions: Webform has name
3. Action: Send HTML email

I need something else on step 2, to compare the field value submitted, but I don't see any condition for that.

Drupa 7, Webform 4.

# Answer
I've been working with something that's similar enough that it might help. I'm using the FillPDF module to fill out an editable PDF and send it by email, all through rules. Different results, but I believe the roadblock you've run into is the same one I had to work with.

Let's say you want to send an email if the admin selected 'Send Email' from a submission select labelled 'send\_email' that included:

```
yes|Send Email
no|Don't Send Email

```

Webform submission data aren't available within the Conditions section of a rule by default. To get around this, you need to:

1. Install the rules\_conditional module
2. Add a variable for your submission value to compare.
3. Create an 'if' condition within the Actions area to compare.

---

**Install rules\_conditional module**.

This will allow you to write conditions in the Actions area.

**Add your submission value as a variable**

Add Action

* action to add: 'Add a variable'
* type 'Text'
* value: from replacement patterns, pick the appropriate submission token, which will probably be `[data:*{component}*-value]` or `[data:*{component}*-value-raw]` for you, where *{component}* is the key of the submission data. For example `[data:send_email-value-raw]`. (Note that if you have grouped your webform fields within fieldsets, you'll need to add the fieldset key inline here. e.g. `[data:admin_data:send_email-value-raw]` if your fieldset is 'admin\_data'. That little nugget took me hours to figure out.)
* variable name: name it so you'll recognize it elsewhere within the rule (e.g. 'submission\_send\_email').

Note that you might need to convert the data type if your value isn't the correct type. You can add a separate action after the variable to convert it.

**Add a condition below the action**

1. Add conditional
2. Add if:

Data comparison

Data to compare: Your new variable (submission\_send\_email) should be within the list of data selectors, or you can begin typing it in the data selector field. (It'll have dashes instead of underscores: submission-send-email.)

Value: enter the value you want to match.

**Place your action within the if**

A tested working example:

---

Notes: in my experience, the 'raw' forms of the submission values are the keys for selects (e.g. 'yes' vs. 'Send Email').
> 0 votes

---
Tags: 7, webforms
---


# Question
Title: Send HTML mail with plain text mime/alternative (for anti-spam)
We use Webform Drupal 8 module to handle newsletter subscription on a website. An html formatted email is sent to confirm subscription. Unfortunately, this email is sent with only content-type:text/html, and you know how picky Spamassassin is about this. It's a real deliverability issue. We'd like to be able to send that email with a content-type:multipart/alternative, with 2 parts : one with text/html content-type and one with text/plain. How can we do this ? We installed "mail system" and "mime mail" modules, but we can't figure out how to use them, or even if it's the right solution. Has anyone ever managed to do this?

# Answer
You can't do this with Drupal core, you need a helper module like Mime Mail.

The Webform module only does the minimum - it sets the content-type header but does not deal with multipart messages, does not deal with embedding images, embedding CSS/JS, re-writing URLs to be absolute, or adding attachments, etc.

The Mime Mail module was specifically written to allow any Drupal module to send multipart/alternative email with the above features.

You say you can't figure out how to use it? There's some really good documentation at https://www.drupal.org/docs/contributed-modules/mime-mail that should help.
> 1 votes

---
Tags: webforms, emails, mimemail
---


# Question
Title: Filter a view based on current user's roles
I'm using a view to populate an Entity reference field on a profile. (So it's a view of "Entity Reference" display type.)

I want to filter this view to show (and allow users to select) only:

1. Published content (OK)
2. Content of a certain type (OK)
3. Only a subset of nodes available to the current user (OK)
4. If the current user is admin or some other role, bypass the previous filter (3) and show all nodes (but still respect filters 1 and 2) (not OK)

Filters 1 and 2 are always mandatory; then either filter 3 or 4 must also be mandatory. I've tried to rearrange filters into filter groups to make this work, but I cannot find a way to build filter 4.

For filter 4, I need to filter based on the role of the current user (NOT author), and I cannot find how to do that.

I'm looking for a Relationship to bring in the current user data (something like "User: current"), and then filter on that data, but where can I find that?

# Answer
> 0 votes
I encountered exactly the same problem, and I ended up writing a hook for this.

I first created the basic view through the UI, and added filters 1. and 2. To filter out the elements to which the current user was not the author, I added this hook in a custom module :

```
function yourmodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  try {
    $userCurrent = \Drupal::currentUser();
    $uid = $userCurrent->id();
    // For non-admin users…
    if($view->id() === 'yourviewid' && !$userCurrent->hasPermission('edit any content')) {
      // …add a WHERE condition to only get the user's own nodes. This can be replaced with your own logic.
      $query->addWhere(0, 'uid', $uid);
    }
  }
  catch(Error $e) {
    drupal_set_message('The server encountered a problem. Please contact the site\'s administrator.', 'error');
    \Drupal::logger('yourmodule')->error("Error adding filter to view in yourmodule.module : %e",
      ['%e' => $e]
    );
    return;
  }
}

```

Hope this helps.

---
Tags: views, 8
---


# Question
Title: How can I get the width or height of an image field image into a twig template?
I'm using PhpStorm/xdebug/MAMP to look at the variable I want to access:

I have tried using the following to get at the data:

```
{% set image_width = content.field_image.0['#item'].values.width %}

```

and

```
{% set image_width = content.field_image.0['#item'].values.width.value %}

```

Neither of these lines produce any data.

Any help is greatly appreciated!

# Answer
You can't access the array `values` because it is protected. But you don't need to, because you can get the properties from a field item directly:

```
{% set image_width = content.field_image.0['#item'].width %}

```

BTW the `content` variable is a render array with no fixed structure. The presence and position of `#item` changes dependent on the field formatter and other core, contrib or custom code.

So it's better to use the entity object, for example the paragraph entity in a paragraph template:

```
{% set image_width = paragraph.field_image.0.width %}

```
> 7 votes

# Answer
If using Media (Drupal 8 or 9), here's an example on how to access the width of the image in a `node` template:

```
{% set image_width = node.field_image.entity.field_media_image.0.width %}

```

Please note that `field_image` is an Entity Reference to Media.
> 0 votes

---
Tags: theming, 8
---


# Question
Title: How to deal with config changes in prod and by multiple developers?
I have two scenarios in configuration management that I am unsure how to deal with:

1. Geeky user makes config changes in production. What is the best practice to import these changes in dev without destroying the work that is being worked on in dev? `git pull` and `drush cim` would override everything you are working on in dev. I know there is `drush cim --partial`, but from what I understand this is not the recommended way of doing it (Source). I could also use configuration read-only module in prod to avoid config changes at all, but there are several examples where the user should actually be allowed to change config.
2. Two devs work in their local dev environments: How can I ensure one is not overriding the work from the other when pushed to stage or prod, particularly when there are also config changes in prod happening (see 1)? Probably some way of git branching may help, but I could use some more help on how to exactly use it.

# Answer
Good use of git branching can definitely help with this. The key thing is that each individual branch has a stable configuration basis: nothing external to the branch should change the configuration state within the branch, so that later when it's time to export configuration in the branch and merge it into production, only the changes relevant to the branch are recorded.

One way to do this is to have a main branch called `production`, and the HEAD of that branch always tracks with the current production state of your codebase. You all agree not to commit or merge things to `production` unless you're preparing to release those things live.

When Arjun wants to work on a new feature, they make a new branch off of `production`, and they call it `arjun-1`.

The next day, Beth needs to fix a bug, so she makes her own new branch off `production` called `beth-1`.

Meanwhile, content manager Ceci is in the site UI building out webforms, which means she is making live configuration changes that diverge from the config state of `production`. In a way, she too is branching off of `production`! In fact, let's go ahead and create a `ceci-1` branch off of `production` now to represent this, even though we probably won't commit anything to it yet.

A few days later, Arjun and Beth's respective branches have been reviewed and accepted, and management wants to deploy a new release with their work to the live site.

The first thing to do is check out the `ceci-1` branch, export the live configuration and commit the updated config files to `ceci-1`.

Now you can proceed to merge to `production`: the new feature `arjun-1`, the bugfix `beth-1`, and the live configuration updates `ceci-1`. There may be merge conflicts to review, but you should not have to worry about accidentally overwriting someone else's config. This is because each individual branch had a consistent basis from which to export their own individual config changes.

Let's say you didn't make a `ceci-1` branch. Instead, you merged `arjun-1` and `beth-1` into `production`, then exported the live config and committed the live updates into `production`. You have screwed up! You changed the basis for Ceci's live site configuration changes. They had been based on the state of production without Arjun and Beth's branches. Exporting now will overwrite any configuration changes they had made.
> 4 votes

# Answer
Changes should never be made in production. Production configuration changes should be made locally by developers. Merge conflicts should be sorted on their local machine. So, it would go like this:

1. Developer checks out code
2. Developer makes changes exports config
3. Developer tries to push, gets rejected to do new commits
4. Developer pulls, sees changes in configuration
5. Developer imports new configuration to ensure it imports properly, and that the changes in his commit are not disrupted
6. Developer exports configuration after making any fixes, commits, and pushes to the server

Any changes to configuration made directly on remote servers should be expected to be overwritten with every push. This solves your above issues, except maybe:

> there are several examples where the user should actually be allowed to change config.

Such as?
> 0 votes

---
Tags: 8, configuration, deployment
---


# Question
Title: Is the content of YAML files stored in the database somewhere?
I just updated from Drupal 8.9.16 to Drupal 9.2.0. It worked fine in my test environment, but when I try on the production environment, I get the following error.

> requires the 'core' key not be set in core/profiles/testing\_install\_profile\_dependencies\_bc/testing\_install\_profile\_dependencies\_bc.info.yml

I have looked in the core directory and do not have this path, so I am not sure why it is complaining about it. Googling, I saw this was part of Drupal 8.8.

Is the content of YAML files stored in the database somewhere?

I am stuck with a site that displays a WSOD. I am hoping someone else has come across this issue and can help me fix it.

These are the first lines of the stack trace.

> Drupal\Core\Extension\InfoParser-\>parse('core/profiles/testing\_install\_profile\_dependencies\_bc/testing\_install\_profile\_dependencies\_bc.info.yml') (Line: 554)
> Drupal\Core\Extension\ExtensionList-\>createExtensionInfo(Object) (Line: 316)
> Drupal\Core\Extension\ExtensionList-\>doList() (Line: 282)
> Drupal\Core\Extension\ExtensionList-\>getList() (Line: 125)
> Drupal\Core\Extension\ModuleExtensionList-\>getActiveProfile() (Line: 90)
> Drupal\Core\Extension\ModuleExtensionList-\>getExtensionDiscovery() (Line: 298)
> Drupal\Core\Extension\ExtensionList-\>doScanExtensions() (Line: 137)
> Drupal\Core\Extension\ModuleExtensionList-\>doScanExtensions() (Line: 312)
> Drupal\Core\Extension\ExtensionList-\>doList() (Line: 154)
> Drupal\Core\Extension\ModuleExtensionList-\>doList() (Line: 282)
> Drupal\Core\Extension\ExtensionList-\>getList() (Line: 260)
> Drupal\Core\Extension\ExtensionList-\>get('ctools') (Line: 243)
> Drupal\Core\Extension\ExtensionList-\>getName('ctools') (Line: 712)
> Drupal\Core\Extension\ModuleHandler-\>getName('ctools') (Line: 52)
> Drupal\Core\Block\BlockManager-\>getProviderName('ctools') (Line: 34)
> Drupal\Core\Block\BlockManager-\>processDefinitionCategory(Array) (Line: 67)
> Drupal\Core\Block\BlockManager-\>processDefinition(Array, 'entity\_view:block') (Line: 286)
> Drupal\Core\Plugin\DefaultPluginManager-\>findDefinitions() (Line: 175)
> Drupal\Core\Plugin\DefaultPluginManager-\>getDefinitions() (Line: 22)

# Answer
> 1 votes
It should be in the `cache_default` bin, keyed as `core.extension.list.module`. However, are you sure that you're using the database cache in the production environment? If you're using memcached or redis instead, the database cache tables would just be sitting there vestigially, pretending to do work.

---
Tags: 9, upgrading
---


# Question
Title: How to get all search results of search api index?
I want to get all the search results from the search API index and then perform a custom sort on it and then display them accordingly.

I used the `hook_search_api_results_alter` and also the search results event. My view has a pager to display 10 results at a time.

But the problem is, I am only getting 10 results instead of all because of that pager.

Is there any to get all the results and then perform the custom sort on it and then return it to search view to display accordingly? So that all other filters, pagers, and sorting applied after my custom sort?

My custom sorting is working fine on per page basis but that is not what I want.

Is it possible to remove the limit from the query to get all results, perform sort and apply the limit again?

# Answer
function hook\_views\_post\_execute would be better here. This is for where the query has been executed, but the pre\_render() phase has not yet happened for handlers so you should be able to sort your results by whatever order you need.
> 0 votes

---
Tags: search, 9
---


# Question
Title: How can I set a custom document title in theme-settings.php?
I need to set the content of the `<title>` tag without using a module, for example changing the content of the *theme-settings.php* file.

I am trying to add the following hook implementation.

```
function mythemename_preprocess_page_title(&$variables) {
  $variables['title'] = 'New title';
}

```

The new title is not shown, though.

If it makes any difference, I am using Drupal 8.7.3.

# Answer
Easiest solution is to use the Metatag module, indeed.

For a full code solution, I'd recommend you to have a look at core/themes/classy/templates/layout/html.html.twig file (which is the default html template used by Drupal if your theme does not override it) for clues concerning template variables. The variable you want to alter is head\_title which, as stated in header of html.html.twig is:

```
 * - head_title: List of text elements that make up the head_title variable.
 *   May contain one or more of the following:
 *   - title: The title of the page.
 *   - name: The name of the site.
 *   - slogan: The slogan of the site.

```

In your theme myTheme.theme file, use the hook\_preprocess\_html() hook to alter your $variables\["head\_title"\] variable.

PS: Do not forget to flush caches when working with templates to be sure your modifications are taken into account.
> 1 votes

---
Tags: 8, theming
---


title: Validation on custom entity edit form

text:
# Question
Title: Validation on custom entity edit form
I have a custom entity where, instead of using the usual way of specifying edit form options with `setDisplayOptions('form'` and relying on `ContentEntityForm` to create my edit form for me, I have to make my own form in `buildForm()` (I have Ajax interactions between the fields that the stock from can't provide). It works all right, just that I can't trigger validation as with the stock form. The constraints are there and if I override:

```
public function validateForm(array &$form, FormStateInterface $form_state) {
  $entity = parent::validateForm($form, $form_state);
  $violations = $entity->validate();
  foreach ($violations as $v) {
    dpm($v->getMessage());
  }
  return $entity;
}

```

the validation errors are in fact found and listed, just the form won't display the usual red warnings, keeping the user from going on. Can I reconcile the custom form building with the automatic validation?

# Answer
> 0 votes
The User entity is one of the Drupal core entities that programmatically adds form elements in their entity form class and still uses validation constraints.
`AccountForm::form()` adds the form elements and `User::baseFieldDefinitions()` adds the validation constraints to the entity fields.
(`AccountForm` is the class extended by the `ProfileForm` and the `RegistrationForm` classes, which are two of the three entity form classes used for the User entity.)

```
  // Account information.
  $form['account'] = [
    '#type' => 'container',
    '#weight' => -10,
  ];

  // The mail field is NOT required if account originally had no mail set
  // and the user performing the edit has 'administer users' permission.
  // This allows users without email address to be edited and deleted.
  // Also see \Drupal\user\Plugin\Validation\Constraint\UserMailRequired.
  $form['account']['mail'] = [
    '#type' => 'email',
    '#title' => $this->t('Email address'),
    '#description' => $this->t('A valid email address. All emails from the system will be sent to this address. The email address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by email.'),
    '#required' => !(!$account->getEmail() && $user->hasPermission('administer users')),
    '#default_value' => !$register ? $account->getEmail() : '',
  ];

  // Only show name field on registration form or user can change own username.
  $form['account']['name'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Username'),
    '#maxlength' => UserInterface::USERNAME_MAX_LENGTH,
    '#description' => $this->t("Several special characters are allowed, including space, period (.), hyphen (-), apostrophe ('), underscore (_), and the @ sign."),
    '#required' => TRUE,
    '#attributes' => [
      'class' => [
        'username',
      ],
      'autocorrect' => 'off',
      'autocapitalize' => 'off',
      'spellcheck' => 'false',
    ],
    '#default_value' => !$register ? $account->getAccountName() : '',
    '#access' => $account->name->access('edit'),
  ];

```

```
  $fields['name'] = BaseFieldDefinition::create('string')
    ->setLabel(t('Name'))
    ->setDescription(t('The name of this user.'))
    ->setRequired(TRUE)
    ->setConstraints([
    // No Length constraint here because the UserName constraint also covers
    // that.
    'UserName' => [],
    'UserNameUnique' => [],
  ]);
  $fields['name']
    ->getItemDefinition()
    ->setClass('\\Drupal\\user\\UserNameItem');
  $fields['pass'] = BaseFieldDefinition::create('password')
    ->setLabel(t('Password'))
    ->setDescription(t('The password of this user (hashed).'))
    ->addConstraint('ProtectedUserField');

```

The `AccountForm`, `ProfileForm, and` RegisterForm `classes, which extend the [`ContentEntityForm`][6] class, doen't extend [`ContentEntityForm::validateForm()`][7], though. They implement methods that is necessary to Drupal to understand which entity fields are edited and which violations should be shown: [`AccountForm::getEditedFieldNames()`][8] and [`AccountForm::flagViolations()\`\].

```
protected function getEditedFieldNames(FormStateInterface $form_state) {
  return array_merge([
    'name',
    'pass',
    'mail',
    'timezone',
    'langcode',
    'preferred_langcode',
    'preferred_admin_langcode',
  ], parent::getEditedFieldNames($form_state));
}

```

```
protected function flagViolations(EntityConstraintViolationListInterface $violations, array $form, FormStateInterface $form_state) {
  // Manually flag violations of fields not handled by the form display. This
  // is necessary as entity form displays only flag violations for fields
  // contained in the display.
  $field_names = [
    'name',
    'pass',
    'mail',
    'timezone',
    'langcode',
    'preferred_langcode',
    'preferred_admin_langcode',
  ];
  foreach ($violations->getByFields($field_names) as $violation) {
    list($field_name) = explode('.', $violation->getPropertyPath(), 2);
    $form_state->setErrorByName($field_name, $violation->getMessage());
  }
  parent::flagViolations($violations, $form, $form_state);
}

```

`ContentEntityForm::validateForm()` shows only the validation errors for those form elements that are reported to be edited. This means that if a form element name isn't returned from `AccountForm::getEditedFieldNames()` or `ContentEntityForm::getEditedFieldNames()`, that form element and the corresponding entity field aren't considered edited.

To answer the question: Yes, it's possible to add form elements in the `form()` method of the entity form class and use validation constraints (and their "automatic" validation), as long as the entity form class implements the `getEditedFieldNames()` and `flagViolations()` methods.

---
Tags: entities, forms
---


# Question
Title: Diff module shows 'No visible changes' for 'Geolocation' and 'International phone' fields
I have "No visible changes" message for 'Geolocation' and 'International phone' fields change and have only one option "Don't compare" in Diff field configuration page /admin/config/content/diff/fields.

Can you help me fix this issue?

# Answer
> 1 votes
The Diff module can only compare fields for which a @FieldDiffBuilder class is implemented for that field and that class offers options for comparing that field.
For example, for a comment field, the Diff module implements the `CommentFieldBuilder` class, for which the options are given by `CommentFieldBuilder::buildConfigurationForm()`.

```
$form['compare_key'] = array(
  '#type' => 'checkbox',
  '#title' => $this->t('Compare comment status key'),
  '#default_value' => $this->configuration['compare_key'],
);
$form['compare_string'] = array(
  '#type' => 'checkbox',
  '#title' => $this->t('Compare comment status string'),
  '#default_value' => $this->configuration['compare_string'],
);

return parent::buildConfigurationForm($form, $form_state);

```

There isn't any issue in the module. A module should change the @FieldDiffBuilder class associated with the *Geolocation* and *International phone* fields, to make the Diff module able to compare their values.

---
Tags: 8
---


# Question
Title: How do I know which services.yml is active?
If I have multiple `services.yml` in the `sites/default/` directory, how can I determine which one Drupal is actually loading?

Is there a drush command to check this? Or is there some other way to verify which services file is being used by a site?

# Answer
> 7 votes
The info is stored in global settings, but it isn't necessarily one file. To get the currently active list:

```
$container_yamls = \Drupal\Core\Site\Settings::get('container_yamls');

```

---
Tags: configuration, 9
---


# Question
Title: invalid token: [node:title] when Token module installed
I'm on Drupal 7.80 and a Drupal newb so help with how to debug as well as things to try appreciated.

Taking over a Drupal install that might have some outstanding issues.

**Problem: It looks like 'core' tokens are not available. E.g. `[node:title]`, `[current-page:pager]`, and `[site:name]` are all unavailable**

Detail: When trying to save/preview a custom content type called 'Event' I get a lot of token errors. It looks like they're coming from the Meta tags module which is set by default to populate its fields using tokens. For example Page title in Meta tags is set to: `[node:title] | [current-page:pager][site:name]`, and when saving an Event I get error messages that *none* of those tokens can be found. (I'm assuming Metatag is a use/required core module and I shouldn't attempt to disable it or just remove all these settings)

I have two token modules installed: 'Entity tokens' and 'Token' that both look like core Required modules. I don't know how to check if they're actually installed and working?

The Token Browser only shows 3 top level sections: 'Current Date', 'Current page' and 'Random'.

Is it possible an errant module is removing tokens? How should I debug this?

Thanks for any/all help

**UPDATE**

I found the Flush Cache \> Metatag, did this and that has just removed the Metatag panel from all my Content Types, but it does not seem to have re-added 'core' tokens - Token Browser still shows the limited set of tokens as above.

I've also done a 'Flush all caches' now

# Answer
> 0 votes
Despite having flushed caches whilst logged in I clicked 'Flush all caches' whilst logged in as admin user and this seemed to do the trick where click this while logged in as non-admin did not before.

I'm about 90% sure it was this, I was also clicking around with things in the Configuration \> Meta Data \> Defaults page to see if re-saving settings there did anything but don't think it was this.

---
Tags: 7, tokens
---


# Question
Title: How can I get IntelliSense/Intelephense to look inside a Drupal Docker Container?
I am developing a Drupal site using the latest official Drupal/PHP/Apache Docker image.

I have some local directories mapped to inside the Drupal container as expected (modules, profiles, sites, themes).

When I create a module and try to, for example, extend a Drupal class such as BlockBase, I get an error saying BlockBase is undefined. This is because the Drupal core code is inside of the container, which intelephense and intellisense can't see. Note the code is actually perfectly fine when it is run.

This problem also means I don't get any autocompletion or suggestions for methods and such.

Is there a way to resolve this issue, for example by somehow giving intelephense access to inside of the container?

Thank you.

# Answer
You could use VS Code Remote Development.

Then extensions like Intelephense run in the container and see the entire code.
> 2 votes

---
Tags: 9
---


# Question
Title: undefined drupal_add_js function inside themename_preprocess_page
I wanted to use javascript to delete an option from the list of options in case the user is not an administrator and I searched and found this code inside a post and I used it inside the project's themes-\>mythemename-\>mythemename.theme file, but that didn't work and I have several problems I want to know how to solve, as I searched a lot I did not find a solution

```
function mythemename_preprocess_page(&$variables, $hook) {
    if (!in_array("administrator", \Drupal::currentUser()->roles) {
        if (isset($variables['node']->type) && !empty($variables['node']->type) && (strpos($variables['node']->type, 'proxy_request') !== false)) {
            drupal_add_js(drupal_get_path('theme', 'mythemename') . '/js/datcbaseauth.js');
        }
    }
}

```

The first problem is that I can't get the data of the current user, as I am always reported that it is the second parameter of the in\_array function is null.

The second problem is that I am telling that the second parameter of the strpos function is an object and not just a string even though the example in the post was treating it as just a string.

The third and final problem is that I am saying that function drupal\_add\_js and function drupal\_get\_path are undefined.

I searched for a long time, but I did not find a solution to these 3 problems, even the topics they may mentioned in it are not complete, for example, do not report how to use the drupal\_add\_js function inside the .theme file what is the prerequisite or even within Drupal's documentation itself, there is no data on the variable &$variables will tell about its content, the nature of each part, etc except that it is an associative array

# Answer
* First problem to get current user roles use this

\Drupal::currentUser()-\>getRoles();
* Second problem: `$variables['node']->type` is an array so use `$variables['node']->bundle()` to get type instead:
* The third **drupal\_add\_js** not supported anymore in Drupal 8 use library and attached so try something like the following

```

/**
 * Implements hook_preprocess_HOOK().
 */
function THEME_preprocess_page(&$variables) {
  if (in_array("administrator", \Drupal::currentUser()->getRoles())) {
    if ($variables['node']->bundle() && (strpos($variables['node']->bundle(), 'proxy_request') !== FALSE)) {
      $variables['#attached']['library'][] = 'THEME/custom-library';
    }
  }
}

```
> 1 votes

---
Tags: theming
---


title: How to load a file entity by uuid?

text:
# Question
Title: How to load a file entity by uuid?
So I am trying to use the default image for users in a menu block if a custom one does not exist. And for it I am getting the image file uuid:

```
$default_image = $user->get('user_picture')->getSetting('default_image');

```

Then loading the file entity:

```
$file = Drupal::service('entity.repository')->loadEntityByUuid('file', $default_image['uuid']);

```

This is returning null. What am I doing wrong? And is there a better way to achieve this?

# Answer
This might be what you need?

```
use Drupal\field\Entity\FieldConfig;
use Drupal\image\Entity\ImageStyle;

if (FieldConfig::loadByName('user', 'user', $imageFieldName)
  ->getSetting('default_image')['uuid']) {

  $imageStyle = ImageStyle::load('thumbnail');

  // Load the default image settings.
  $imageGetSettings = FieldConfig::loadByName('user', 'user', $imageFieldName)
    ->getSetting('default_image');

  // Get the default image URI from settings.
  $imageURI = Drupal::service('entity.repository')
    ->loadEntityByUuid('file', $imageGetSettings['uuid'])
    ->getFileUri();

  // Build image style path.
  $imageStyleURL = $imageStyle->buildUrl($imageURI);

  // Set $imageURL.
  $imageURL = file_url_transform_relative($imageStyleURL);
}

```
> 2 votes

---
Tags: 8, entities
---


# Question
Title: How can I override or disable a parent theme's CSS file?
I am trying to override the menu.css file in the default Classy theme through my library file. I have read through the documentation, but anything I tried doesn't work.

What would be the correct markup to override or disable this file?

# Answer
Add this to your theme's **.info.yml** to override it with css/my-menu.css from your theme:

```
libraries-override:
  classy/base:
    css:
      component:
        css/components/menu.css: css/my-menu.css

```

To disable it (don't load it when loading the classy/base library):

```
libraries-override:
  classy/base:
    css:
      component:
        css/components/menu.css: false

```

To get the `classy/base` key you need for the override, find the \*.libraries.yml file where the CSS is declared. The part before the slash is the * in that file (e.g. classy.libraries.yml), and the part after is the top-level key in that file under which the CSS is declared.

In most cases I find it easiest to actually copy the library declaration from the libraries file that declares the asset to maintain the 'css', 'component', keys and indentation.

Note that you can do the same thing for JavaScript assets as well.

See https://www.drupal.org/node/2216195#override-extend for more information.
> 15 votes

# Answer
just gonna drop this update here for anyone else landing on this answer: Apparently the names have changed, but this works for me on D9.2.0:

```
libraries-override:
  bartik/global-styling:
    css:
      component:
        css/components/menu.css: false
        css/classy/components/menu.css: false
  bartik/classy.base:
    css:
      component:
        css/classy/components/menu.css: false

```
> 0 votes

---
Tags: 8, theming
---


# Question
Title: How can I make all external links to open in a new tab?
I want to create a small, custom Drupal 8 module to open all external links in the menu in a new tab, how can I do that?

I think I should use `hook_link_alter` to do it, but I don't know how to do it so I can select all the external links only?

# Answer
> 11 votes
Links can be generated in a number of ways, which makes it hard to change consistently. For a single implementation that you want to reach most parts, you should swap the `link_generator` service with your own subclass. This should catch all menu items and links in general, but wont touch custom markup from wysiwyg. Here you would need to create a custom filter.

The `::generate($text, Url $url)` method is what is used to actually create the create the HTML. What you want to do, it to add the `_blank` target attribute if the url is external.

The code for the link generator subclass, could look like this:

```
class MyLinkGenerator extends LinkGenerator {
  public function generate($text, Url $url) {
    if ($url->isExternal()) {
      $attributes = $url->getOption('attributes');
      $attributes['target'] = '_blank';
      $url->setOption('attributes', $attributes);
    }
    return parent::generate($text, $url);
  }
}

```

I wont go into how to change the class of a service, there is plenty of examples for this here and elsewhere.

# Answer
> 1 votes
If you want to use hook\_link\_alter you can also simply implement the following code in a module :

```
/**
 * Implements hook_link_alter().
 */
function mymodule_link_alter(&$vars) {
  if ($vars['options']['external'] == TRUE) {
    $vars['options']['attributes']['target'] = '_blank';
  }
}

```

# Answer
> 1 votes
extlink contrib module for Drupal 8 & 9 (also a D7 version) can do the job.

On the extlink contrib module project page it says:

> Configure external links to open in a new window

And there is other functionality, too.

I've just started using this module and from tests so far, it does the job.

In my case it does actually open an external link in a **new tab** so even though it says new window, it actually opens in a new tab.

---
Tags: theming
---


title: Change Block view using custom Views

text:
# Question
Title: Change Block view using custom Views
I have one content type(Contains Image & body field). for that, I have created a custom block view using Views. currently, it's showing content like on the left side the image is placed and on the right side, the body content is placed. I have added content 4 times for that content type. now I want to show that content like:

```
    LEFT           RIGHT

    image          body
    body           image
    image          body
    body           image

```

**Can I achieve this using Views or do I need to add custom code or anything else?**

I am new to drupal. Please help me with this.

**Thanks in advance.**

# Answer
I'm not sure of what you want to do, but you can edit the order of the fields into the view itself, in particular from the section fields (if you had set the view as fields):
> 0 votes

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


# Question
Title: How to load a JS library (in a custom module) from a theme using only JS?
I want custom subthemes, one for admin and one for front end. both need to load the leaflet js library that im trying to put into a custom module.

Ive got the subtheme bit working, and my global-scripts js running, but cant get module loaded or running.

*themes/angas\_admin/*

**angas\_admin.info.yml**

```
# subtheme by haydent httech.com.au
name:  Angas Admin
type: theme
description: 'seven subtheme by hayden - httech.com.au'
core: 8.x
base theme: seven

libraries:
  - angas_admin/global-styling
  - angas_admin/global-scripts
  - angas_module/leaflet

regions:
  header: 'Header'
  pre_content: 'Pre-content'
  breadcrumb: Breadcrumb
  highlighted: Highlighted
  help: Help
  content: Content
  page_top: 'Page top'
  page_bottom: 'Page bottom'
  sidebar_first: 'First sidebar'
regions_hidden:
  - sidebar_first

```

**angas\_admin.libraries.yml**

```
global-styling:
  version: 1.x
  css:
    theme:
      css/style.css: {}
global-scripts:
  version: 1.x
  js:
    js/script.js: {}

```

*modules/angas\_module/*

**angas\_module.info.yml**

```
name: Angas Module
description: map by haydent httech.com.au
type: module
core: 8.x

libraries:
  - angas_module/leaflet

```

**angas\_module.libraries.yml**

```
leaflet:
  version: 1.x
  css:
    theme:
      css/leaflet.css: {}
  js:
    js/leaflet.js: {}

```

# Answer
> 3 votes
You need to add your module's library as a dependency of your theme's library (or any other library that depends on it). This will ensure it's always loaded and available for your theme's library. See Declaring dependencies in d.o's docs.

For example, in your theme's libraries.yml file:

```
global-scripts:
  version: 1.x
  js:
    js/script.js: {}
  dependencies:
    - angas_module/leaflet

```

After adding it as a dependency for your libraries, remove it from your theme's .info.yml file (not needed). And remove it from the module's .info.yml file (also not needed).

---
Tags: 8
---


# Question
Title: How can I make Barrio SASS gulpfile coninue watching for changes
When running gulp. It runs and compiles SASS one time. How can I adjust the watch so that it continues watching for changes. Do I need to add usePolling: true or usegulp.series. I am following the directions exactly from the Bootstrap 4 SASS - Barrio Starter Kit

My setup: drupal core 9.1.10 bootstrap\_barrio 8.x-4.33 bootstrap\_sass 8.x-1.13 node v12.22.1 npm 6.14.12 gulp CLI version: 2.3.0 gulp Local version: 4.0.2 Vagrant on Windows using a Redhat 7 virtual machine

```
let gulp = require('gulp'),
      sass = require('gulp-sass'),
      sourcemaps = require('gulp-sourcemaps'),
      cleanCss = require('gulp-clean-css'),
      rename = require('gulp-rename'),
      postcss = require('gulp-postcss'),
      autoprefixer = require('autoprefixer'),
      browserSync = require('browser-sync').create()

    const paths = {
      scss: {
        src: './scss/style.scss',
        dest: './css',
        watch: './scss/**/*.scss',
        bootstrap: './node_modules/bootstrap/scss/bootstrap.scss'
      },
      js: {
        bootstrap: './node_modules/bootstrap/dist/js/bootstrap.min.js',
        jquery: './node_modules/jquery/dist/jquery.min.js',
        popper: 'node_modules/popper.js/dist/umd/popper.min.js',
        popper: 'node_modules/popper.js/dist/umd/popper.min.js.map',
        dest: './js'
      }
    }

    // Compile sass into CSS & auto-inject into browsers
    function styles () {
      return gulp.src([paths.scss.bootstrap, paths.scss.src])
        .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(postcss([autoprefixer({
          browsers: [
            'Chrome >= 35',
            'Firefox >= 38',
            'Edge >= 12',
            'Explorer >= 10',
            'iOS >= 8',
            'Safari >= 8',
            'Android 2.3',
            'Android >= 4',
            'Opera >= 12']
        })]))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(paths.scss.dest))
        .pipe(cleanCss())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest(paths.scss.dest))
        .pipe(browserSync.stream())
    }

    // Move the javascript files into our js folder
    function js () {
      return gulp.src([paths.js.bootstrap, paths.js.jquery, paths.js.popper])
        .pipe(gulp.dest(paths.js.dest))
        .pipe(browserSync.stream())
    }

    // Static Server + watching scss/html files
    function serve () {
      browserSync.init({
        proxy: 'http://orgex1',
        open: false,
      })

      gulp.watch([paths.scss.watch, paths.scss.bootstrap], styles).on('change', browserSync.reload)
    }

    const build = gulp.series(styles, gulp.parallel(js, serve))

    exports.styles = styles
    exports.js = js
    exports.serve = serve

    exports.default = build

```

Result when running gulp:

```
    [vagrant@vagrant6 presentation]$ gulp
    [15:47:33] Using gulpfile /var/www/html/orgex1/web/themes/custom/presentation/gulpfile.js
    [15:47:33] Starting 'default'...
    [15:47:33] Starting 'styles'...
    [15:47:37] Finished 'styles' after 3.62 s
    [15:47:37] Starting 'js'...
    [15:47:37] Starting 'serve'...
    [Browsersync] 3 files changed (bootstrap.min.js, jquery.min.js, popper.min.js.map)
    [15:47:37] Finished 'js' after 56 ms
    [Browsersync] Proxying: http://orgex1
    [Browsersync] Access URLs:
     ----------------------------------
           Local: http://localhost:3000
        External: http://10.0.2.15:3000
     ----------------------------------
              UI: http://localhost:3001
     UI External: http://localhost:3001
     ----------------------------------

```

# Answer
I found my mistake. Since I am using Vagrant on Windows and a Centos7 VM box. When I run the gulp command on the box. My Windows host browser will not see the CSS changes. I had to install Nodejs on Windows, then run the gulp command in my theme folder inside Windows explorer. Then my Windows browser receives the Browsersync update and displays the CSS changes.
> 0 votes

---
Tags: 8, theming, bootstrap-theme
---


# Question
Title: CSRF token is not varying in Ajax callback while submitting form
I have a form with ajax callback as following , on each submit token is not varying , it remains constant for all submit .

wall.routing.yml

```
wall.commentform:
  path: '/commentform'
  defaults:
    _title: 'Comment form'
    _form: '\Drupal\wall\Form\WallCommentPost'
  requirements:
    _permission: 'access content'
    _csrf_token: 'TRUE'

```

In from as following

WallCommentPost.php

```
$ajax = [
  'callback' => [$this, '_wall_comment_ajax_form_post'],
  'wrapper' => 'field-type-replace-comment',
  'event' => 'click',
  'progress' => array(
    'type' => 'throbber',
    'message' => '',
  )
];

$form['wall_submit'] = [
  '#type' => 'submit',
  '#value' => 'Submit',
  '#ajax' => $ajax,
  '#prefix' => '<div class="col-12 p-1 d-flex justify-content-between"><div class="file_name_insert file_name_insert_data-' . $nid . ' pl-4 text-truncate"></div>',
  '#suffix' => '</div>',
  '#attributes' => array(
    'class' => array(
      'btn',
      $ajax_class,
      'd-none',
      'subbtn-' . $nid
    ),
    'disabled' => 'disabled'
  ),
];
$url = Url::fromRoute('wall.commentform');
$token = \Drupal::csrfToken()->get($url->getInternalPath());

$form['#action'] = Url::fromRoute('wall.commentform')->setOption('query', [FormBuilderInterface::AJAX_FORM_REQUEST => 1, 'token1' => $token])->toString();

```

# Answer
> 0 votes
After further digging found out the cause for CSRF token not varying.

CSRF token is dependent on session. So until the session is same CSRF token stays same.

Logout and login again and submit the form, you will get new token.

There is an issue reported in Drupal.org for the same even though it is fixed for Drupal 8, it is not working as expected.

---
Tags: forms, ajax, csrf
---


# Question
Title: Programmatically update Webform Submission by sid
I'm trying create/update Webform Submission programmatically. I already know how the create new submission by following the Drupal 8 API. Now I'm trying to build a update method, I refer to the Webform module source-code and API documents but couldn't find a solution. I guess they remove `webform_get_submission` `webform_submission_update` functions in Drupal 8.3 as-well.

```
$values = [
  'webform_id' => 'attendees_info',
  'in_draft' => FALSE,
  'uid' => $uid,
  'langcode' => 'en',
  'token' => 'at_'.$token,
  'uri' => '/webform/attendees/api',
  'remote_addr' => '',
  'data' => [
    'name' => $name,
    'email' => $email,
    'gallery_url' => 'gallery/'.$token,
  ],
];

$webform = Webform::load($values['webform_id']);
$is_open = WebformSubmissionForm::isOpen($webform);

if ($is_open === TRUE) {
    // Validate submission.
    $errors = WebformSubmissionForm::validateValues($values);

    // Check there are no validation errors.
    if (!empty($errors)) {
       return $errors;
    }
    else {
      // Submit values and get submission ID.
      $webform_submission = WebformSubmissionForm::submitValues($values);
      return $webform_submission->id();
    }
}

```

Above is my Submission creation code, I don't know how to do the update method. Is anyone face this issue before? Hope someone will help me on this, thanks.

# Answer
> 12 votes
Try using *\Drupal\webform\WebformSubmissionInterface::getData();* and *\Drupal\webform\WebformSubmissionInterface::setData($data);*

```
// Load submission using sid.
/** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
$webform_submission = \Drupal\webform\Entity\WebformSubmission::load($sid);

// Get submission data.
$data = $webform_submission->getData();

// Change submission data.
$data['element_key'] = 'custom_element_value';

// Set submission data.
$webform_submission->setData($data);

// Save submission.
$webform_submission->save();

```

# Answer
> 0 votes
jrockowitz's above code is the correct and clean approach. Below also works, just wanted to share.

```
$query = \Drupal::database()->merge('webform_submission_data');
$query->key([
    'sid' => $sid,
    'name' => 'your_custom_key',
])->fields([
    'value' => 'your_value',
]);
$query->execute();

```

# Answer
> 0 votes
To only change **one** element, use:

```
 $webform_submission->setElementData('element_key', 'custom_element_value')

```

---

For example:

> ```
> /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
> $webform_submission = \Drupal\webform\entity\WebformSubmission::load($sid);
> $webform_submission->setElementData('element_key', 'custom_element_value');
> $webform_submission->save();
>
> ```
>
> Source: https://www.drupal.org/project/webform/issues/2911356

---
Tags: 8, forms, webforms
---


# Question
Title: Making content type fields into an exposed filter dropdown?
I have several taxonomy reference fields in a content type that I would like to make into an exposed filter dropdown. With other taxonomy reference fields, it's easier to do so because they only have one parent term for each vocabulary. In this particular case, though, I have a vocabulary term with parent and child terms.

Since the contextual filter isn't working for me in this case, I was wondering if there were maybe any modules out there that can combine all of the content fields that I want and create an exposed filter dropdown with them.

# Answer
> 0 votes
If creating a views exposed filter:

1. Go to the "Filters" section and add a filter.
2. For the filter: Select your node field (where you reference taxonomy terms)
3. For the filter config: select "Select List" and the vocabularies you want listed in the exposed filter.
4. For the filter options: select "Expose this filter to visitors, to allow them to change it"

---
Tags: 8
---


title: Hide Admin Toolbar in iFrame

text:
# Question
Title: Hide Admin Toolbar in iFrame
Is it somehow possible within Drupal 8 to hide the Admin Toolbar when the site is loaded within an iFrame? Like e.g. passing an argument? :-)

I thought about using some sort of preprocess on the page that is getting rendered within the iFrame, but this will not work since the html is cached by Drupal. Also I thought about doing it within Javascript, but I do not want to include a javascript file on every page but default.

Maybe someone knows a hook\_() which will allow me to manipulate the css but is not getting cached?

# Answer
> 3 votes
I would use a similar approach as @Hudri and access the site as `https://www.mysite.com?is_iframe=true`.

Then, add a class to the body tag if the request option is there:

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_html(&$variables) {
  $is_iframe = \Drupal::request()->query->get('is_iframe');
  if ($is_iframe === 'true') {
    $variables['attributes']['class'][] = 'hide-admin-toolbar';
  }
}

```

If I remember correctly, Drupal will regenerate the HTML when you access `https://www.mysite.com?is_iframe=true` vs `https://www.mysite.com`.

---

References:

# Answer
> 2 votes
This should be doable with a cache context:

Drupal core already provides a cache context
`url.query_args`
which can be used for your query parameter, e.g. an URL
`https://www.mysite.com?is_iframe=true`
would be a cache context
`\Drupal::service('cache_context.url.query_args')->getContext('is_iframe');`

AFAIK the cache\_context `url.query_args` is already enabled by default in Drupal core, so you only need to add this cache context to the render array in an appropriate preprocess function.

Note that cache contexts generally do not work with Internal Page Cache module!

For production you should finetune this with a more specific, custom cache-context `url.query_args:my_query_param` to limit unnecessary cache contexts (dumb bots could trigger a gazillion cache context calculations otherwise)

---
Tags: toolbar, 8
---


# Question
Title: How can I add a dynamic redirect on a 404 hit?
I Created a site and URL that returns a 404 Not Found status on www.xyz.com This creates a loss of link equity to the domain and negatively impacts the ability to compete in organic search results.

I wanted to Redirect the URLs returning a 404 status to the defined closest alternative, or parent category, to reclaim link equity from external domains.

Example: Suppose I am using URL **http://www.mysite.com/about/xyz/** and it return 404 so I wanted to create any module or system that smartly redirect to nearest parent path like **"http://www.mysite.com/about/"**

I am not able to find any specific documentation which would point me in the right direction.

# Answer
> 1 votes
Try creating a custom event subscriber. If the page is 404, grab the original URL and redirect accordingly.

To do so, create a new module ("response\_test" in this example), with the usual .info.yml and .module file.

Then register your event subscriber in the module's services file... (see EventSubscriber Example for a full example.

**`./response_test.services.yml`**

```
services:
    response_test.response_subscriber:
      class: Drupal\response_test\404RedirectResponseSubscriber
      tags:
        - { name: event_subscriber }

```

Then create a class to handle the event

**`./src/EventSubscriber/404RedirectResponseSubscriber.php`**

```
<?php

namespace Drupal\response_test;

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

class 404RedirectResponseSubscriber implements EventSubscriberInterface {

  public function onRespond(FilterResponseEvent $event) {
    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
      return;
    }

    $response = $event->getResponse();
    if ($response->getStatusCode() == 404) {

      // Get the old path somehow
      // @see https://stackoverflow.com/q/11047305
      $oldPath = ''; // Try using $response->getUri() or $response->headers->get('location')

      // Manipulate the $oldPath to remove the last part
      // @see https://stackoverflow.com/a/51573313/5771750
      $redirectPath = dirname($oldPath);

      $new_response = new RedirectResponse($redirectPath );

      // Prepare a new Symfony\Component\HttpFoundation\Response and use
      $event->setResponse($new_response);

    }
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = array('onRespond');
    return $events;
  }

}

```

**Note**: This answer is partly based of Clive's answer here: https://drupal.stackexchange.com/a/86622

---
Tags: 8, routes
---


title: How to update a module in production?

text:
# Question
Title: How to update a module in production?
I am using git to deploy my composer.lock to production. Contrib is not part of my git repo. Therefore, in production I then run `composer install` to add contrib to production.

What happens when I update a module in dev via `composer update`, then deploy the updated composer.lock to production and run `composer install` there? Will it update/replace the existing module code or what is the best practices to update a module in production without having to run the resource hungry `composer update` command in production?

# Answer
> What happens when I update a module in dev via composer update, then deploy the updated composer.lock to production and run composer install there? Will it update/replace the existing module code

Yes. Running `composer install` is a fairly lightweight command that will install the components of the system exactly as they have been recorded in `composer.lock` which is essentially a snapshot of the codebase. As you will have committed `composer.lock` containing references to the updated code, when you run `composer install` on any server, it will update the code to match `composer.lock` which has the updated code.

Running `composer update` updates code versions, and is much more resource intensive.

I wrote a blog series on Composer and Drupal a couple of years back which explains this all in more depth: https://www.morpht.com/blog/drupal-and-composer-part-1-understanding-composer
> 1 votes

---
Tags: 8, configuration, composer
---


# Question
Title: After upgrade to Drupal 9.2: Call to undefined function escapeshellcmd(). Why?
When I want to submit a form (webform module) I get get the followng error:

> Call to undefined function Drupal\Core\Mail\Plugin\Mail\escapeshellcmd() in Drupal\Core\Mail\Plugin\Mail\PhpMail::\_isShellSafe() (line 165 of core/lib/Drupal/Core/Mail/Plugin/Mail/PhpMail.php).

This error disappears if I remove all mails in "*/admin/structure/webform/manage/MY-FORM/handlers*".

This error occurs also using simplenews module by trying to subscribe to a newsletter.

# Answer
`escapeshellcmd()` is a built-in PHP function, and should always be found. It evidently can't be found in the global namespace on your system, so PHP falls back to looking for it in the current namespace where it is being called, which is `\Drupal\Core\Mail\Plugin\Mail\escapeshellcmd()`. And obviously it won't be found there either, which is why you get the error.

Try `php --info` and search for the `disable_functions` setting to see if someone turned off use of `escapeshellcmd()` on your system. That seems the only likely possibility. Or better yet search for the `disable_functions` setting at `/admin/reports/status/php` since that will show the settings for the version of PHP that your webserver is using.
> 4 votes

---
Tags: webforms, debugging, 9
---


# Question
Title: I am unable to run "drush site-install" without getting errors
When I open Terminal on the *david/Sites/animals* directory, and I run `drush site-install --db-url=mysql://david:root@localhost:3306/animals`, the get the following error.

> In SiteInstallCommands.php line 152: Drush was unable to drop all tables because `mysql` was not found, and therefore Drupal threw an AlreadyInstalledException. Ensure `mysql` is available in your PATH.

Did I write the correct command?

# Answer
> 2 votes
The solution is part of the error message. `Ensure mysql is available in your PATH.` The command mysql is included in MAMP. You just need to add it the `PATH` environmental variable.

There are many, many post about this - see for example https://stackoverflow.com/questions/2684347/mac-os-x-mamp-how-to-run-mysql-without-having-to-type-in-the-full-path

---
Tags: drush
---


# Question
Title: Getting total count of query in combination with pager
My code:

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

$count = $query->count()->execute();

```

However my $count value is always 9 (because of the pager).

How can i get the total count of the query? (All results)

# Answer
// Use clone.

```
$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$query->condition('type', 'news');
$query->pager(9);
**$count_query = clone $query;**

$items = $query->execute();

$count = $count_query->count()->execute()

```
> 2 votes

# Answer
You can't reuse the same query object for these two different things. `->pager()` permanently turns the query into a paged query, and `->count()` permanently turns it into a count query. Trying to do both results in unpredicted behavior depending on execution order.

The code you pasted actually does return the total count, because count trumps pager if both are set when the query is first executed. But afterwards it's a count query and will always return a number:

```
// With 50 nodes in the database:

$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$query->condition('type', 'news');
$query->pager(9);

$count = $query->count()->execute();
// $count is 50, the ->pager() is ignored.

$items = $query->execute();
// $items is 50, not an array. It's permanently a count query now.

```

Flipping the execution order:

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

$items = $query->execute();
// $items is an array with 9 nodes.

$count = $query->count()->execute();
// $count is 9.

```

Instead, you need to use two separate queries here:

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

$items = \Drupal::entityQuery('node');
  ->condition('status', 1);
  ->condition('type', 'news');
  ->pager(9)
  ->execute();

```
> 1 votes

---
Tags: database, paging
---


# Question
Title: how long do files hang around in temporary://?
I want to offer a file download to my users, and I was thinking of using `temporary://` to store the data. But how temporary is it? When do files disappear from it? Of course, I want to avoid having the file not be present when my user goes to download it jsut after a form submission, and I also want it gone after a while. So when do they go?

# Answer
> 7 votes
Temporary files that are created with the managed file functions are deleted when they are older than six hours, and during cron tasks.

The description for the FILE\_STATUS\_PERMANENT reports the following text:

> Temporary files older than DRUPAL\_MAXIMUM\_TEMP\_FILE\_AGE will be removed during cron runs, but permanent files will not be removed during the file garbage collection process.

The value of `DRUPAL_MAXIMUM_TEMP_FILE_AGE` is 21600 (seconds), which means six hours.

# Answer
> 0 votes
**From Admin UI**
You can configure and check that from `admin/config/media/file-system`.

**Using Drush**
Also can be checked and adjusted using `drush`
`drush cget system.file temporary_maximum_age`to check and `drush cset system.file temporary_maximum_age 300 -y` (To set the time 300 sec)

Also you can customize the setting with `$config['system.file']['temporary_maximum_age'] = TIME_IN_SEC`
in `settings.php` file.

---
Tags: files
---


# Question
Title: Why an exception is raised when I insert a token as a value of an html src attribute
How to raise the exception:

In any text\_area field using ckeditor, insert the following code `<img src="[node:my_custom_token]">` and save the form.

You will get the following error: (assuming the edited form was `http://mysite/fr/node/8/edit`)

```
page not found|127.0.0.1|http://mysite/fr/node/8/[node:my_custom_token]

```

This is a `NotFoundHttpException` thrown in `RouterListener`

Here is the trace

```
PHP internal call Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest(Symfony\Component\HttpKernel\Event\GetResponseEvent $event)
<ROOT>/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php:142 call_user_func($function_name, $parameters)
<ROOT>/vendor/symfony/http-kernel/HttpKernel.php:134 Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch($event)
<ROOT>/vendor/symfony/http-kernel/HttpKernel.php:80 Symfony\Component\HttpKernel\HttpKernel->handleRaw(Symfony\Component\HttpFoundation\Request $request, int $type = 1)
<ROOT>/core/lib/Drupal/Core/StackMiddleware/Session.php:57 Symfony\Component\HttpKernel\HttpKernel->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php:47 Drupal\Core\StackMiddleware\Session->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/core/modules/page_cache/src/StackMiddleware/PageCache.php:106 Drupal\Core\StackMiddleware\KernelPreHandle->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/core/modules/page_cache/src/StackMiddleware/PageCache.php:85 Drupal\page_cache\StackMiddleware\PageCache->pass(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php:47 Drupal\page_cache\StackMiddleware\PageCache->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php:52 Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/vendor/stack/builder/src/Stack/StackedHttpKernel.php:23 Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)
<ROOT>/core/lib/Drupal/Core/DrupalKernel.php:716 Stack\StackedHttpKernel->handle(Symfony\Component\HttpFoundation\Request $request, $type = 1, $catch = true)

```

# Answer
If you are editing an entity and you save the entity, you are redirected to the page showing the entity.
As in the entity content you added `<img src="[node:my_custom_token]">`, the browser is trying to access http://your-site-domain/\[node:my\_custom\_token\] to get the image data for the image it should show. Drupal doesn't find any route associated with that URL and it logs a *Page not found* error and throws an exception.

That isn't related to using tokens, as that could happen whether you enter a URL for your site that doesn't exist, for the *src* attribute.

If you are wondering why that token isn't replaced, that's because the entity form field isn't set to replace tokens, which it can also happens when the entity field is a *Text (formatted, long)* field for which none of the input filters set for its format handle tokens.
> 3 votes

---
Tags: forms
---


# Question
Title: Private file not being displayed on Twig template
I am trying to get an image from the private folder to display on a printer-friendly Twig template page. The private folder is inaccessible to browsers and the only display method I know of is to load the image and convert it to Base64 and pass the Base64 characters into the 'src' attribute of an 'img' element.

My controller code looks something like this:

```
class PrinterFriendlyController extends ControllerBase {

  public function printerFriendly($text) {

    // Load image from private directory and convert to base64
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $image = $this->entityTypeManager
      ->getStorage('file')
      ->load($file_id);
    $image_path = PrivateStream::basePath() . '/images/' . $image->getFilename();
    $image_data = file_get_contents($image_path);
    $image_base64 = 'data:' . finfo_file($finfo, $image_path) . ';base64,' . base64_encode($image_data);

    $page = [
      // Definitely longer than 255 characters
      '#image_base64' => $image_base64,
      // This doesn't work either so it's not a character length issue
      //'#image_base64' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==',
      '#text' => $text,
      '#theme' => 'printer_friendly',
    ];

    return $page;
  }
}

```

The template file looks something like this:

```
<div id="printer-friendly">
  <img src="{{ image_base64 }}" />
  <div id="text">{{ text }}</div>
</div>

```

The 'text' element contains custom text that is positioned over the 'img' element using CSS but is only included for context. It's not related to the problem.

The result that appears on Chrome Inspect is:

```
<img src="">

```

or

```
<img src(unknown)>

```

Either Drupal or Twig is blocking the Base64 image characters but I don't know which one is doing the blocking and I don't know how to prevent it from doing so.

# Answer
Maybe your problem come from function theme printer\_friendly. If your define this funtion, you have to provide variables when define. If this function from contribute module you can use hook\_preprocess\_printer\_friendly to add more variables before render in twig template.
> 1 votes

---
Tags: theming, 8
---


# Question
Title: Add relationships that has 3 layers, Parent -> Child1 -> Child2
Recently I asked a question that was similar (Parent node needs to display the scheduled date that is referenced in the child node), but requirements have changed and now I'm dealing with the Node A (parent) -\> Node B (child) -\> Node C (grand-child). Bear with me as I explain this.

Node A is the main parent. It contains an entity reference field that calls Node B. I've successfully created the contextual filter and relationship to display the necessary information from both Node A and Node B. Entering the mix is Node C. Node C contains one piece of info that needs to be displayed. There is an entity reference field in Node B that calls Node C.

I currently have a contextual filter and relationship on the Node B entity reference field, but the field from Node C isn't displaying. I'm sure this has to do with there being 3 layers to this view. Is there something here that I'm missing, or is views unable to handle the 3 layer relationship?

# Answer
Well, that didn't take much time at all. After doing a bit more searching around, I came up with the following solution.

Under "Relationships" I created another one on the entity reference field used in Node B. Then I assigned the relationship that was created for the Node A entity reference field to this new relationship. Note: the relationship is NOT required because some items do not contain the info from Node C.

Next, under "Fields" I updated the relationship used for the field containing the info from Node C to reference this new relationship. All fields display as/when they should.

I hope this helps someone else out. Cheers.
> 1 votes

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


title: How to invalidate the block list cache?

text:
# Question
Title: How to invalidate the block list cache?
I need to invalidate the block list cache each time a new configuration entity is created, this is because I have a derivative block to handle dynamically one block for each of my configuration entities. I tried to invalidate the block list with the following code

```
Drupal\Core\Cache\Cache::invalidateTags(['block_list']);

```

But when I go to see available blocks I'm not able to see my new block until I clean all the caches on the site.

Usually, when I need to invalidate entity lists from the cache I use the `ENTITY-NAME_list` tag to do it but this time is not working, maybe I'm missing something here?

# Answer
> 3 votes
Clearing the cache not only invalidates the render cache, but also a lot of other caches. For example all plugin manager discovery caches.

In this case you probably need to invalidate the cache of the block plugin manager:

```
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();

```

---
Tags: 8, blocks, caching
---


# Question
Title: Redirect to 404 page, if the path alias doesn't exist
I am developing a multilingual site in Drupal 8. I added content in Turkish and I didn't create any translation for that node.
I managed to redirect user to the path alias. For example, when users visit https://example.com/tr/node/123, they are redirected to https://example.com/tr/custom-node-in-turkish.

When users visit https://example.com/node/123 or https://example.com/ar/node/123, they should be redirected to the 404 page.

How can I achieve this in Drupal 8?

# Answer
You could add the redirect to the .htaccess file.

```
Redirect 301 /ar/node/123 /page-not-found

```
> 0 votes

# Answer
How did you managed to redirect users to the page alias? Maybe you could use:

```
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();

```
> 0 votes

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


title: Somehow subscribe/react to addMessage

text:
# Question
Title: Somehow subscribe/react to addMessage
I'm trying to find an event that I can subscribe to for the method addMessage.

I need to trigger some code everytime a status message is added. On reacting to this event, I need to send a variable from php to JS. I could not find an event to subscribe to so instead I used a preprocess, below.

```
<?php
function mymodule_preprocess_status_messages(&$variables) {
  $variables['#attached']['drupalSettings']['send_me_to_js']['_variable'] = 'Going to js...';
}

```

This preprocess runs everytime addMessage is used and a status message is displayed, but, the variable that i need sent to JS, is not always sent.

For example, this works for messages created from core, and I get the variable in JS. But when Drupal Commerce uses addMessage (eg. when adding a product to cart in ajax setup), the preprocess runs, the status message displays, but the variable is not available in JS.

Here's the javascript:

```
(function ($, Drupal, drupalSettings) {

  Drupal.behaviors.alwave_alerts = {
    attach: function (context, settings) {

      $('.my-class', context).once('unique-string').each(function () {

        // Run after each ajax call
        $(document).ajaxComplete(function () {

          // This is sometimes undefined even though the preprocess above runs
          // and there is a status message on screen
          // (eg. when  commerce creates a status message)
          console.log(settings.send_me_to_js);

        });

      });

    }
  };

}(jQuery, Drupal, drupalSettings));

```

There must be an easy way?

**Update:**

I discovered that the preprocess does not send the variable to javascript only on ajax requests. On first page load it is sent, but subsequent ajax requests do not send this variable to JS. Seems to be the order sequence in which things are executed during ajax requests.

So the question is, How do I send a variable to JS from this preprocess on ajax calls?

# Answer
I managed to resolve this issue. Basically, the problem was that I could not pass a variable from the preprocess function to JavaScript during AJAX requests (as mentioned several times in this issue). So what I did:

1. Inside the preprocess, I set a private temp store variable for later use during AJAX requests.
2. A custom AJAX Callback Command was created that accepts the variable and invokes a JavaScript function, which in turn receives the variable.
3. I then subscribe to a response event that runs on every request. The event is KernelEvents::RESPONSE.
4. Inside the handler for this event, I check that we are in an AJAX request, then retrieve the variable from the temp store, that was previously set.
5. I use the custom AJAX Command, giving it the tempstore variable, which sends it to JavaScript. Done!

You can find the complete code in this module: https://www.drupal.org/project/shoelace\_messages
> 0 votes

---
Tags: theming, commerce, javascript, ajax
---


# Question
Title: How to get total number of results in Search API View?
How can I get the total number of results on a Search API View that has a limit of 5 results to display?

Some more info: I have to make a bit more complex search where several attachments are combined on a page as a groups of results. Every group should show just the first 5 results, but also a link "see all XX results". I'm using Search API + Solr, Views with exposed fulltext search. If I use "Global: Results summary" in header or footer, it will show maximum the limit of 5 as a number.

**edit 1**

Search API Solr returns 'numFound' which is what I need, but how do I use it in Views?

# Answer
So after a day, here's the result:

As J. Reynolds suggested, I finished up using $view-\>total\_rows, but:

* To populate $views-\>total\_rows, you have to use a pager in your view - that was not an option with the attachments.
* If you don't use a pager, you could force populating $view-\>total\_rows by altering the View query before its execution like this:

```
    function mycustommodule_views_pre_execute(&$view) {
      $view->get_total_rows = TRUE;
    }

```

And after that you have that $view-\>total\_rows!
> 5 votes

# Answer
Try with this type of code. You can select either attachment\_before or attachment\_after, and if the placement is not to your liking you may alter the views template to suit. I know this works with a normal view and I don't see why it would not work with a Search API result. And I think you can place it in a theme's template.php file if you prefer rather than a module.

```
function MYMODULE_views_post_execute(&$view){
    if ($view->name == "MACHINENAME_OF_VIEW") { // can slso check for display if need be
        $view->attachment_before .= <div class="result">$view->total_rows</div>
    }
}

```
> 2 votes

# Answer
By configure Views Global result summary in header or Footer, we can display Total number of results.

Search with result summary in Header and pass the tokens,

@start -- the initial record number in the set @end -- the last record number in the set @total -- the total records in the set @label -- the human-readable name of the view @per\_page -- the number of items per page @current\_page -- the current page number @current\_record\_count -- the current page record count @page\_count -- the total page count
> 1 votes

---
Tags: 7, search, views
---


title: Convert Media tags to markup

text:
# Question
Title: Convert Media tags to markup
I imported the content of a website from Drupal 7 to Drupal 8, but some nodes contain something like this.

```
[[{"type":"media","view_mode":"media_large","fid":"403","attributes":{"alt":"","class":"media-image","height":"187","style":"display: block; margin-left: auto; margin-right: auto;","typeof":"foaf:Image","width":"480"}}]]

```

In Drupal 7 this is fixed by setting the filter "Convert Media tags to markup", which does not exist in Drupal 8.

How can I fix this in Drupal 8?

# Answer
Your media token snippet is from the Drupal 7 Media library and WYSIWYG integration.

I don't know if that integration exists yet in Drupal 8. It would apart of, listed as a project of the Media Entity project for drupal 8.

**EDIT**

You want to see the Entity Embed module for Drupal 8 which supports WYSIWYG editors. I don't know if they offer a migration of old media content into this new module though.

These modules were found by these blog resources and DrupalCamp sessions which have a Youtube video showing these modules in action:
> 1 votes

# Answer
In my case:

* source D7
* destination D8 (i have not been able to make it work in D9 yet)
* source uses media\_wysiwyg

in destination enable media\_migration

in settings.php add:

$settings\['media\_migration\_embed\_token\_transform\_destination\_filter\_plugin'\] = 'media\_embed';

run the migration.

@huzooka has added a lot more detailed instruction is media\_migration readme.

## Update

Looks like in D9 I have to :

a) actually call the plugin and

b) match the display modes

This worked:

```
 body:
    -
      plugin: sub_process
      source: body
      process:
        value: value
        summary: summary
        format:
          plugin: default_value
          default_value: cc_wysiwyg
    -
      plugin: media_wysiwyg_filter
      view_mode_matching:
        default: full
        full: full
        teaser: teaser
        small: medium

```
> 0 votes

---
Tags: 8, nodes
---


title: REST GET without caching

text:
# Question
Title: REST GET without caching
Using ~~this tutorial~~ Drupal Console's `drupal gprr` command, I've created a custom REST resource in Drupal 8. I'm able to use this resource to retrieve a simple JSON object that says hello to the current user by doing a GET on:

```
http://localhost/example/hello?_format=json

```

The JSON returned then looks like this:

```
{ "hello": "tyler" }

```

This is to be expected, as I'm logged in. But when I logout, and do another GET on the resource, the ***same result is returned***:

```
{ "hello": "tyler" }

```

Doing a full Drupal cache clear fixes this issue, but I'd like to specifically disable caching on this resource. How can I do that?

As a workaround, I thought adding a time stamp to the query string would work:

```
http://localhost/example/hello?_format=json&time=123456789

```

But that ***also returns the exact same result***, no matter what time stamp value is in the query string.

For brevity, here's the skeleton code for building the GET resource:

```
class ExampleHello extends ResourceBase {

  /**
   * {@inheritdoc}
   */
  public static function create(/* ... */) {
    return new static(/* ... */);
  }

  /**
   * Constructs a Drupal\rest\Plugin\ResourceBase object.
   */
  public function __construct(/* ... */) {
    parent::__construct(/* ... */);
    // ...
  }

  /*
   * Responds to GET requests.
   */
  public function get() {

    $account = \Drupal::currentUser()->getAccount();
    if (!$account->id()) {
      return new ResourceResponse(array(
        'welcome' => 'visitor'
      ));
    }
    return new ResourceResponse(array(
      'hello' => $account->getAccountName()
    ));
  }

}

```

Is there a configuration/setting I need to set on this plugin to disable caching on GET requests?

# Answer
> 18 votes
You want to read the Cacheability documentation. it says render arrays, but it also applies to response objects.

ResourceResponse implements CacheableResponseInterface, which has the addCacheableDependency method.

If in any way possible, you want to avoid disabling the cache (which you would do by setting the cache max age to 0), but add the necessary cache contexts and cache tags.

In your cache, that means all you need to do is $response-\>addCacheableDependency($account).

You also don't need getAccount(), just use currentUser() directly, it's a proxy.

# Answer
> 17 votes
I had the same issue.

After reading through the documentation and looking through this page, I was able to shut off the cache for my custom endpoint. Here's an example of my working code inside the get() function for my endpoint:

```
$build = array(
  '#cache' => array(
    'max-age' => 0,
  ),
);

return (new ResourceResponse($myResponse))->addCacheableDependency($build);

```

Adding this for future reference, hope this helps anyone who needs it.

CacheableResponseTrait documentation page

# Answer
> 6 votes
Without any tweaking, you can simply return a ModifiedResourceResponse:

```
<?php

// ...

use Drupal\rest\ModifiedResourceResponse;

// ...

class ExampleHello extends ResourceBase {

    public function get() {
        // ...
        return new ModifiedResourceResponse($response, 200);
    }

}

```

# Answer
> 5 votes
I also had the same issue and the solution for that is:

```
$response->getCacheableMetadata()->addCacheContexts(['url.query_args', 'url.path']);

```

You can also see the CacheableMetadata and the cache contexts documentations.

---
Tags: 8
---


title: How to programmatically load a View?

text:
# Question
Title: How to programmatically load a View?
I have created a View that I want to fetch the output from within a module. On drupal.org, the latest recommendation seems to be

`$entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load(1)`

So, this is my code.

```
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
$view = \Drupal::entityTypeManager()
  ->getStorage('view')
  ->load($view_id);
$view->getDisplay('latest_blog');

```

It seems to be getting me very close - in debug, I'm seeing properties that clearly indicate I'm getting the object.

Am I on the right track and just missing one little piece? Loading a taxonomy term, or a node is easy. But this View thing is stumping me and I can't find anything much beyond the old Drupal 7 way of doing this.

# Answer
Thank you @4x4. I dug around core and also found that. My working code that produces the resulting node from the query is this.

```
  $view = \Drupal::entityTypeManager()
    ->getStorage('view')
    ->load($view_id)
    ->getExecutable();

  // Get the NID from the View result.
  $view->initDisplay();
  $view->setDisplay('latest_blog');
  $view->execute();
  $result = $view->result;

```

With the NID from that, we can easily get the path - which was what I needed.
> 3 votes

# Answer
You probably want to load a ViewExecutable:

> class ViewExecutable
>
> Represents a view as a whole.
>
> An object to contain all of the data to generate a view, plus the member functions to build the view query, execute the query and render the output.

```
$executable = $view->getExecutable();

```
> 3 votes

---
Tags: 8, views
---


# Question
Title: How many temporary files will be deleted on every cron run?
I was just wondering if anyone knew how many files the Drupal cron removes from your tmp/ directory per cron run? Is it limited to 100 at a time? Where can I see this information?

# Answer
> 4 votes
Yes, the query is set to 100 items per cron run. You can see the associated code for it in file\_cron().

> ```
> $fids = Drupal::entityQuery('file')
>   ->accessCheck(FALSE)
>   ->condition('status', FILE_STATUS_PERMANENT, '<>')
>   ->condition('changed', REQUEST_TIME - $age, '<')
>   ->range(0, 100)
>   ->execute();
>
> ```

---
Tags: 8, cron
---


# Question
Title: How do I remove the title field from a node's custom view mode
In my Drupal 8 website I created a custom view mode through the UI. I use it to output nodes using a view.

In the view result I do not want the titles of the nodes to appear. The UI (content type \> manage display) does not seem to give the option to hide the title.

How can I hide the title in a specific view mode for an entity via the UI or via custom code?

# Answer
> 3 votes
The output of the title is different from the other fields. The reasons for that is, that the title is used for the title block and as metadata in the html head:

```
html.html.twig:
<!DOCTYPE html>
<html{{ html_attributes }}>
  <head>
    <head-placeholder token="{{ placeholder_token|raw }}">
    <title>{{ head_title|safe_join(' | ') }}</title>

```

If the node is used in another context, for example when it is part of a view, the title is placed in the node template as `{{ label }}`:

```
node.html.twig:
  {% if not page %}
    <h2{{ title_attributes }}>
      <a href="{{ url }}" rel="bookmark">{{ label }}</a>
    </h2>
  {% endif %}

```

This is controlled by the variable `page`, a boolean, which is true, if the view mode is `full`. This is standard in drupal, when the node is displayed as main content and the title should appear in the head.

If you want to change this default behavior, you have to edit the node twig or change the variable `page` in preprocess.

In preprocess this would look like this:

```
function theme_preprocess(&$variables, $hook) {

   if ($hook == 'node') {
      if ( $variables['elements']['#view_mode'] == 'teaser' ) {
         $variables['page'] = true;
      }
   }
}

```

This will remove the title from the view mode `teaser`.

**Edit:**

To answer the specific question in the latest comment, how to make the title field manageable in the display UI:

You have to change the field definition in a hook:

```
function mymodule_entity_base_field_info_alter(&$fields, $entity_type) {
  if ($entity_type->id() == 'node') {
    if (isset($fields['title'])) {
      $fields['title']->setDisplayConfigurable('view', TRUE);
    }
  }
}

```

Don't forget to remove `{{ label }}` from node twig, so that the title is not displayed twice.

# Answer
> -1 votes
Can do via UI with Display Suite:

Manage Display for the entity - at the bottom the Layout, set as One Column

---
Tags: 8, entities
---


# Question
Title: How can I see which modules can be upgraded when upgrading core?
Is there a way to get the list of the modules installed on a Drupal 7 site which could be upgraded to Drupal 9 or replaced by modules compatible with Drupal 9?

# Answer
> 0 votes
The module for this is Upgrade Status.

However, this will still require additional research-- several modules in Drupal 7 have been partially or completely integrated into core (such as Views, Entity, etc.), and this has resulted in contrib modules getting reworked to handle more use cases than in Drupal 7, so they don't necessarily match `1:1` anymore.

---
Tags: migrations, 9
---