# Question
Title: How to add highlighting to exposed views_autocomplete_filter in Drupal 8
Is there a way (a hook perhaps) that would allow me to modify the autocomplete fields returned by an exposed views\_autocomplete\_filter field? I'd like to style the text typed into the field differently from the rest of the suggestion text.

Something like this:

------------------
| term\_ |
------------------------------
| term**inal emulators** |
------------------------------
| **de**term**ination** |
------------------------------
| **mid**term **exams** |
------------------------------

# Answer
> 2 votes
So it seems it is necessary to extend the `ViewsAutocompleteFiltersController` class to do this. In order to override the routing so that a custom controller can be used instead, an entry must be added to `/mymodule/mymodule.services.yml`:

```
services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

```

Then provide your `/mymodule/src/Routing/RouteSubscriber.php` file, which redirects to our local `ViewsAutocompleteFiltersController`

```
<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Replace "some.route.name" below with the actual route you want to override.
    if ($route = $collection->get('viewsfilters.autocomplete')) {
      $route->setDefaults(array(
        '_controller' => '\Drupal\mymodule\Controller\ViewsAutocompleteFiltersController::autocomplete',
      ));
    }
  }
}

```

Finally provide your local `/mymodule/src/Controller/ViewsAutocompleteFiltersController.php` which filters for the view of interest, then modifies the output of the base `ViewsAutocompleteFiltersController`. The tricky part of that process is that the `data` member of the `JsonResponse` output is protected, so we use a customized `JsonResponse` wrapper to perform the highlighting:

```
<?php

namespace Drupal\mymodule\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Overrides default ViewsAutocompleteFiltersController to provide highlighting of autocomplete suggestions
 */
class ViewsAutocompleteFiltersController extends \Drupal\views_autocomplete_filters\Controller\ViewsAutocompleteFiltersController {

  /**
   * {@inheritdoc]
   */
  public function autocomplete(Request $request, $view_name, $view_display, $filter_name, $view_args) {

    $response = parent::autocomplete($request, $view_name, $view_display, $filter_name, $view_args);
    if($response instanceof JsonResponse && $view_name === 'my_view' && $view_display === 'my_view_display') {
      $response = new HighlightedJsonResponse($response, $request->query->get('q'));
    }
    return $response;
  }

}

/**
 * Overrides default JsonResponse to provide highlighting of autocomplete suggestions
 */
class HighlightedJsonResponse extends JsonResponse {

  function __construct($jsonResponse, $q) {

    $data = \json_decode($jsonResponse->data);
    if(isset($q)) {
      $qPattern = '/(' . preg_quote($q, '/') . ')/i';
      foreach($data as &$datum) {
        if(isset($datum->label)) {
          $datum->label = '<b>' . \preg_replace($qPattern, '</b>$0<b>', $datum->label) . '</b>';
          $datum->label = \str_replace("<b></b>","",$datum->label);
        }
      }
    }

    parent::__construct($data, $jsonResponse->statusCode, $jsonResponse->headers->all());

  }
}

```

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


# Question
Title: How to create a view to display event registrants?
I'm having troubles setting up a View that displays a list of **registrants** (not registrations!) for a particular event. I don't know how to setup RELATIONSHIPS correctly?

(I have already created a view that displays all **registrations** for a particular event, but since the user can register more than once for a particular event, I'm getting a list with multiple users enteries (if user registered multiple times) which is not what I want.)

Any suggestions?

# Answer
For displaying user entries only one, open the Query settings: Settings located at bottom of the Advance section. There u can check the Distinct checkbox which will make the view display only distinct items.

Hope this help you...
> 0 votes

# Answer
I do not see a difference between registrations and registrants,this can be handled with what fields you are showing in the views.While the problem of having repetitive results can be handled by showing the distinct results but I would have preferred doing it at the time user is registering multiple times for the same event user has already registered, as the problem you are having user will face the same problem, they will never know if they are already registered for the event, instead a validation should be there on email address(or any unique field to catch user presence) and event to tell user about being already registered.
> 0 votes

# Answer
I believe you can expose user fields and add a relationship on the user entity referenced by registration field "user". This may not solve your duplicate problems.

You may be able to list users instead, and add a relationship to the registration referencing the user, and you may need to go one level deeper and add a relationship to your event content referencing the registration. Then filter on the registration existing and on the event content ID.

If anonymous users can register, both of these will have slight issues with that.
> 0 votes

# Answer
Dealing with duplicates like this is often an issue with Views. I have two suggestions to try:

1. Assuming this is a field-based View, try using "group by" on a user field, and don't display any of the registration distinct information, if possible. You may want/need to play with display tricks, whether specifying tags or custom CSS to get the display nice.
2. If that doesn't do the trick, you may have to resort to a `hook_views_prerender` function, and combine/eliminate results there. It's not fun, but I have had to do that kind of thing on more than one occasion.
> 0 votes

---
Tags: views
---


# Question
Title: Custom formatting of tokens for date fields
In D8.1, I have created a field called field\_date and added it to a content type.

I try to use pathauto to try to configure a URL pattern for the content type like type/year/title. But the token browser does not expose expandable date options for date\_field. If I enter it manually, I get "The Path pattern is using the following invalid tokens: \[node:field\_datetime:custom:Y\]."

How can I format the output of a token for a date field, the same way I can for a node property like date created?

I've searched the issue queues for contrib token, core datetime and core token system, but I find nothing about this.

# Answer
In the **Manage Display** section of your content type can control the output of your date field token.

Under **Custom Display Settings**, make sure the *Token* checkbox is set so you can adjust your token display. Once set, you can navigate to the **Token** tab where you can set your date field's **Format** to *Custom* and add your custom PHP `date()` string in the **Date/time format** field.
> 2 votes

# Answer
The Token module added direct support for datetime and daterange fields in December 2016. See https://www.drupal.org/project/token/issues/2786181.

You should be able to use something like `[node:field_datetime:date:custom:Y]`
> 5 votes

# Answer
Another option is to use:

\[node:field\_\[YOUR-CONTENT-TYPE\]\_date:0:date:custom:Y\]
> -1 votes

---
Tags: 8, datetime, tokens
---


# Question
Title: Can't use exit(0), how else can I terminate a response?
Here's my code(using Drupal 8):

```
public function checkForRedirection(GetResponseEvent $event) {
    $is_authenticated = $this->currentUser->isAuthenticated();
    $route_name = $this->routeMatch->getRouteName();

    if (!$is_authenticated && $route_name !== "user.login") {
      header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
      header("Cache-Control: post-check=0, pre-check=0", FALSE);
      header("Pragma: no-cache");
      define("SITE", "www.google.com");
      $response = new RedirectResponse(SITE, $this->redirectCode);
      $response->send();
      $exit(0);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ["checkForRedirection", 30];
    return $events;
  }

```

So I'm redirecting an authenticated user away from my site. It works perfectly how I want it to, the only problem is PHP Mess Detector doesn't allow the exit(0) function, so wondering what are my alternatives to produce same functionality that exit(0) does here?

# Answer
> 2 votes
You need to terminate using the kernel. You'll have to generate `$currentRequest` and `$response`, which may already be available depending on where your code lies. After you have them, you can terminate the request using:

```
\Drupal::service('kernel')->terminate($currentRequest, $response);

```

---
Tags: 8
---


# Question
Title: How do I only render the main content without wrapping it with the theme or side blocks and menus?
I want to output a google map div with a side panel in my drupal 8 moodule. So no need for blocks surrounding my main content.

The question is how do I tell Drupal to only render main content using a Twig template of my module without outputting the entire Drupal theme stuff a long with the menus and the blocks?

All online materials I found so far talks about concepts behind Drupal rendering mechanism and render arrays but none really tell something about their implementation.

Take for instance, the concept of page variants in the following link. HTMLRenderer fires an event to determine which type of page will be used to wrap the main content around: RenderEvents::SELECT\_PAGE\_DISPLAY\_VARIANT. Its also says the SimplePageVariant, which will only output the main content, is suppose to be used by default but in case the Block module is enabled like my case, the BlockPageVariant kicks in to allow the placement of blocks in the regions around the main content. It continues, if you want, you can subscribe to this event in your own module and provide your own variant. However, I couldn't figure out how to do this subscribing.

I feel what I want is simpler than creating my own Page variant. I just want to output simple html with two divs in the Twig template of my own module.

Anyone has an idea what to do?

**Edit**

So there are two ways to do this as mentioned in the answer below, I will just summarize them and add a little more clarification of naming convention in drupal 8:

Return a basic Symfony response with out any drupal specific rendering:

```
$element['#title'] = 'Title';
$html = \Drupal::service('renderer')->renderRoot($element);
$response = new Response();
$response->setContent($html);
return $response;

```

Doing so, you will not be able to attach css or js libraries with render arrays. However, if you want to do that you can override the page.html.twig by following dupral 8 template naming conventions link with out returning "pure symfony" response and hindering drupal from finishing its theming.

# Answer
There are two similar questions.

Problems creating a custom blank page with my custom module

How to output from custom module without rest of theme

You can use a symfony response or replace the page template with a blank twig in `hook_theme()`.
> 5 votes

# Answer
If you need to render a piece of content with no regions or blocks, but just the piece of content, wrapped in valid HTML, with the ability to attach CSS/JS or whatnot you can do the following. In this example, I am going to wrap a field of a node in proper HTML (HTML tag, head tag, body tag etc), with nothing else at all. This content will be accessible at a route/path, so that it can be used in an iframe.

Situation

* Node has: field\_description - a textfield that needs to be rendered in a stand alone page
* Goal is to render the description, alone as a stand-alone, valid HTML page.

## Step 1: Create a route

Create a route that will be used for the description

```
node.description_raw:
  path: '/node/{node}/description'
  defaults:
    _controller: '\Drupal\example\Controller\Controller::descriptionRaw'
    _title: 'Description'
  requirements:
    _permission: 'access content'
    node: \d+
  options:
    parameters:
      node:
        type: entity:node

```

This route calls `\Drupal\example\Controller\Controller::descriptionRaw()` to generate the page response.

## Step 2: Build the Controller Response

The next step is to build the controller response:

```
public function descriptionRaw(NodeInterface $node) {
  $page = [
    // Note - the view mode here is `standalone_description` - a
    // custom view mode (More to come later in the tutorial)
    'description' => $node->field_description->view('standalone_description'),
    // If you need CSS/JS, you can attach the library
    '#attached' => [
      'library' => 'example/description_raw',
    ],
  ];

  return $page;
}

```

At this point, the page will be rendered with all the regions/content etc, so the requirements aren't yet met.

## Step 3: Create a New Page Template for the Standalone Description

The next thing is to create a theme suggestion for the audio player page, that will override the default page.html.twig template. This is done by implementing `hook_theme_suggestions_page()`:

```
function HOOK_theme_suggestions_page(array $variables) {
  $suggestions = [];
  $route_name = \Drupal::routeMatch()->getRouteName();
  if ($route_name == 'node.description_raw') {
    $suggestions[] = 'page__description_raw';
  }

  return $suggestions;
}

```

Now when accessing the route defined in step 1, the system will look for the template `page--description-raw.html.twig` in the active theme, and if it exists, it will use that template to render the page, rather than the default `page.html.twig`.

## Step 4: Create the template to render the content

The next step is to create the template used to render the content, as defined in the theme suggestions in the last step. The content of this template is very simple. `page--description-raw.html.twig`:

```
{{ page.content }}

```

This is very simple, as only the content of the page should be rendered, and nothing else. In this case, the content of the page is the description field that was set in the controller.

## Step 5: Adjust settings using view modes

There is still likely a lot of unwanted markup around the description from labels. In the controller, the field was set to use the view mode `standalone_description`. The first step is to create this view mode:

1. Navigate to Admin -\> Structure -\> Display modes -\> View modes -\> Add view mode
2. Click `Content` (for nodes)
3. Enter `Standalone Description` (machine name `standalone_description`)
4. Save

Next, the new view mode must be configured:

1. Navigate to Admin -\> Content types -\> \[Content Type\] -\> Manage Display
2. Scroll to the bottom and expand 'Custom display modes'
3. Check `Standalone Description` (the view mode just created)
4. Save.
5. Click on the newly created `Standalone Description` tab
6. Hide all fields other than the description
7. Set the label to be 'visually-hidden' (For the sight-impaired)
8. Set the format to your desired settings
9. Save

When this is all said and done, the field on the node is rendered in a stand-alone HTML page, and is customizable through the newly created view mode.
> 3 votes

---
Tags: 8
---


# Question
Title: How do I display a username on their profile pages?
Using Drupal 8, I simply want a user's profile (or account) page to show its username, like so:

For username "bob":

Username: bob

Do I add a computed field? What's a line of code would I use?

# Answer
> Do I add a computed field?

No

> What's a line of code would I use?

In your theme's `.theme` file add:

```
/**
 * Implements hook_preprocess_HOOK().
 */
function THEMENAME_preprocess_page_title(&$variables) { // your theme might already have this function/hook.
  $user = \Drupal::request()->attributes->get('user');
  if ($user instanceof \Drupal\user\UserInterface) {
    $variables['title'] = t('Username') . ': ' . $user->getAccountName();
  }
}

```

Note: Clear/flush the cache for changes to kick in.
> 0 votes

---
Tags: users
---


# Question
Title: What message is throwing InvalidArgumentException(s) in my contact forms?
When submitting a contact form it redirects to a WSOD and this is logged:

```
Uncaught PHP Exception InvalidArgumentException: "$string ("Message") must be a string." at /Applications/MAMP/htdocs/onb/core/lib/Drupal/Core/StringTranslation/

```

I've tried creating new forms and setting them as default. It didn't work. I've also tried uninstalling and installing the contact module without much luck. Any thought on how to fix it or dig up what exactly is causing it?

Thanks.

# Answer
You're most likely passing an object or an array to a translation function call. The `t()` function expects a string as it's first parameter (see the function spec on drupal.org). Search for places where you call the `t()` function.

More information on how the translation functions are used in D8 can be found on the translation api page on drupal.org. This will give you an idea of how and where you could have translations so you can check those places in your code.
> 3 votes

# Answer
One thing to also watch out is using `$this->t` or `t()` function on the method that is accepting string and than translating that string by default. Meaning, we are trying to run the string trough `t()` function twice.

For example: `$route->setDefault('_title', $this->t('some string'))`. No need to use `t()` function here because `'_title'` string is available for translation by default.
> 1 votes

---
Tags: 8, forms, i18n-l10n
---


title: Watchdog file growing out of control

text:
# Question
Title: Watchdog file growing out of control
My ISP has a 1Gb limit and blocked my site.
The file grew to 16 Gb in less than a week. I emptied the watchdog sql file in the database with phpAdmin. This overcame the block and the site restarted, with an SQL error on the front end and hundreds of SQL errors on the back end, which still, nevertheless, will start.
In less than 10 minutes after emptying the file, the size had returned to 1 Gb. 45 minutes later, there were 250,000 rows occupying 3 Gb.

The site is normally quiet. It has had little in the way of addition in the last 6 months and serves about 200-500 pages a day.

The logged error is the following.

> Deprecated: assert(): Calling assert() with a string argument is deprecated in Drupal/Core/Plugin/DefaultPluginManager.php on line 151

# Answer
> 3 votes
You have a few options here.

For the short term, you can disable database logging on /admin/modules/uninstall until you can get the full situation under control.

You can disable assertions. Search yout settings file(s) and set

```
assert_options(ASSERT_ACTIVE, FALSE);

```

You should also edit your php.ini file to set `zend.assertions=0`.

You can then enable database logging again.

That said, it seems like you are running an old version of Drupal. PHP 7 changed the way assertions work, this was fixed in core in late 2017 and was part of Drupal 8.5. You should update your site to fix this, and get the security updates that have been made since then.

---
Tags: 8
---


title: Custom column in commerce view?

text:
# Question
Title: Custom column in commerce view?
I have a view that lists all the orders. I want an action/operations column in the view which has buttons/links for eg: edit, repeat, delete, upload, download, reset, print. I cannot find a way to include a custom column in my view.

Current "Operations links" Columns shows me some menus which are added by default. Can I change them or can i add another column with my own choice of buttons/links ?

# Answer
You have two "simple" options and a third "hard" option, which involves writing a custom Views field ... I'm going to skip that one and focus on the simpler options.

1. Those links all share a common pattern with only the order ID changing based on the row you're looking at. You can use tokens ("replacement patterns") in custom text fields on Views, including the order ID if you've added it to the View's fields list. This means your first option is to add the Order ID field to the View (and hide it by "excluding it from display") and then add a custom text field that adds whatever HTML you want, using the order ID token in the URLs.
2. The other option would be to add custom CSS to the View that alters the dropbutton styling. In the default HTML for that operations column, it's just using CSS to turn multiple links into that dropbutton format. You can undo that with your own CSS if you'd like, using the classes on the individual links to pick the right icon or whatever from your theme (e.g. "edit", "delete", etc.).

Either one of these solutions will be much simpler than writing custom Views code, and the second doesn't involve editing the View at all. : )
> 0 votes

---
Tags: views, commerce
---


# Question
Title: Using Drupal 8 Feeds with Xpath parser, can I concatenate two attribute values that appear in a single tag?
I have a dataset content type and an xml structure like this:

```
<dataset>
   <purpose>blah blah</purpose>
   <abstract>blah blah</abstract>
   <authors>blah blah1, blah blah2</authors>
   <ordered-authors>
      <author>blah blah</author>
      <author>blah blah</author>
      <author>blah blah</author>
   </ordered-authors>
   <tags>
      <themes>
         <theme name="xxx" rank="1"/>
         <theme name="yyy" rank="1"/>
      </themes>
   </tags>
</dataset>

```

I want to get the multiple attributes of each theme tag into a form like: xxx-1, yyy-2, etc. which will be used as entity references for each dataset, whether as an array, or a list that I then implode via a tamper. In Drupal 7 there were "dummy" fields to hold temporary values - I could create extra fields in the content type for this purpose but so far, that hasn't helped me find any way to query the xml and/or use available tamper options to combine the nested attributes to get a usable array of concatenated values (short of giving up with the feeds interface and moving to migrate). ANY help or suggestions would be appreciated!

# Answer
> 0 votes
Well, I have a solution but it's not elegant. I used this query: //theme/@name|//theme/@rank

and Imploded the resulting array to get theme1,rank1,theme2,rank2, etc,

then used a regex to replace every odd comma with a dash: /(\w+)\W\*,\W\*(\w+)/ $1-$2

and then Exploded back to an array.

Would still like to know if there's a better alternative.

---
Tags: feeds
---


title: Add wrapper to Views Rest JSON Output

text:
# Question
Title: Add wrapper to Views Rest JSON Output
I am rebuilding an API in Drupal. The structure of the JSON must remain the same.

I am using Views and Draggable Views so the user can order items on an overview page. I Enabled the view for exporting REST JSON.

The response JSON must have a structure like this

```
{
  items: [{...},{...}]
}

```

But currently views output is like this

```
{[{...},{...}]}

```

I already managed to get my desired output without views and a special export controller but unfortunately, I need draggable views in additions to views. I also managed to create nested structures with Entity Normalizers inside an item but I want the whole output of the view is wrapped in "items". Any help would be appreciated.

# Answer
You can write a views style plugin to get through this fast. Here is an example of that, which adds an outer wrapper of `results` plus a `totalCount` item:

```
<?php

namespace Drupal\mymodule\Plugin\views\style;

use Drupal\rest\Plugin\views\style\Serializer;

/**
 * The style plugin for serialized output formats.
 *
 * @ingroup views_style_plugins
 *
 * @ViewsStyle(
 *   id = "serializer_count",
 *   title = @Translation("Serializer with Count"),
 *   help = @Translation("Serializes views row data using the Serializer component and adds a count."),
 *   display_types = {"data"}
 * )
 */
class SerializerCount extends Serializer {

  /**
   * {@inheritdoc}
   */
  public function render() {
    $rows = [];

    if (isset($this->view->pager)) {
      $count = $this->view->pager->getTotalItems();
    }
    else {
      $count = 0;
    }

    // If the Data Entity row plugin is used, this will be an array of entities
    // which will pass through Serializer to one of the registered Normalizers,
    // which will transform it to arrays/scalars. If the Data field row plugin
    // is used, $rows will not contain objects and will pass directly to the
    // Encoder.
    foreach ($this->view->result as $row_index => $row) {
      $this->view->row_index = $row_index;
      $rows[$row_index] = $this->view->rowPlugin->render($row);
    }

    unset($this->view->row_index);

    // Get the content type configured in the display or fallback to the
    // default.
    if ((empty($this->view->live_preview))) {
      $content_type = $this->displayHandler->getContentType();
    }
    else {
      $content_type = !empty($this->options['formats']) ? reset($this->options['formats']) : 'json';
    }

    return $this->serializer->serialize(['results' => ['items' => $rows, 'totalCount' => (int) $count]], $content_type, ['views_style_plugin' => $this]);
  }

}

```

Then clear cache, and change the plugin for the View under "Style".

So in your case, the final line would look like:

```
return $this->serializer->serialize(['items' => $rows], $content_type, ['views_style_plugin' => $this]);

```
> 2 votes

# Answer
Drupal's Core Serializer does not provide options to customize the json, nor does it include the pagination data.

The Pager Serializer module does include the pagination information, and the property names are customizable, so your api can remain unchanged.

By default, it produces something like this.

```
{
  rows: [
    {...},
    {...}
  ],
  pager: {
    current_page: 0,
    total_items: 6,
    total_pages: 2,
    items_per_page: 5,
  }
}

```

Use the module's configuration form to customize the *rows* key, and disable the unneeded properties to meet your needs.

```
{
  items: [
    {...},
    {...}
  ]
}

```

*or* if you need the total count as provided in the answer by @kevin.

```
{
  items: [
    {...},
    {...}
  ],
  totalCount: 6
}

```

*or*

```
{
  items: [
    {...},
    {...}
  ],
  pager: {
    total_items: 6
  }
}

```
> 1 votes

---
Tags: views, 8
---


title: HTML mail without using modules

text:
# Question
Title: HTML mail without using modules
I am trying to use the `MailManager` class in Drupal 8 to send HTML mail. I got it working, but it isn't parsing the HTML markup. I think something is wrong with the headers of the email.

What I have is a custom module (*Custom\_forward*) that contains a form and that calls `Mailmanager::mail()` in its `submitForm()` method, which contains the following code.

```
        // Email body
        $header = $sender . ' thought you would like to see this page from the website.';
        $personal_message = $form_state->getValues()['message_body'];
        $entity_url_value = '<a href="' . $entity_url->toString() . '">Go to article</a>';
        $message = $header . '<br>' . $personal_message . '<br>' . $entity_url_value;

        // Email
        $langcode = 'en';
        $mailManager = \Drupal::service('plugin.manager.mail');
        $to = $form_state->getValues()['recipient'];

        $params['title'] = 'Forward';
        $params['message'] = $message;
        $result = $mailManager->mail('custom_forward', 'forward', $to, $langcode, $params, NULL, true);

        if ($result['result'] !== true) {
            drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
            \Drupal::logger('mail-log')->error($message);
        }
        else {
            drupal_set_message(t('Your message has been sent.'));
        }

```

According to Drupal you also need the hook\_mail method in mytheme.theme to be able to send message, you can see this method here:

```
function custom_forward_mail($key, &$message, $params) {
  $message['body'] = [];
  $message['subject'] = [];
  $message['headers'] = array(
    'content-type' => 'text/html',
    'charset' => 'UTF-8',
    'format' => 'flowed',
    'delsp' => 'yes',
    'from' => \Drupal::config('system.site')->get('mail')
  );

  switch ($key) {
    case 'forward':
      $message['subject'] = $params['title'];
      $message['body'][] = '<html><body>' . $params['message'] . '</body></html>';
      break;
  }
}

```

As you can see, I am setting the content type to *text/html* and that should tell the mail system to parse the content as an HTML, but this is not working for some reasons.

This is a testing email. All the HTML markup is not shown, but also not working.

```
Bassem thought you would like to see this page from the website. personal message Go to article [1] [1] http://myhost/node/81

```

# Answer
> 13 votes
Without any module it is not possible to send HTML emails. This is because the default plugin the `MailManager` class (which is a plugin manager) uses to effectively send emails contains the following code. (See PhpMail.php.)

```
public function format(array $message) {

    // Join the body array into one string.
    $message['body'] = implode("\n\n", $message['body']);

    // Convert any HTML to plain-text.
    $message['body'] = MailFormatHelper::htmlToText($message['body']);

    // Wrap the mail body for sending.
    $message['body'] = MailFormatHelper::wrapMail($message['body']);
    return $message;
  }

```

The comment clearly states: *Convert any HTML to plain-text.*

If you look at `MailFormatHelper::htmlToText()`, you will see the code that is converting the HTML markup in plain text, in particular the following that changes any `<a>` tag as you saw in your test email.

```
  // Replace inline <a> tags with the text of link and a footnote.
  // 'See <a href="https://www.drupal.org">the Drupal site</a>' becomes
  // 'See the Drupal site [1]' with the URL included as a footnote.
  static::htmlToMailUrls(NULL, TRUE);
  $pattern = '@(<a[^>]+?href="([^"]*)"[^>]*?>(.+?)</a>)@i';
  $string = preg_replace_callback($pattern, 'static::htmlToMailUrls', $string);
  $urls = static::htmlToMailUrls();
  $footnotes = '';
  if (count($urls)) {
    $footnotes .= "\n";
    for ($i = 0, $max = count($urls); $i < $max; $i++) {
      $footnotes .= '[' . ($i + 1) . '] ' . $urls[$i] . "\n";
    }
  }

```

You need a module that defines a new mail plugin using a different implementation of the `format()` method and make the `MailManager` class use it. As said in the documentation for `MailManager::getInstance()`, the class uses the configuration in system.mail.interface. (The array returned from `\Drupal::config('system.mail.interface')`.) In your example, an array value for *custom\_forward\_formard* (e.g. `'custom_forward_forward => 'custom_forward_mail'`, where *custom\_forward\_mail* is the plugin ID for the class implemented by your module) would do the trick.

# Answer
> 1 votes
The default mail module would not let you send html mail, but there is a hack for that. before assigning html variable to body please use PHP function htmlentities, it prevent html tags being removed from message. and you can get the html mail.

```
$message['body'][] =  htmlentities($msg);

```

this is for quick hack.. without altering any core codes.

---
Tags: 8, emails
---


# Question
Title: More information than standard "Site Details", also to be available as tokens
Is there a way to add additional fields to the config/system/site-information area such as **business owner**, **"business location"**, **"hours of operation"**, **"phone number"**, etc. I would then like to be able to use that information throughout nodes and blocks as tokens.

That way if the details change, they will change throughout the site. This is particularly handy when using token filter for document templates on uses for multiple sites, like privacy statements.

Is this possible, or is there another way to add this functionality?

# Answer
> 3 votes
I wrote a tutorial on most of this: http://www.jaypan.com/tutorial/drupal-8-extending-core-configuration-extending-core-forms-and-overriding-core-routes

I didn't get into creating tokens for the new items, but you can do it by implementing hook\_token\_info\_alter() and declaring the new tokens as part of the `site` tokens, and implementing hook\_tokens\_alter() to set the values from the config you create following the tutorial.

---
Tags: configuration, tokens
---


# Question
Title: How do I get translated label for a base field definition?
As mentioned here and here, there is a (complicated) way, to get can get a translated labels for bundle fields.

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

// Override language before loading field configuration.
$language = \Drupal::languageManager()->getLanguage('fr');
\Drupal::languageManager()->setConfigOverrideLanguage($language);

// $entity_type, $bundle, $field.
$field_info = FieldConfig::loadByName('entity_type', 'bundle', 'myField');

$label = $field_info->getLabel();

```

I however cannot find a way, how to achieve this for base fields. A hack like supplying a(any) bundle also leads to no success.

# Answer
There are two possible translation methods for a base field, interface translation and configuration translation.

Base fields are defined in code and translated by t(), which gets the translatable string from the core interface translation table.

```
$translatableMarkup = t($label, [], ["langcode" => $langcode]);
//optionally, render to string
$translatedLabel = $translatableMarkup->render();

```

If a base field override exists in configuration, then it contains a translatable label:

```
// Override language before loading field configuration.
$language = \Drupal::languageManager()->getLanguage('fr');
\Drupal::languageManager()->setConfigOverrideLanguage($language);

$field_override = BaseFieldOverride::loadByName('entity_type', 'bundle', 'myField');
if ($field_override) {
  $label = $field_override->getLabel();
}

```
> 4 votes

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


title: Metatag migration from html

text:
# Question
Title: Metatag migration from html
Drupal 8.8
Modules: Metatags & Migration plus.

I am trying to convert a tag in an XML file to an open graph image metatag.

**File: modules/custom/my\_module/dataxml.html**
*This is the url that has to be converted to the image metatag.*

```
<ImageUrl>
  <![CDATA[https://via.placeholder.com/300.jpg/09f/fff]]>
</ImageUrl>

```

**File: modules/custom/my\_module/config/install/migrate\_plus.migration.content.yml**
*These are the source field for the required metatag.*

```
source:
  fields:
     - name: og_image_url
       label: Image
       selector: ImageUrl

```

*Process for the required metatag*

```
process:
  field_meta_tags:
    source: og_image_url
    plugin: prepare_meta

```

**File: modules/custom/my\_module/src/Plugin/migrate/process/PrepareMeta.php**
*The plugin links the metatag with the required value and serializes the mapped result*

```
<?php

namespace Drupal\my_module\Plugin\migrate\process;

use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;

/**
 * Plugin to prepare the meta tags.
 *
 * @MigrateProcessPlugin(
 *   id = "prepare_meta",
 * )
 */
class PrepareMeta extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $metas = [];

    // This should likely work with an array later on, but for now, it'll do.
    if (!empty($value)) {
      $metas[$this->configuration['source']] = $value;
    }

    return $metas ? serialize($metas) : [];
  }
}

```

When I run xDebug $metas has the following value:
$metas = \[ og\_image\_url =\> "https://via.placeholder.com/300.jpg/09f/fff" \];

The node is created and the other field are migrated perfectly. However the metatag field og:image:url remains empty and doesn't trigger an error. I don't really know what I'm doing wrong here. If someone could point me in the right direction, that would be much appreciated.

# Answer
> 0 votes
Turns out I used the wrong field name. My field is called **field\_meta\_tag** instead of **field\_meta\_tags** as used in the question above.

---
Tags: 8, migrations, meta-tags
---


# Question
Title: Custom configuration forms: translation access denied
While creating custom configuration forms, I'm getting an access denied. But on the /translation page of the form only. Configuration form itself can be reached, filled and updated without problems.

Configuration does show up on the admin/config/regional/config-translation page but can't be translated for some reason.

Any idea's?

Overview of files:

**schema.yml**

```
faq.settings:
  type: mapping
  label: 'FAQ settings'
  mapping:
    faq_title:
      type: text
      label: 'Title'
    faq_text:
      type: text
      label: 'Text'
    faq_cta_label:
      type: text
      label: 'CTA label'
    faq_cta:
      type: text
      label: 'CTA'
...

```

**routing.yml**

```
aform.faq:
  path: '/admin/config/aform/faq'
  defaults:
    _form: '\Drupal\aform\Form\faqForm'
    _title: 'FAQ block'
  requirements:
    _permission: 'administer site configuration'
...

```

**config\_translation.yml**

```
aform.faq:
  title: 'aform FAQ'
  base_route_name: aform.faq
  names:
    - faq.settings
...

```

# Answer
> 1 votes
For anyone stumbling towards a similar problem: it seems you have to set-up not only schema, routing and config\_translations yml files but you also have to define each configuration in installation yml files so your config is picked up by Drupal.

So I had to include a faq.settings.yml file in /install of my custom module directory, like:

```
faq_title: ''
faq_text: ''
faq_cta_label: ''
faq_cta: ''
langcode: en

```

And boom you got yourself a translatable configuration form.

# Answer
> 0 votes
It can take quite a while until you get all the naming correct. For people struggling with this, we've published a module with a working example here: https://github.com/VITObelgium/drupal-boilerplate

---
Tags: 8, routes, users, configuration
---


# Question
Title: D8 How to create custom configurational form translatable?
I am new to Drupal 8 Custom Translation. I am working on a custom module with a backend form from where user can add some textual inputs.

The Site is multilingual, so I need to have this backend form translatable.

May I know the steps or any links from where I can get an idea where to start for translatable configuration form/page where user can add textual inputs for each languages.

Thanks in advance.

# Answer
You need a schema yaml file in the module folder `/config/schema` to make configuration forms translatable:

> ### What are schema files used for?
>
> 1. The primary use case schema files were introduced for is multilingual support. We need to have a tool to identify all translatable strings in your shipped configuration so when you ship with your own settings as well as default Views, additional user roles, menu items, etc. we can offer those up for translation as part of your module/theme release on http://localize.drupal.org. The nesting levels and types would be enough for this use case.
> 2. We also use schemas to provide actual translation forms for configuration based on your data. This use case is where types gain more importance and labels become crucial. The core *Configuration translation* module uses schemas to generate translation forms and save translations. The two most important built-in translatable types are 'label' for one-line text input and 'text' for multiline text input.

Source: https://www.drupal.org/node/1905070
> 5 votes

# Answer
It can take quite a while until you get all the naming correct. For people struggling with this, we've published a module with a working example here: https://github.com/VITObelgium/drupal-boilerplate

> This module provides an example of how to create a configuration form in a custom module and make it translatable out-of-the-box.
> 3 votes

---
Tags: 8, forms, i18n-l10n
---


# Question
Title: How to display entity label using entity reference field checkbox form display
I am working with Drupal 8. And I want to create a field of entity\_reference type. The field has a reference to context\_question entity. And the field is displayed fine, but without any description beside the check boxes.

The context\_question entity has a label field and I want exactly the label be displayed beside the checkbox in my first entity. What should I change in the code? Or do I need to create the fieldFormatter?

```
$fields['context_question'] = BaseFieldDefinition::create('entity_reference')
  ->setLabel(t('Context Question'))
  ->setDescription(t('Reference to context-question-type'))
  ->setSetting('target_type', 'context_question')
  ->setDisplayOptions('view', array(
    'label' => 'above',
    'format' => 'label',
    'weight' => 15,
  ))
  ->setDisplayOptions('form', array(
    'type' => 'options_buttons',
    'weight' => 15,
  ))
  ->setCardinality(1000)
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE);

```

# Answer
> 0 votes
I assume the `context_question` is your custom entity or coming from a contrib module?

There are two options:

1. Add `label` key to `context_question` entity definition under `entity_keys` so that `Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection` pick it up. See Aggregator item for reference.
2. Add a `@EntityReferenceSelection` plugin. You have to define one. Check TermSelection for how it is implemented for terms. It looks like this:

---
Tags: 8, entities
---


# Question
Title: AJAX ReplaceCommand executes as expected only on first iteration
**Expected Output:**

1. User triggers remove item button.
2. Program updates database.
3. Form gets rebuild with updated information from the database.
4. AJAX replaces the old information with new information from buildForm.

**Actual Output:** The expected output only occurs on the first iteration. If the user triggers remove item button on another item. The database will get updated. But the AJAX is not executed.

I'm still learning the Drupal AJAX system, I don't understand why this works for only one iteration.

**buildForm:**

```
//get information from shopping cart table
        $cart = new \Drupal\pps_shopping_cart\Controller\ShoppingCart();
        $items = $cart->getShoppingCartItems();

        //display review order
        if($step === 1)
        {
            //generate table structure
            $form['table'] = [
                '#type' => 'table',
                '#header' => [
                    $this->t("Image"),
                    $this->t("Manufacturer Part Number"),
                    $this->t("Order QTY"),
                    $this->t("Unit Price"),
                    $this->t("Remove")
                ],
                '#empty' => $this->t("You don't have any items in your cart.")
            ];

            $index = 0;
            foreach($items as $record)
            {
                $imgURL = $cart->getImageUrlByPartNumber($record->pno);
                $form['table'][$index]['image'] = [
                    '#type' => 'container',
                    '#markup' => "<img src='{$imgURL}' alt='{$record->pno}' width='200px' height='200px'>"
                ];

                $form['table'][$index]['pno'] = [
                    '#type' => 'label',
                    '#title' => $record->pno
                ];

                $form['table'][$index]['pno']['reference'] = [
                    '#type' => 'hidden',
                    '#value' => $record->pno
                ];

                $form['table'][$index]['qty'] = [
                    '#type' => 'number',
                    '#default_value' => $record->qty,
                    '#min' => 0,
                    '#max' => $cart->getCustomerAvlQty($record->pno)
                ];

                $form['table'][$index]['price'] = [
                    '#type' => 'label',
                    '#title' => '$' . number_format($record->price, 2)
                ];

                $form['table'][$index]['remove'] = [
                    '#type' => 'submit',
                    '#name' => $record->pno,
                    '#value' => $this->t("Remove"),
                    '#validate' => ['::validateRemoveItem'],
                    '#submit' => ['::submitRemoveItem'],
                    '#ajax' => [
                        'callback' => [$this, 'ajaxRemoveItem'],
                        'wrapper' => 'edit-table'
                    ]
                ];

                $index++;
            }

            if($index > 0)
            {
                $form['actions'] = ['#type' => 'actions'];
                $form['actions']['review'] = [
                    '#type' => 'submit',
                    '#value' => $this->t("Review Order"),
                    '#validate' => ['::validateReview'],
                    '#submit' => ['::submitReview']
                ];

                $form['actions']['save'] = [
                    '#type' => 'submit',
                    '#value' => $this->t("Save"),
                    '#validate' => ['::validateSaveOrder'],
                    '#submit' => ['::submitSaveOrder'],
                    '#ajax' => ['callback' => [$this, 'ajaxSaveOrder']]
                ];
            }
        }

```

**submitRemoveItem:**

```
 $cart = new \Drupal\pps_shopping_cart\Controller\ShoppingCart();

 $cart->removeFromCart($form_state->getTriggeringElement()['#name']);
 $form_state->setRebuild();

```

**ajaxRemoveItem:**

```
        $response = new AjaxResponse();
        $response->addCommand(new ReplaceCommand('#edit-table', $form['table']));
        $response->addCommand(new OpenModalDialogCommand($this->t("Removing Item from Cart"), $this->t("@item: has been removed from your shopping cart!", ['@item' => $form_state->getTriggeringElement()['#name']])));
        return $response;

```

# Answer
> 1 votes
I'm missing something like

`$form['table']['#attributes']['id'] = 'edit-table';`

in your code. You are telling Drupal's Ajax to replace the DOM element with id `edit-table` with the HTML output of `$form['table']`. In the 2nd iteration it can't find the DOM element to replace anymore, so nothing happens

# Answer
> 0 votes
Drupal rewrites the form element IDs when it rebuilds the form so you have to explicitly set the form ID in the returned form element.

https://www.drupal.org/docs/8/api/javascript-api/ajax-forms#s-render-array

"The returned array replaces the element with the ID specified by the wrapper element (#edit-output). This is important to remember when deciding what to return from the callback! Whatever was specified by the given ID is completely replaced by the new HTML! Make sure that the returned field also contains the id #edit-output or the next AJAX callback will not find a target to place the rendered code into."

---
Tags: 8, ajax
---


# Question
Title: Why are non-required fields still showing up in my node_edit template using Page Manager
I am stumped. Certain fields are NOT required and yet they still show up if I add the *base form* to a `node_edit` variant in Page Manager (**Node add/edit form**).

# Answer
> 0 votes
## And I finally found out why:

If the user who's accessing this `node_edit` form variant has the right to update this field even if it's not required and you didn't add it to the form, it will show up as part of the base form in **Node add/edit form** *(Home » Administration » Structure » Pages)*

Hope that helps someone else too.

---
Tags: 7
---


# Question
Title: "drush sapi-i" command which calls drush_backend_batch_process() fails with "Output is empty"
I am trying to integrate `ElasticSearch` with `Drupal` and till now everything seems to be working except that the command `drush sapi-i` crashes with the output:

```
> 'C:/xampp/htdocs/my-project/docroot/vendor/bin/drush' is not recognized as an internal or external command,
> operable program or batch file.

In ProcessBase.php line 172:

  Output is empty.

search-api:index [--limit [LIMIT]] [--batch-size [BATCH-SIZE]] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-d|--debug] [-y|--yes] [--no] [--remote-host REMOTE-HOST] [--remote-user REMOTE-USER] [-r|--root ROOT] [-l|--uri URI] [--simulate] [--pipe] [-D|--define DEFINE] [--druplicon] [--notify [NOTIFY]] [--xh-link XH-LINK] [--] <command> [<indexId>]

```

After debugging with `drush sapi-i -d` it seems the call to `drush_backend_batch_process()` causes the issue for some reason.

# Answer
> 0 votes
After checking the `vendor/bin` directory I noticed that the `drush` script exists but `drush.bat` or `drush.cmd` were missing, I mean, for some reason even though I executed the `drush sapi-i` command using Git-bash, `Drupal` was still trying to access the `Windows` type of the file (which didn't exist in the source I copied from `Mac`). so creating the below file manually fixed the issue.

### `drush.cmd` file:

```
@echo off
setlocal DISABLEDELAYEDEXPANSION
php "%~dp0../drush/drush/drush" %*

```

### `drush` file:

```
#!/usr/bin/env sh

dir=$(cd "${0%[/\\]*}" > /dev/null; cd '../drush/drush' && pwd)

if [ -d /proc/cygdrive ]; then
    case $(which php) in
        $(readlink -n /proc/cygdrive)/*)
            # We are in Cygwin using Windows php, so the path must be translated
            dir=$(cygpath -m "$dir");
            ;;
    esac
fi

"${dir}/drush" "$@"

```

**Note** that the `drush` script's line ending should be LF (instead of CRLF which `drush.cmd` needs), so in Git-bash simply `cd` to where your script is and run `sed -i 's/\r$//' my-script-filename` (if your editor can only save with CRLF).

---
Tags: search, drush
---


# Question
Title: How to programatically change image style of images gathered by view?
I have a view that collect fields of some content type and one of those fields is image field. I can set image style for that image from view editing page and that image in every row will have that same image style.

Now I need to set different image style for some rows. I.e. first row image should have style "ep1", second "ep2" and third and fourth "ep3".

What I tried so far is pre-processing image field like this:

```
function hook_preprocess_views_view_field(&$variables)
{
  $view = $variables['view'];
  $field = $variables['field'];

  switch ($view->id()){
    case 'view_id':
      switch($field->field) {
        case 'image_id':
          $rowIndex = $variables["field"]->view->row_index;

          $variables['field']->options["settings"]["image_style"] = 'thumbnail';
          break;
      }
      break;
  }
}

```

This way I can collect row number, but setting this "thumbnail" style is not working. On front-end I'm still getting image style set from view.

Then I tried preprocessing image formatter like this:

```
function cr_common_preprocess_image_formatter(&$variables) {
  if ($variables['image']['#style_name'] === 'style_to_change') {
    $variables['image']['#style_name'] = 'thumbnail';
  }
}

```

And this way style really is changed, but I don't' have info on current view row so it can be used only for setting random image styles or something.

# Answer
> 1 votes
You could try a different approach, via the Views UI, adding the same image field 3 times, and assigning each of these different image styles.

Add a `View result counter` field, this will let you know the row number.

Then on template/twig file print image field that was assigned x image if `counter` <sub>(this is the twig variable name for View result counter)</sub> equals y.

---
Tags: views, 8
---


# Question
Title: Is there any way to disable a module and the modules which depend on it?
Is there any way to disable a module and the modules which depend on it with Drush?

Let's say I need to disable the Views module, but I enabled the *Views Accordion* module as well. If I run `drush pm-disable views`, it does not disable the Views module.

# Answer
> 31 votes
You should update your Drush by the sounds of things. Doing `drush dis views` should result in the following:

> The following extensions will be disabled: views, views\_bulk\_operations, og\_ui, views\_content, og\_example, views\_php, views\_ui
> Do you really want to continue? (y/n)

Which means the dependents are disabled at the same time.

# Answer
> 1 votes
In Drupal 8, we can uninstall a module with `drush pm:uninstall oauth2`, for example.

---
Tags: drush
---


title: How to link to a file in twig template

text:
# Question
Title: How to link to a file in twig template
I'm trying to link to a file in a view. I have a field in the view that outputs the link if I use it like this:

```
<div class="product-cta-view-pdf">
  {{ fields.field_notice.content }}
</div>

```

The output: /sites/default/files/products/notice/test.pdf

What I want to do is use that to create a link to the pdf to view (and another one to download). How can I use this in the href of a link?

# Answer
> 0 votes
You can use the drupal build in file\_url twig function for that:

```
{{ file_url( fields.field_notice.content) }}

```

You can find more information about the Drupal build in twig functions here:

https://www.drupal.org/docs/8/theming/twig/functions-in-twig-templates

---
Tags: views, theming, uri
---


# Question
Title: How can I tell Drupal to add autocomplete=off to the login form
I'm under pressure to close out some issues from a Qualys scan. One issue flagged was

> 150112 Sensitive form field has not disabled autocomplete

Suggestions include adding `autocomplete="off"` to the username and password fields.

What would be the best practice way to achieve this?

# Answer
It seems there is a module for this, No Autocomplete. As a sidenote (copied from the module's page:

> However, browsers and password managers and the like may very well not respect the "autocomplete=off" attribute anyway. For example, Chrome seems no longer to respect it and Lastpass ignores it by default.

Well, good luck with Qualys!
> 3 votes

# Answer
Use `hook_form_alter()` in a Drupal module:

```
function hook_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_login') {
    $form['pass']['#attributes']['autocomplete'] = 'off';
  }
}

```

Or use jQuery:

```
$('#edit-password').attr('autocomplete', 'off');

```
> 1 votes

# Answer
You can set the attribute autocomplete='off' in **username** and **password** field of login page ***hook\_form\_alter()***

> Tested on Drupal 8 using **hook\_form\_alter()**

```
function hook_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_login_form') {
    $form['name']['#attributes']['autocomplete'] = 'off';
    $form['pass']['#attributes']['autocomplete'] = 'off';
  }
}

```
> 1 votes

---
Tags: 7, users, forms
---


# Question
Title: Selected/Restricted Autosubmit with Better Exposed Filters in Drupal
I'm using the Better Exposed Filters module to manipulate the filters in my view. It works great except for one issue that's affecting the whole layout.

Within my view I have four exposed filters out one is a Search (*Search Terms*). The auto submit works perfectly with the checkboxes filter but makes the search unusable. It basically submits it on every keypress and that hinders writing the complete word.

Is it possible, that I could have autosubmit on all filters except one (*Search Terms* filter)?

# Answer
The auto-submit feature is a part of the Views module. It relies on the auto-submit CTools behavior. This plugin disables auto-submit for form elements that have the CSS class `ctools-auto-submit-exclude`. You can embed this JavaScript within the form header to disable auto submission on text fields.

```
jQuery(document).ready(function() {
  jQuery('div.views-exposed-form input[type="text"]').addClass('ctools-auto-submit-exclude');
});

```

You can adjust your jQuery selector accordingly for other form elements.
> 3 votes

# Answer
The documentation in CTools suggests adding the class `ctools-auto-submit-exclude` in the element `#attributes` key for the form element you don't want to processed:

```
function MODULE_search_submission_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == "views_exposed_form") {
    if (isset($form['keys'])) {
      $form['keys']['#attributes']['class'][] = 'ctools-auto-submit-exclude';
    }
  }
}

```
> 6 votes

# Answer
Below code will exclude the autocomplete in Drupal 8.

```
$form['keys']['#attributes'] = ['data-bef-auto-submit-exclude' => ''];

```
> 1 votes

# Answer
For Drupal 8 better exposed use data attribute to exclude an item :

```
$form['keys']['#attributes']['data-bef-auto-submit-exclude'] = '';

```
> 0 votes

---
Tags: search, views
---


# Question
Title: How can I access all values of a multi-value field?
I am using Drupal 8 for a project for learning purposes. In my case I want to access to a field which contains multiple values, but I can't find how to do that. For example for a single value field I can access it like this:

```
kint($variables['node']->field_name->value);

```

But how can I get all the values of field which allows more than one value?

# Answer
> 3 votes
To get all values of a multi-value field:

```
$node = $variables['node'];
$values = array();
foreach ($node->field_name->getValue() as $value) {
  if (!empty($value['value'])) {
    $values[] = $value['value'];
  }
}

```

OR

```
$node = $variables['node'];
$values = array();
foreach ($node->field_name as $item) {
  if (!empty($item->value)) {
    $values[] = $item->value;
  }
}

```

---
Tags: 8
---


title: Missing "view mode" permission in core

text:
# Question
Title: Missing "view mode" permission in core
## Context

* Drupal 8
* Switching to Drupal for intranet site in large organization

## Background

OtraganixLocker Corporation is switching to Drupal from a custom-made home-grown intranet site. They want to use D8.

The problem is, the old custom-made intranet had the following permissions for (its equivalent of) D8 nodes:

* add content
* edit own content
* edit any content
* delete own content
* delete any content
* view own content
* view any content

Moreover, the granularity of the permissions worked down to the "content-type" level on the old intranet.

Moreover, the granularity of the permissions on the old intranet permitted user-based-assignment as well as role-based-assignment.

## Question

Drupal 8 seems to be missing the `view own content` and `view any content` permissions that the old intranet system had.

Moreover, there seem to be a lot of ways to handle this, at least in D7.

* Is this missing functionality accounted for in D8 core and simply missing from the front-end interface, or is it also absent from D8 core?
* If it is not absent from D8 core, which specific function or functions in the D8 API account for this functionality?

## See also

# Answer
The node access control methods between Drupal 7 and Drupal 8 are largely the same and described in Node access rights. There are still the same hooks, just some of the plumbing is different.

So, if you want to implement the Drupal 6 fine grained access in Drupal 8, you can either do `hook_node_access()` or proper grants. Remember, node usage can exist in case other than the node pages (eg, lists); the node access system takes care of this. Work has begun on the ACL module and dependencies which provide some abstractions for these.

Drupal 8 also has a new concept for route access. It uses classes that implement `AccessInterface`, and then use YAML configuration for providing the `requirements` for the route. Looking at how routing is set up for the code node module (which defines the `Node` entity), may be the best starting point for delving into this, though it uses the same Access classes as the node acccess system. I think explaining it here may be too much.
> 2 votes

# Answer
There is a module doing exactly that https://www.drupal.org/project/node\_view\_permissions.
> 0 votes

---
Tags: 8, users
---


title: Dynamic about us page

text:
# Question
Title: Dynamic about us page
I'm fairly new to Drupal and have this task to create an about us page. Now every customer has two certain co-workers assigned to him. This information is stored in the database. I want to show the two co-workers depending on the customer that is signed in. Someone said that I need to create a custom content type, but i couldn't find anything about it online. What would be the best approach to this problem?

# Answer
> 4 votes
Sounds like you need to use Views with a contextual filter based on the logged in user and a relationship from the user to the coworkers

---
Tags: 8
---


title: Delete confirmation as popup

text:
# Question
Title: Delete confirmation as popup
I have a view containing saved user webform drafts set up in a table format. I have given permission to the authenticated user to delete own submissions. When clicking the delete link located on the table it redirects user to a separate page asking "Are you sure you want to delete this submission?" I'd like to accomplish one of two things.

1. Have no delete confirmation, when the user clicks delete it is immediately deleted. *Preferred*
2. Have the delete confirmation page as a pop up.

I'm new to coding drupal modules but I believe I have isolated the code to be found within the webform.submissions.inc folder, line 465 - 467:

$question = t('Are you sure you want to delete this submission?');

return confirm\_form($form, NULL, "node/{$node-\>nid}/submission/{$submission-\>sid}", $question, t('Delete'), t('Cancel'));

Any help would be appreciated, I have searched and researched and keep coming to the same results.

# Answer
Use the hook\_form\_alter hook, check which form you're on and what the current action is, then remove the node and redirect to where you want to go.

https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook\_form\_alter/7.x

Here's my D8 code, should be fairly similar in D7:

```
<?php

function my_module_name_form_alter(&$form, $form_state, $form_id)
{
  if ($form_id == 'node_mynodename_delete_form') {
    // write code here to delete the node and redirect
  }
}

```

This code goes into the .module file.

Replace `my_module_name` with the name of your own custom module.

Replace `mynodename` with the machine name of your node.

There are plenty of examples out there on how to programmatically remove a node and redirect.
> 0 votes

---
Tags: 7, forms
---


# Question
Title: Searching entity reference field value with Search API
I am using Seach API, Solr Search modules in my website for searching. I've created an index, say 'Blogs index', I've selected blogs content type to index Fields - title, body, Author are added to index.

Created the View for the search results.

Issue is when I search the name of the author, I'm getting no relevant results. Result should be the list of blogs written by the searched author.

field Author is an entity reference field referencing the content type 'Blog Author' and is a multi-valued field. Any help is appreciated.

# Answer
> 1 votes
To allow `nested` Facet searches, based on referenced entity's titles (`$target->field_title->value`), in our Drupal 8 site we defined a custom-field with a processor
(which create and sets our `my_titles_field` field);

Place the `MyCustomProcessor.php` file in `modules/custom/my_module/src/Plugin/search_api/processor/` directory;

With contents like below:

<?php

namespace Drupal\my_module\Plugin\search_api\processor;

use Drupal\Core\Entity\EntityInterface;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Item\Field;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Plugin\PluginFormTrait;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;

/**
 * Allows finding by titles associated (with field_references entities).
 *
 * @SearchApiProcessor(
 *   id = "my_custom_processor",
 *   label = @Translation("My Custom Processor"),
 *   description = @Translation("Allows filtering by entity-reference's titles."),
 *   stages = {
 *     "add_properties" = 0,
 *   },
 *   locked = true,
 *   hidden = true,
 * )
 */
class MyCustomProcessor extends ProcessorPluginBase {

  use PluginFormTrait;

  const ENTITY = 'node';
  const DATASOURCE = 'entity:' . self::ENTITY;
  const FIELD_NAME = 'my_titles_field';

  /**
   * {@inheritdoc}
   */
  public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
    $properties = [];

    // Ensures our field is in General section, else we would check:
    // ```
    // if ($dataSource && $dataSource->getEntityTypeId() == self::ENTITY) {
    // ```

    if (!$datasource) {
      $property = new ProcessorProperty([
        'label' => $this->t('Entity-title'),
        'description' => $this->t('Attached Entity-ref title list'),
        'type' => 'object',
        'is_list' => FALSE,
        'hidden' => FALSE,
        'processor_id' => $this->getPluginId(),
      ]);
      $properties[self::FIELD_NAME] = $property;
    }

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function addFieldValues(ItemInterface $item) {
    // Loads actual entity (which $item represents).
    $entity = $item->getOriginalObject()->getValue();
    if (!($entity instanceof EntityInterface)) {
      return;
    }

    // Generate searchable JSON object (that is returned to Search-API callers
    // and which we can edit as we like to fit our needs).
    $json = [];
    $references = $entity->get('field_references');
    foreach ($references->referencedEntities() as $key => $target) {
      $json[$target->id()] = [
        'value' => $target->field_title->value,
      ];
    }

    // At last, assign our custom filter-criteria value as an index field.
    $fields = $item->getFields(FALSE);
    $fields = $this->getFieldsHelper()
      ->filterForPropertyPath($fields, NULL, self::FIELD_NAME);
    foreach ($fields as $field) {
      $field->addValue($json);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function preIndexSave() {
    // For General fields:
    $this->ensureField(null, self::FIELD_NAME);

    // For content this would look like:
//    foreach ($this->index->getDatasources() as $sourceId => $dataSource) {
//      if ($dataSource && $dataSource->getEntityTypeId() == self::ENTITY) {
//        $this->ensureField($sourceId, self::FIELD_NAME);
//      }
//    }
  }
}

**Note** that the field needs to added to your `index` by clicking `Add fields` in `/admin/config/search/search-api/index/__my_index__/fields` route manually.

For Drupal-7 See also Cross-entity searches

# Answer
> 0 votes
I haven't tried this with Search API but if your "Author" is a separate content type and not the actual default Author field you need to add the Relationship for that Entity reference field (for the "Blog Author" content type).

Different Content types store data in different database tables. Relationships introduce that other table data into your Views.

You'll probably have to add the Title field using that Relationship (which is, I presume, your blog author name), and include that field in the Search API settings so it gets searched.

Entity reference fields only store the ID of the referenced entity, so using them alone won't let you search the actual Title field text of the referenced entity. You can only do that through the Relationship and the relevant Title field (or however you named that field).

---
Tags: views, search
---


# Question
Title: Error "Public files directory Not fully protected" Appears in Nginx?
I'm wondering why this errors appear on my drupal site when I am using Nginx:

```
Public files directory  Not fully protected
See http://drupal.org/SA-CORE-2013-003 for information about the recommended .htaccess file which should be added to the sites/default/files directory to help protect against arbitrary code execution.
Error
Temporary files directory   Not fully protected
See http://drupal.org/SA-CORE-2013-003 for information about the recommended .htaccess file which should be added to the tmp directory to help protect against arbitrary code execution.

```

Any solution to this?

# Answer
> 2 votes
In the security advisory referenced in the error, it describes the specific vulnerability as "Code execution prevention (Files directory .htaccess for Apache - Drupal 6 and 7)" and recommends updates to your htaccess files in your files directory. Part of the recommended htaccess update is the following text:

```
# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  # Override the handler again if we're run later in the evaluation list.
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</files>

```

The SetHandler string is what Drupal is using to determine whether you've made this change or not. Even though you're using Nginx as your webserver, its still going to display this error until you've made this update. From the advisory again:

> To fix the code execution prevention vulnerability on existing Apache installations also requires changes to your site's .htaccess files in the files directories. Until you do this, your site's status report page at admin/reports/status will display error messages about the problem. Please note that if you are using a different web server such as Nginx the .htaccess files have no effect and you need to configure PHP execution protection yourself in the respective server configuration files.

I'm running a couple nginx servers as well and had to make these updates just to make these errors go away. I was curious how they were doing this check and found this in the modules/system/system.install file at line 284:

```
// Check for the string which was added to the recommended .htaccess file
// in the latest security update.
if (!file_exists($htaccess_file) || !($contents = @file_get_contents($htaccess_file))
|| strpos($contents, 'Drupal_Security_Do_Not_Remove_See_SA_2013_003') === FALSE) {
...

```

# Answer
> 0 votes
I made a core patch for users using non apache servers, you can find it here, maybe one day it goes into core https://www.drupal.org/project/drupal/issues/3117665

---
Tags: 7
---


# Question
Title: Config Export: How to store default value of taxonomy field?
When I define a field with taxonomy term fields, I can set a default value depending on the available terms. Since the terms themselves are content, they are not stored via configuration management. When I export the configuration on one server (e.g. development) and import it into a different server (e.g. stage), these values may differ. Especially two terms with the same value on the servers don't necessarily share the same `tid`.

When I set a default value in dev, then this value's `tid` maybe not be the same as on the stage server and thus no default value or a wrong default value might be chosen, if I insert a new content of the type that has that field.

How do I manage this?

# Answer
> 0 votes
I figured out the solution.

The value stored in the config/sync is not the `tid` of the taxonomy term, but the `uuid`. Because of this, I can just change the value of `uuid` column in `taxonomy_term_data` row of the dev's term to that of the stage's server without affecting the `tid` column.

---
Tags: 8, taxonomy-terms, configuration
---


title: CSS not work after applying ajax

text:
# Question
Title: CSS not work after applying ajax
I have a problem with css after applying ajax. I have an exposed form that I stylized. Before applying ajax it is: id="edit-field-price-value-min" After applying it changed to id="edit-field-price-value-min--8EHokPV5K8s"

Also similar codes with --RandomSymbols are added to others elements.

How can I use ajax whithout adding --8EHokPV5K8s ?

# Answer
> 1 votes
Use a class to target the element.

If this is in a view, you can add a class on the fields you need to target. You could also add a class to the view and use existing classes inside that view.

---
Tags: theming, ajax
---


# Question
Title: Deployment of full database dump still causes error
I want to deploy my local DB to a staging server.

The local DB dump was exported with all tables. Including the "cache\_" prefix table structures with no data exported.

After deployed to staging (with Jenkins), I got exceptions like Plugin missing error or field missing.

> Uncaught PHP Exception RuntimeException: "Unable to determine class for field type 'daterange' found in the 'field.storage.node.field\_date\_range' configuration" at /var/www/html/lightnest/releases/20200227152907/docroot/core/modules/field/src/FieldStorageConfigStorage.php line 164

I cannot run update.php or rebuild.php because this error will popup again. I also cannot run drush commands as I have no direct access to the staging.

Am I missing anything?

# Answer
You can run Drush commands remotely from another server using methods such as site aliases. https://docs.drush.org/en/master/usage/#site-aliases

So you might be able to run registry rebuild https://www.drupal.org/project/registry\_rebuild

which sometimes helps with class errors.
> 0 votes

---
Tags: database, deployment
---


# Question
Title: How can I add a product SKU field to the search filter for the orders view?
In the administrator interface, there is an *Orders* view which shows all orders. Within this view, I would like to add a *Product SKU* field to the search filter.

On the edit form for the Orders view, I clicked on the *Add* button shown for *Advanced » Relationship*, but I can't find any product or product variation entity there.

How can I add a product SKU field to the search filter for the orders view?

# Answer
Ok you all most did it !

first in the view you need to add the "Order item referenced from order\_items" relationship

in your view -\>advanced RELATIONSHIPS...

after this you can then add the "Product variation" relationship.

with the 2 relationships added to the view you can now add the exposed filter you require.
> 1 votes

# Answer
I just wanted to comment on here about what to do if you're using the D7 version and come across this post (like we did). Here's the two relationships you will need to add in order to have SKU as a filter:

Commerce Order: Referenced line items

Commerce Line item: Referenced products
> 0 votes

---
Tags: views, commerce
---


# Question
Title: How to set a yml sequence config value via drush cset
When the drupal config value (as defined in .schema.yml) is a sequence what is the correct syntax for `drush config-set` so that the value is a sequence not a simple string? For example, with the devel module `drush config-get devel.settings error_handlers` returns

`'devel.settings:error_handlers':
 1: 1`

So what is the syntax to set the value to `4: 4`. I have tried lots of combinations, such as 4:4 \[4:4\]. error\_handlers.4 4 but have not hit on the right way yet. I could not find any examples or documentation, so asking here. Thanks.

# Answer
Uh, I love riddles like this! And finally found a way!

---

You first have to delete the `error_handlers` config key.

```
$ drush -y cdel devel.settings error_handlers

```

And then set it again.

```
$ drush -y cset devel.settings error_handlers.4 4

```

Let's check.

```
$ drush cget devel.settings error_handlers
'devel.settings:error_handlers':
  4: 4

```

Yeah!

---

Just `drush -y cset devel.settings error_handlers.4 4` without deleting it first would just append it and you'd end up with `1: 1` and `4: 4` both.
> 3 votes

---
Tags: drush
---


# Question
Title: How to get height and width of image style?
We have a custom module `mymodule` where we call `mymodule_tokens` so that we can assign custom token values from the current node. These custom tokens are used to insert values in the Article's MetaTag fields.

**Problem**

When fetching the default value based on an Image Style (e.g. medium), I cannot get the Height and Width based on the Configuration for the Image Style. How can I get the height and width from the Image Style?

**What I have tried, but cannot get the height and width:**

```
function mymodule_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];
  $node = $data['node'];
  $node_image = $node->field_image;
  $field_image_style = 'medium';

  if($node_image->isEmpty()) {
    $field_info = FieldConfig::loadByName('node', 'article, 'field_image');
    $image_uuid = $field_info->getSetting('default_image')['uuid'];
    $image = Drupal::service('entity.repository')->loadEntityByUuid('file', $image_uuid);
    $field_image_url = ImageStyle::load($field_image_style)->buildUrl($image->getFileUri());
    $image_style = ImageStyle::load($field_image_style)->getEffects()->getConfiguration();

    // Both give me error messages.
    $image_style_height = $image_style->get('height');
    $image_style_width = $image_style->get('width');
  }
  else {
    $field_image_url = $node_field_image->entity->getFileUri();
    $image_style = ImageStyle::load($field_image_style)->getEffects()->getConfiguration();

    // Both give me error messages.
    $image_style_height = $image_style->get('height');
    $image_style_width = $image_style->get('width');
  }

  foreach($tokens as $name => $original) {
    switch ($name) {
      case 'custom_image_url':
        $replacements[$original] = $field_image_url;
        break;
      case 'custom_image_height':
        $replacements[$original] = $image_style_height;
        break;
      case 'custom_image_width':
        $replacements[$original] = $image_style_width;
       break;
    }
  }

  return $replacements;
}

```

**Error Message**

> Error: Call to a member function get() on array in mymodule\_tokens()

**When printing `ImageStyle::load($field_image_style)` using Kint this is what we get.**

**When printing `$image_style`, I get the following.**

**Using core or contrib tokens rather than custom tokens**

Using the following tokens only work when there is a value added to the `field_image` field, but when the `field_image` is not populated, the token is not able to return the default image that is populated on the field's settings page.

```
[node:field_image:medium:height]
[node:field_image:medium:url]
[node:field_image:medium:width]

```

# Answer
> 2 votes
You'll need to click on the Available Methods tab and see if there is an method for width and height.

When you click on it, searching for width or height should come up empty. I can tell this by looking at the ImageStyle Class.

But there will be a `getEffects()` method that you can use, which should contain the width and height.

```
$style = ImageStyle::load($field_image_style);

```

So do `kint($style->getEffects());`

I'll let you take it from here.

---

If you want to go the `$image_style` route then you can get the value with

```
$image_style[0]['1aa.......']['data']['width'];
$image_style[0]['1aa.......']['data']['height'];

```

**PS:**

I suggest you read my answer to What is easiest way to debug variables in nodes, views, blocks and page twig templates? to learn how to use kint properly.

# Answer
> 8 votes
If you wonder how to get the height/width of a rendered image style (not Image style configuration, but the result itself), here's how it's done :

```
<?php
use Drupal\image\Entity\ImageStyle;

$img_uri = $entity->field_picture->entity->getFileUri();
$image_style = ImageStyle::load('your_image_style');
// $build_url = $image_style->buildUrl($img_uri);
$build_uri = $image_style->buildUri($img_uri);
$image_factory = \Drupal::service('image.factory')->get($build_uri);

$height = $image_factory->getToolkit()->getHeight();
$width = $image_factory->getToolkit()->getWidth();

```

# Answer
> 4 votes
No Sssweat's answer inspired this.

I added this before if statement (`if($node_image->isEmpty())`) to get the height and width.

```
$image_style_config = (ImageStyle::load('medium')->getEffects()->getConfiguration());

foreach($image_style_config as $config) {
  if(isset($config['data'])) {
    if(isset($config['data']['height'])) {
      $image_style_height = $config['data']['height'];
    }
    if(isset($config['data']['width'])) {
      $image_style_width = $config['data']['width'];
    }
  }
}

```

---
Tags: 8, media
---


title: Problems with altering a form

text:
# Question
Title: Problems with altering a form
I'm wanting to alter the commerce cart page form.

By using `var_dump($form_id)` or chrome inspect I can see the id is `id="views-form-commerce-cart-form-orange-default-42"`. If I write my hook as :

```
function module_form_views_form_commerce_cart_form_orange_default_42_alter

```

I can see that I am altering the form. But this has been altered in my theme hence the extra bit on the id `orange_default_42`. If I do :

```
function testingstuffs_form_views_form_commerce_cart_form_alter

```

I cannot alter the form.

How do I hook into this form correctly / is there a correct way to find form ids?

# Answer
> 1 votes
The issue here is that there are probably two form IDs for the form. One is the `form_id`, and the lesser known one is the `base_form_id`. If a Drupal form is used more than once on a page, weird things come about. To get around this, form developers can set the form ID to be dynamic, so that each time the form is built, it's given a unique ID. Example:

```
class FooBarForm implements FormInterface {

  protected $id;

  public function __construct($type) {
    $this->id = $id;
  }

  public function getFormId() {
    return 'foo_bar_form-' . $this->id;
  }
}

class FooRouteController {

  public function fooBarForm(ContentEntityInterface $entity) {
    $form = new FooBarForm($entity->id());

    return \Drupal::formBuilder()->getForm($form);
  }
}

```

Forms can also implement BaseFormIdInterface, which requires them to implement BaseFormIdInterface::getBaseFormId(). The form ID returned from this hook will be the same for all instances of the form, and NOT dynamic.

```
class FooBarForm implements FormInterface, BaseFormIdInterface {

  protected $id;

  public function __construct($type) {
    $this->id = $id;
  }

  public function getFormId() {
    return 'foo_bar_form-' . $this->id;
  }

  public function getBaseFormId() {
    return 'foo_bar_form';
  }
}

```

The relevance of this is that there are actually multiple form alter hooks called, in this order:

1. hook\_form\_alter()
2. hook\_form\_BASE\_FORM\_ID\_alter()
3. hook\_form\_FORM\_ID\_alter()

Looking at your hook - `module_form_views_form_commerce_cart_form_orange_default_42_alter`, it would appear you are implementing the third hook. The ID of 42 is being appended as part of the dynamic Form ID.

To find out the base form ID (if one exists), you can call the following in your form:

`$form_state->getBuildInfo()`

This will give you the build info, which you can dump with `kint()` or however you do your debugging. In the build info will be the base form ID (assuming it's set). If it is, you can implement the second form alter hook above, using that base form ID.

---
Tags: 8, forms, hooks
---


# Question
Title: Place the footer AND the copyright blocks at the bottom of the page responsive
I installed Industrial Theme from Zymphonies and I am struggling to place the footer and the copyright (2 block layouts) at the bottom of the page.

So, on my website it looks like that.

I tried a lot of methods but I do not know how to deal with 2 containers simultaneously.

# Answer
> 2 votes
If you are indeed looking to create a sticky footer, not sure what option this particular theme gives you but the idea is the same with any drupal theme

* Add both blocks to a region that you will dedicate for this purpose
* if no available region exists you can just create a new one
* using custom css on your theme you can make this specific region `position: fixed` but there are other ways as mentioned by No Sssweat

---
Tags: theming
---


# Question
Title: setErrorByName not working properly if field is in #details
In a form, some fields are defined in '#details':

```
$form['person2'] = [
  '#type' => 'details',
  '#title' => t('Person2'),
];
$form['person2']['lastname2'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Last Name'),
  '#size' => 32,
  '#default_value' => $this->store->get('lastname2') ? $this->store->get('lastname2') : '',
];
$form['person2']['firstname2'] = [
  '#type' => 'textfield',
  '#title' => $this->t('First Name'),
  '#size' => 32,
  '#default_value' => $this->store->get('firstname2') ? $this->store->get('firstname2') : '',
];
$form['person2']['email2'] = [
  '#type' => 'email',
  '#title' => $this->t('Email'),
  '#size' => 64,
  '#default_value' => $this->store->get('email2') ? $this->store->get('email2') : '',
  '#weight' => $weight,
];

```

In `validateForm()` I have some controls: if one of the fields has a value, the others should have one too.
I use `setErrorByName` but I can't have the faulty field highlighted in red, though the control fires as expected... Here is the code:

```
  if (!$form_state->getValue('firstname2')) {
    $form_state->setErrorByName('lastname2', $this->t('This field is required.'));
  }

```

# Answer
> 0 votes
Answer provided by Clive in comment is the correct one.

```
$form_state->setErrorByName('person2][lastname2', $this->t('This field is required.'));

```

Though if you just want to make the field required it would be better to do:

```
$form['person2']['lastname2'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Last Name'),
  '#size' => 32,
  '#default_value' => $this->store->get('lastname2') ? $this->store->get('lastname2') : '',
  '#required' => true,
];

```

---
Tags: 8, forms
---


# Question
Title: Missing tabs in Media Library widget in Drupal 8.8
I'm trying to set up Media Library widget in Drupal 8.8. But for some reason, no tabs are available for selection in the widget settings. Please see following screenshots:

Do I need to install some additional module? I wasn't able to discover any settings, which would allow me to do this.

# Answer
> 3 votes
This can happen when the field is not configured to reference any media types. It's a quirk of the underlying entity reference system that can be exposed under some circumstances.

The solution is to edit the field settings and ensure that the field is configured to reference at least two media types. (If only one media type can be referenced, the widget has no relevant settings to display.)

---
Tags: media
---


# Question
Title: Default customer profiles re-added on order edit, even without address field present
My site uses 2 custom profile types for a particular set of customers. For these, I have the default billing and shipping profile panes completely removed on the order edit screen via Customer Profile Type UI, yet any edit to an order (manual or programmatic) still re-adds them to the profile on save (resulting in 4 profiles for the order).

The address field has been identified as the culprit, but in my case, the default profile panes are not present in the form, so I don't understand how an address field that isn't there could trigger a new profile being added. Is there another mechanism in Commerce that would add default profiles if they are missing?

# Answer
I *think* the typical issue is that because the address field value includes a country code by default, it's always assumed to have data ... so my guess is that whatever mechanism the Customer Profile Type UI is using to disable those sections of the order edit form isn't actually unsetting or otherwise removing them from the forms themselves. I don't have experience with the module in question, but if you have the ability, you'd likely be better off writing your own form alter to disable those portions of the edit form.
> 0 votes

---
Tags: commerce
---


# Question
Title: Get the raw URL of an image in views-view-table.html.twig
In the `views-view-table.html.twig` template, I can get the raw values of fields by repeating on `rows` and accessing the `view` object. For example:

```
    {{ view.field.title.value(view.result[i]) }}   {# the title of the node in this row #}
    {{ view.field.field_link.value(view.result[i]) }}   {# the URL in the link field #}

```

With `Formatter` for an image field set to `URL to image` in the view, I can test to see if an image exists in the field by doing:

```
    {% if view.field.field_image.value(view.result[i]) %}

```

QUESTION: How can I get the raw URL for the image? If I use:

```
    {{ view.field.field_image.value(view.result[i]) }}

```

I get a number as output. I have tried:

```
    {{ view.field.field_image.value(view.result[i]).entity.uri.value }}   {# I get nothing #}

```

and various combinations of things, but haven't hit the right one.

I know I don't have to use the raw values. For example, I can use

```
    {{ row.columns.field_image.content|render|striptags|trim }}

```

to get the URL, but this seems like a lot of processing to get something that must be available in the raw result.

# Answer
> 1 votes
Thanks to all, especially @belltouche and @Jaypan, for taking the time to respond. After all the kind suggestions and lots of reading and trial-and-error, I ended up using the following code in `views-view-table.html.twig` to display an image URL:

```
{% for i, row in rows %}
  ...
  {% if view.field.field_image.value(view.result[i]) %}
    {{ row.columns.field_image.content|render|striptags|trim }}
  {% endif %}
  ...
{% endfor %}

```

Note that I'm using the `URL to image` formatter for the image field in the view.

To explain, `view.field.field_image.value(view.result[i])` gets the raw value of the image field, which turns out to be the entity id for the image. Checking it makes a concise test to see if there is an image in the field (if there's a better way, please say so).

It also turns out that there isn't any other information about the image in the raw value. Just the entity id, which is why I could never find the image URL in the raw value.

There was a suggestion made that I could use Twig Tweak to load the image entity by its id and get the URL from it. I'm sure this would have worked, but since my purpose was to avoid the overhead of `render|striptags|trim` processing, loading the entity after it had already been loaded to produce the content didn't seem an advantage.

# Answer
> 0 votes
For a custom Views Field template, you can access entity field values in the row with a dot structured format with something looks something like this: `row._entity.field_name.value` for the base entity, or `row._relationship_entities.field_name_that_brought_in_the_relationship.field_name_on_the_related_entity.value` when accessing something you brought in via Views' relationships. And I've gotten file uris with `file_url(...field_imagefieldname.entity.uri.value)`.

That being said, the comment about using `{{ dump(view.result) }}` is a good one.

---
Tags: views, 8
---


# Question
Title: For Each, set element's title to some string
Hi I have made a custom module to alter the address module form. It works well for one field, however I am stuck trying to use a for each loop in recursively calling this to as many elements there are.

My current code is as such:

```
function address_custom_address($element, $form_state) {
  $element[0]['address']['given_name']['#title'] = t('Base Name');
  $element[1]['address']['given_name']['#title'] = t('Base Name');
  $element[2]['address']['given_name']['#title'] = t('Base Name');
  return $element;
}

```

this works, however as you can tell it is redundant and does not satify cases in which the user creates more than 3+ addresses.

I tried to use a foreach loop

```
foreach($element as $value){
   $title = $value['address']['given_name']['#title']; //this is the title of each element
   //assert title not null
   if(isset($title)) {

      //this is the error it gives me
      $value['address']['given_name'] = array(
       '#title' => 'Base Name',
     );
   }
}

```

Error: Cannot use string offset as an array

If anyone has references to where i can better understand this, that would be very helpful. Thank you.

# Answer
> 1 votes
You're on the right track, but doing it slightly incorrect. You can use this:

```
function address_custom_address($element, $form_state) {
  $i = 0;
  while (isset($element[$i)) {
    $element[$i]['address']['given_name']['#title'] = t('Base Name');

    $i++;
  }

  return $element;
}

```

---
Tags: 8, entities, forms
---


# Question
Title: How to call custom javascript function defined in js file from .module file
I have some custom menu defined for which in the page callback function I want to execute some javascript function defined in some js file which is included in .info file.

The alert and console.log works as file is included on the page and loading successfully in browser, but custom js function not working. It says function is not defined.

.info file:

```
scripts[] = js/code_init.js

```

Here is my code in .module file:

```
function mymod_process_file(){

     $count = 2;
     for($i = 1; $i <= $count; $i++) {
     $file_path = "/abcd.html";

     echo "counter:$i";
     echo "<script language='javascript' type='text/javascript'>";
     echo "myFunction('".$file_path."', 'index_".$i."');";
     echo "</script>";
     }
     return 1;
}

```

# Answer
I have faced same kind of issue few days ago and I have resolved it by adding type as module to the script tag. All script with type=module have differ attribute. It download such js parallel with loading of other page and then run them in order but after the parsing is done.

This might help you:

```
<script language='javascript' type='module'>

```
> -1 votes

---
Tags: 7, javascript
---


# Question
Title: getting a target_id value for for users in particular node drupal 8
i want to display a taget\_id values for user in node's field but i can't print them , this is what I have done in the hook :

```
 $node = \Drupal::routeMatch()->getParameter('node');
  if ($node && $node->bundle() == 'MynodeType') {
    $members = $node->field_members->getValue();
    $members_ids = [];
    $current_user = \Drupal::currentUser();
    $user_id = \Drupal\user\Entity\User::load($current_user->id());

    foreach ($members as $member){
      $members_ids[] = $member['target_id'];
      echo $members_ids; // why this is not like (1,8,....)?
    }

```

# Answer
> 1 votes
Looks like this one has to be solved this way

```
  $members = $node->field_members;
  foreach ($members as $member) {
      $members_ids[] = $member->getValue()['target_id'];
  }

```

---
Tags: hooks
---


title: Automatically load pending draft

text:
# Question
Title: Automatically load pending draft
I'm using drupal 8 and webform module (multistep). In the webform submission settings, i enabled submit several drafts which adds the 'save' button for saving the progress. When the user logs out and logs in later on, a messsage to 'load pending draft' appears. In my settings, each user is allowed one submission. Is there a way to automatically load pending drafts without clicking on the link in the said message?

Appreciate any help given, thanks

# Answer
There is. When a user's saves draft a token gets generated. You need to get their token value.

```
$webform_submission = \Drupal\webform\Entity\WebformSubmission\WebformSubmission::load($sid);
$token = $webform_submission->getToken();

```

Then, you need to generate a URL like this

```
$draft_url = '/form/webform-name?token=' . $token

```

and on login redirect them to that url.
> 0 votes

---
Tags: webforms
---


# Question
Title: How to make exposed timestamp filter accept human readable date
I'm using Drupal 8. I created a new content type (title, body, image, date). The date is a **timestamp** field.

I used the devel module and the Realistic Dummy Content module to generate a test content for my view **test**.

I created my **test** view and chose the date as an exposed filter.

Here is my configuration:

And this is my view:

When I apply my filter, I want to say all contents having a date **greater than** my input:

If I test with **01/31/2018 - 02:54**, nothing was changed!

But If I test with the unix value: **1538323253**, my filter works well!

Any idea please to make the filter with human readable value?

# Answer
I ran into this issue on D7. I enabled the views query and noticed that the values were being passed as human date to the query rather than timestamp.

So what I did was use hook\_views\_query\_alter and converted them to timestamp.

Example code (D7 code)

```
function mymodule_views_query_alter(&$view, &$query) {
  if ($view->name == 'list_employers') {
    foreach ($query->where[1]['conditions'] as $con_key => $con_val) {
      if ((strpos($con_val['field'], 'node.created = ') !== FALSE) &&
        empty($con_val['value'])) {
        $date = $con_val['field'];
        $date = str_replace('node.created = ', '', $date);
        $date = date('m/d/Y', $date);
        $start = strtotime($date . ' 12:00 AM'); // convert to timestamp
        $end = strtotime($date . ' 11:59 PM'); // convert to timestamp
        unset($query->where[1]['conditions'][$con_key]['value']); // remove default condition
        $query->where[1]['conditions'][$con_key]['field'] = 'node.created';
        $query->where[1]['conditions'][$con_key]['value'][0] = $start;
        $query->where[1]['conditions'][$con_key]['value'][1] = $end;
        $query->where[1]['conditions'][$con_key]['operator'] = 'BETWEEN';
      }
    }
  }
}

```
> 2 votes

# Answer
As mentioned before you have to enter a UNIX time into the text field.

If you want to use a date picker in the exposed filter in Drupal 8 have a look at this issue (currently there is a patch for that):

https://www.drupal.org/project/drupal/issues/2648950
> 2 votes

# Answer
https://www.drupal.org/project/date\_popup

This will add the native HTML 5 date popup widget to all date fields in views filters.

But this module won't work with timestamp fields.
> -3 votes

---
Tags: views, 8
---