# Question
Title: What's the difference between the container and html_tag render elements?
What is the difference between render elements of #type html\_tag (set to div) and container in Drupal 8?

Is the container render element, a simpler version of html\_tag? Easier for processing to preprocess container elements?

I note that:

Perhaps my theories are correct (easier to leave be for historical reason / form element reasons)?

PHP:

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

  $variables['myhtml_tag'] = [
    '#type' => 'html_tag',
    '#tag' => 'div',
    '#attributes' => [
      'class' => 'my-container-class1',
    ],
    'child' => [
      '#markup' => new TranslatableMarkup('Some Container text1.'),
    ],
  ];

  $variables['mycontainer'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => 'my-container-class2',
    ],
    'child' => [
      '#markup' => new TranslatableMarkup('Some Container text2.'),
    ],
  ];

```

HTML:

```
<div class="my-container-class1">Some Container text1.</div>

<div class="my-container-class2">Some Container text2.</div>

```

# Answer
> 4 votes
I did "Blame" on the 7.x system.module after I didn't found a clue of `'container'` in the 6.x branch. In the "Blame" you can see that Dries himself committed the patch that introduced `$types['container']` in 2010 and that it leads back to the following issue on drupal.org:

The issue which introduced `#states` to the **Form API**! Now let's scan the page for "container". Okay, comment #36 explains quite a bit of the reason why it was introduced:

> As discussed with kkaefer and tha\_sun, we switched the "wrapper" Form API element type to "container" to not get too confused with other "wrapper" stuff, like "wrapper\_callback", "theme\_wrappers", etc. The "container" type still uses the CSS class of "\*-wrapper" though, to match with the rest of the Drupal coding standards.

And in the commit itself you then can see how `container` elements already replace some `markup` elements (`markup` being the default if `#type` omitted) which had `'#prefix' => '<div>', '#suffix' => '</div>` with hardcoded HTML.

To make it short: Container is a classical wrapper. And more of a **form element**. Whereas `html_tag` is more of a **render element**, traditionally used for void elements, often in the HTML `<head>`. Like placing meta tags or placing JavaScript and CSS libraries in script tags.

# Answer
> 4 votes
Good question. The way I see it, the container is a simple way to wrap things in a `<div>`. This is useful to add structure to forms, but also very useful for other situations where you need to build larger render arrays. I often use it like this (simplified example) because it makes your code clearer:

```
$build['wrapper'] = [
  '#type' => 'container',
  '#attributes' => ['class' => ['select-wrapper']],
];

$build['wrapper']['select'] = [
  '#type' => 'select',
  '#title' => $this->t('Select'),
  '#options' => $options,
  '#empty_option' => $this->t('- Select an option -'),
];

```

Also, the fact that a container doesn't require additional settings makes it suitable for and often used in the #theme\_wrappers property like this:

```
$form['description'] = [
  '#markup' => $description,
  '#theme_wrappers' => ['container'],
];

```

Personally, I only use the html\_tag type for simple elements other than a div, for instance:

```
$build['heading'] = [
  '#type' => 'html_tag',
  '#tag' => 'h2',
  '#value' => 'My Title',
];

```

Hope that helps!

# Answer
> 2 votes
The container element makes most sense in a form. It can be arranged in groups, it can be made optional and the ID, if missing, is auto-generated.

---
Tags: 8, theming
---


# Question
Title: How to issue 404 from a KernelEvents::REQUEST event
I'm trying to issue a 404 from a KernelEvents::REQUEST event, but it's resulting in the following error:

```
Fatal error: Maximum function nesting level of '256' reached, aborting! in /var/www/vendor/symfony/http-foundation/HeaderBag.php on line 162

```

Here's my class

```
<?php

namespace Drupal\my_module\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;

class MyClass implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['my404Check'];

    return $events;
  }

  public function my404Check(GetResponseEvent $event) {
    // Do some logic here to check if it should be a 404.
    throw new NotFoundHttpException();
  }

}

```

I'm guessing I can't throw exceptions here, but can't see any other documentation on how to issue the 404.

# Answer
You can set a response early in a request event:

```
 public function my404Check(RequestEvent $event) {

    // only return a response for a master request
    if (!$event->isMainRequest()) {
      return;
    }

    // Do some logic here to check if it should be a 404.

    $response = new Response('', Response::HTTP_NOT_FOUND);
    $event->setResponse($response);
  }

```

The event dispatcher checks if a response is already set and returns this response without executing any more code to build a Drupal response.

(Code updated for D9/10)
> 6 votes

# Answer
I would like to post another solution, that I have found in the Rabbit Hole module:

```
public function my404Check(GetResponseEvent $event) {
  // Don't process events with HTTP exceptions - those have either been thrown
  // by us or have nothing to do with this module.
  if ($event->getRequest()->get('exception') != NULL) {
    return;
  }

  // Do some logic here to check if it should be a 404.

  $response = new Response('', Response::HTTP_NOT_FOUND);
  $event->setResponse($response);
}

```

The event dispatcher skips processing if request has an exception already. In addition you can check the exception type.
> 1 votes

# Answer
I know this is old, but in case someone else finds this... setting the response was not enough for me, I still ended up with the same 'fast 404' error page, even when checking for the master request (I cleared cache). I also would prefer to simply throw the `NotFoundHttpException` like anywhere else in my code rather than create the response manually.

With this approach, I simply 'transform' the exception I'm catching from the event into a the `NotFoundHttpException`. Note that I use a priority higher than core's `ExceptionLoggingSubscriber` to avoid double logging of the exception.

```
  /**
   * {@inheritdoc}
   *
   * Use priority > 50 to run before core's ExceptionLoggingSubscriber.
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::EXCEPTION][] = ['onException', 60];
    return $events;
  }

  /**
   * Return a 404.
   *
   * @param GetResponseForExceptionEvent $event
   */
  public function onException(GetResponseForExceptionEvent $event) {
    $e = $event->getException();
    if ({{CUSTOM LOGIC HERE}}) {
      $new_exception = new NotFoundHttpException($e->getMessage());
      $event->setException($new_exception);
    }
  }

```
> 0 votes

---
Tags: 8, http-request, event-subscribers
---


# Question
Title: Sending data to a controller with AJAX POST
I am using AJAX to send request to controller, but the data is sent with the GET method. I want the request send with the POST method.

The following is the code I used.

```
var table_url = '/table-data'+params;
var elementSettings = {};
elementSettings.url = table_url;
elementSettings.progress = {
  type: 'throbber'
};
Drupal.ajax(elementSettings).execute();

```

# Answer
If you want to send POST parameters add them to `elementSettings.submit`:

```
elementSettings.submit = {
  foo: 'bar'
};

```

and remove the GET parameters from `elementSettings.url`.
> 4 votes

# Answer
You could always non-Drupaly do it like this

```
$("#some-id").click(function(){
  $.ajax({
    type: 'POST',
    url: '/table-data'+params',
    data: JSON.stringify ({username: 'No Sssweat'}),
    contentType: "application/json",
    dataType: 'json',
    beforeSend: function(){
      $(this).prepend('<span class="ajax-progress-throbber"><div class="throbber">  </div></span>');
    },
    success: function(data) {
      alert(data);
    },
    complete: function(){
     $('.ajax-progress-throbber').remove();
    }
  });
});

```
> 1 votes

---
Tags: ajax
---


# Question
Title: Building a search View that respects access control
I'm implementing search on a site using taxonomy access control with search api and search api solr. Reading the help page node access section, I see:

> Needs details on how to build a View that respects access control.

… which is exactly what I need. How can I make a search view properly respect the taxonomy access control? I've got node access turned on in the index settings, and see the field available in the views filter, so I see some items with node\_access\_taxonomy\_access\_role:n set up, I could try to filter on this, but it would not affect the facets.

I have

> Additional access checks on result entities

turned on in query settings as a temporary measure, but that only filters the search results, and not any facets, etc.

One possible (though inefficient) solution seems like it could be to make two indexes and the have two displays in the search view, searching the right index depending on whether the user is authenticated or not, but I see no good way to limit the index based on the taxonomy term assigned.

It seems like my question extends beyond the boundaries of the search view, and onto the index itself.

# Answer
I've gotten this to work, but it was not exactly straightforward, mainly because there wasn't a clear way to find out what to filter for in the view. Big thanks to @Shawn Conn for the idea of contacting Jon Pugh, who wrote the comment in the help page, and Jon Pugh for answering me quickly. He didn't give me the answer, but made me feel more confident that if I kept working on what I was working on, there would be some likelihood of success.

## Step One: Make sure node access info is being indexed

## Step Two: Make the field available to views:

## Step Three: In Solr, open your core, and in the Schema Browser find the access field:

## Step Four: Click on that field, Load Term Info, and see what access term data Solr is getting:

## Step Five: In your view, enable a filter on the node access field, and filter using the value(s) you found in step four:

## Further Notes

Filtering this way causes the search results counts and facet counts/facets available to all give the correct information. There is another option as in Shawn Conn's answer that will filter the results for access after the query has already been made. This filters the list separately from providing results to the facets and search information blocks, etc, which causes them to provide incorrect results.
> 3 votes

# Answer
For the Search Views module there's an option that enables further access checks on indexed entities that will enable your Taxonomy Access Control permission check.

You'll find in the Views UI under **Advanced \> Query settings** on via the **Settings** link. It is enabled via the **Additional access checks on result entities** checkbox. As a caveat, this option will make result counts, pagination, and other search result details behave oddly since permission checks can't be made at index time.
> 2 votes

# Answer
in drupal8 , simply opt-in the

> ```
> Adds content access checks for nodes and comments.
>
> ```

of the search api module configuration at this address:

/admin/config/search/search-api/index/article/processors
> 0 votes

---
Tags: 8, views, taxonomy-terms, search
---


# Question
Title: Get paragraph field in a specific text format
I have a landing page with a list of paragraphs. I'm trying to render the main body paragraph field as a summary to use in a metatag in the header.

`$basic_content_block->get('field_content')->first()->getValue();`

Returns:

```
[
    'value' => "<p><span><span><span><span><span><span>Some rich text here.</span></span></span></span></span></span><span",
    'format' => "basic_html"
]

```

How can I return this field as a teaser view, or more appropriately, a summary of just the text?

# Answer
```
$basic_content_block->get('field_content')->summary;

```

I believe that should do it.
> 0 votes

---
Tags: 8, paragraphs
---


# Question
Title: Order item with persistent custom field value
### Goal

With Drupal Commerce, my goal is to have a customizable product with persistent user entered text.

I have added a text field to the order item type and I can see the custom field in the "add to cart" form. When customer enters a value in that field and adds the product to the cart, I can see the value of that field in the cart form view.

I want to have a link to the purchased entity in the cart form view so I checked "Link label to the referenced entity" in the view field configuration.

When I hit that link, I get back to my product page, with the correct variation selected, but the custom text field will be empty.

### Question

How can I make this custom text field persistent, that is, "save" its value so that when I click the item link in the cart view, I get back to the product variation with the custom text field already filled in?

*Note: I could have multiple products/variations in the cart, each with a different custom text so I need to keep the value on the order item level.*

### What I have tried

I thought about having that custom text field value as a parameter in the cart form view purchased entity link URL so I tried to rewrite the output of that field/link, but I don't have access to the product entity from that view and I'd need it to compute the new URL... so that won't work.

Any idea?

# Answer
> 1 votes
I couldn't find a more elegant way but this works for me.

First I rebuild the purchased entity link in the commerce cart form view to include the custom text field value as a parameter in the link URL for when I navigate back from the cart to the product variation:

```
/**
 * Implements hook_preprocess_views_view_field().
 */
function MYMODULE_preprocess_views_view_field(&$variables) {

  $view = $variables['view'];
  $field = $variables['field'];

  // Commerce cart form
  if (isset($view) && ($view->id() === 'commerce_cart_form')) {

    switch($field->field) {
      case 'purchased_entity':

        // Get purchased entity
        $purchased_entity = $variables['row']->_relationship_entities['order_items']->purchased_entity->getValue();
        $purchased_entity_id = $purchased_entity[0]['target_id'];

        // Load product variation
        $product_variation = $variation = ProductVariation::load($purchased_entity_id);

        // Get product variation URL
        $url = Url::fromUserInput($product_variation->toLink()->getUrl()->toString());

        // Get custom field value
        $custom_field = $variables['row']->_relationship_entities['order_items']->field_custom->getValue();

        // Rebuild url with variation & custom field value
        $url->setOption('query', [
          'v' => $purchased_entity_id,
          'custom' => $custom_field[0]['value'],
        ]);

        // Output
        $variables['output'] = Link::fromTextAndUrl(t($product_variation->label()), $url);

        break;
    }
  }
}

```

This will output a link like `/product/1?v=2&custom=MYVALUE`

And then on the product add to cart form, if the param is in the URL, I set the default value of the custom field:

```
/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if (strpos($form_id, 'commerce_order_item_add_to_cart_form_commerce_product_') !== false) {

    // Set custom text form field value from URL
    $form['field_custom']['widget'][0]['value']['#default_value'] = \Drupal::request()->query->get('custom');
  }
}

```

---
Tags: 8, views, commerce
---


# Question
Title: Debugging the result property in a ViewExecutable
I need to debug the `$result` property of the `ViewExecutable` object passed to `hook_views_post_execute` but for what ever reason, Drupal can't handle it. $view-\>result is an array of type `ResultRow`, and because it's an array, I'm attempting to log it like so:

```
\Drupal::logger('foo')->notice('<pre>' . print_r($view->result, TRUE) . '</pre>');

```

When I do this and then load the view I'm attempting to mess with, it loads the page without css and then the recent log messages just shows up blank, no errors or anything that would actually be helpful.

I've tried a number of different ways but this is always the result. Why can't this logger print a simple array?

I've even tried looping through the array and printing just the value:

```
foreach($view->result as $key => $value) {
  \Drupal::logger('bar')->notice(print_r($value, true));
}

```

And that will render the view without css and then the logger doesn't print anything at all. I double checked and printed a regular string and that worked, but when I attempt to print the value it just breaks and doesn't do anything.

# Answer
> 0 votes
Your code works fine for me so perhaps your view has no results?

Anyways, the Drupal log is not really meant to be used for printing variables for debugging purposes. Use an appropriate tool like Devel which has/comes with another module called Kint, enable Kint.

```
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_post_execute()
 */
function mymodule_views_post_execute(ViewExecutable $view) {
  kint($view->result);
}

```

Flush cache and you'll see this

For more info on how to use Kint, see Welcome to Kint 101

---
Tags: 8
---


title: Get order of a content type's fields

text:
# Question
Title: Get order of a content type's fields
When I manage fields in content type edition I can put them in order. How could I retrieve this information to use it in a custom module. In Database there is no any column which saves weight order information of fields as they appears in "Manage fields" tab in content type edition.

# Answer
> 1 votes
Use field\_info\_instance()

```
  $entity_type = 'node';
  $field_name = 'body';
  $bundle_name = 'article';
  $body = field_info_instance($entity_type, $field_name, $bundle_name);

```

Which gives you access to numerous config/settings

```
  $body_weight = $body['display']['default']['weight'];

```

---
Tags: 7, entities
---


# Question
Title: How do I limit access to a custom field type I have created so that it can only be attached to certain bundles of content?
I have a custom field class. I would like to limit it to specific content types and bundles that I will choose when my custom module is installed and as other content types meet certain criteria. I don't want it to be available at /admin/structure/types/manage/article/fields/add-field

Is hook\_form\_alter on the add-field page form my only option or is there an Annotation or API I can use to mark my field as "not available to this content" similar to the way FieldWidgets can be marked as applicable to only certain field types?

Note: I was also planning to add a ConstraintValidator to the field so that it won't validate if added to the wrong content.

# Answer
After some further research I will answer with what I found:

In order to make a field type be unavailable on the manage fields page there is an option in the FieldType annotion plugin called `$no_ui` which must be set to `TRUE` as documented here.

Then the field can still be added to specific content types using `BaseFieldDefinition::create()` in `hook_entity_base_field_info` or to bundles using the less common `hook_entity_bundle_field_info` plus `hook_entity_field_storage_info`.
> 0 votes

# Answer
It is not possible to define field types which are only applicable to certain bundles. I think you need hook\_form\_alter for the form where the fields are chosen for a bundle to achieve that.
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Memory error when updating user field with Rules
I'm using the Rules module to update my user email signatures.

The rule get's triggered whenever an account is updated and performs a simple custom action.

This is the action, all it does is save a new value to the signature field (textfield, full\_html).

```
<?php

namespace Drupal\frontview_general\Plugin\RulesAction;

use Drupal\rules\Core\RulesActionBase;
use Drupal\user\Entity\User;

/**
 * Change event date status to ( selected, open, closed )
 *
 * @RulesAction(
 *   id = "rules_update_signature",
 *   label = @Translation("Update User Signature"),
 *   category = @Translation("Custom"),
 *   context_definitions = {
 *     "uid" = @ContextDefinition("integer",
 *       label = @Translation("User id"),
 *       description = @Translation("Specifies the id of the user that needs to be updated.")
 *     )
 *   }
 * )
 */
class UpdateSignature extends RulesActionBase {

  /**
   * {@inheritdoc}
   */
  public function doExecute($uid) {

    $user = User::load($uid);

    $first_name = $user->get("field_first_name")->value;
    $last_name = $user->get("field_last_name")->value;

    $name = $first_name . " " . $last_name;

    $user->set("field_signature", $name);
    $user->field_signature->format = "full_html";

    $user->save();

  }
}

```

This all works fine until it hits the  `$user->save();` part. That's where something goes wrong and I end up with this error:

```
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /Users/lennertslabbinck/Sites/Frontview/web/core/lib/Drupal/Core/Cache/DatabaseBackend.php on line 167

```

This works great in other actions with other content so it probably has something to do with this being users but I can't figure out what.

# Answer
> 1 votes
Your problem is loop update user infinity. When user update, hook\_entity\_update will be call:

```
/**
 * Implements hook_entity_update().
 */
function rules_entity_update(EntityInterface $entity) {
  // Only handle content entities and ignore config entities.
  if ($entity instanceof ContentEntityInterface) {
    $entity_type_id = $entity->getEntityTypeId();
    $event = new EntityEvent($entity, [
      $entity_type_id => $entity,
      $entity_type_id . '_unchanged' => $entity->original,
    ]);
    $event_dispatcher = \Drupal::service('event_dispatcher');
    $event_dispatcher->dispatch("rules_entity_update:$entity_type_id", $event);
  }
}

```

soure

This event will be call your rule action. So when you call $user-\>save(), the hook\_entity\_update will call again... That's your problem. To be resolve, you can follow example.

* Edit your annotation. "user" = @ContextDefinition("entity:user",
* Update logic method `doExecute`
* Update your rule.

**Remember don't call $user-\>save() again.**

---
Tags: 8, users, rules, actions
---


title: Custom 404 page not working

text:
# Question
Title: Custom 404 page not working
I'm trying to set a custom 404 page but is not working. What I tried:

* configuration - system - basic site settings and set node path on 404 page -\> didn't work
* add page--404.html.twig to my custom theme -\> didn't work
* in my custom-theme.theme added \_theme\_suggestions\_page\_alter function -\> didn't work

Always show default 404 page, not my custom page. I clear cache on every attempt. Is there something I am missing?

Thanks in advance

---

Edited

Tried on local and cloud acquia server

I check with another websites that I build and all of them give me this 404 page (default)

But with this specific website I get this 404 page

It seems this website 404 error is handle by browser and not by drupal 8(?)

---

Edited 2

Another thing I notice is when I type a wrong URL appear on "log messages"

But on current website (the one I can't set custom 404) I don't have any error on "log messages".

Is there any code/config to enable/disable this?

Maybe this is same problem?

# Answer
> 1 votes
Are your sure you did all the steps? **Step 1: in mytheme.theme**

```
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MYTHEME_theme_suggestions_page_alter(array &$suggestions, array $variables) {

  $route_name = \Drupal::routeMatch()->getRouteName();
  switch ($route_name) {
    case 'system.401':
      // Unauthorized Access.
      $error = 401;
      break;

    case 'system.403':
      // Access Denied.
      $error = 403;
      break;

    case 'system.404':
      // Page Not Found.
      $error = 404;
      break;
  }
  if (isset($error)) {
    $suggestions[] = 'page__' . $error;
  }
}

```

**Step 2: create the page--404.html.twig file**

**Step 3: clear cache**

For some markup, check https://stefvanlooveren.me/blog/styling-404-error-pages-drupal-8

# Answer
> 1 votes
Thanks everyone who contrib to help me solve this problem.

Special thanks to @4k4 user, with some keywords and starting points I could found where my problem was.

It was in settings.php at "Fast 404 pages" function, I had this code:

Commented this block and it works like charm.

Thanks @4k4 for your help.

# Answer
> 0 votes
```
/**
 * Implements hook_theme_suggestions_page_alter().
 */
function THEMENAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
        $path_args = explode('/', trim(\Drupal::service('path.current')->getPath(), '/'));
        $suggestions = theme_get_suggestions($path_args, 'page');
        $http_error_suggestions = [
            'system.401' => 'page__401',
            'system.403' => 'page__403',
            'system.404' => 'page__404',
        ];

        $route_name = \Drupal::routeMatch()->getRouteName();
        if (isset($http_error_suggestions[$route_name])) {
            $suggestions[] = $http_error_suggestions[$route_name];
        }
}

```

Create the page template page--404.html.twig

---
Tags: 8, theming, hooks
---


title: Determine if entity type is fieldable

text:
# Question
Title: Determine if entity type is fieldable
Given an $entityTypeId as string, how can I determine if this entity type is fieldable? That is, if entities of that type implement FieldableEntityInterface?

# Answer
> 4 votes
There might be a simpler way but I think this should be pretty reliable:

```
// Inject the entity_type.manager service instead if possible.
$class = \Drupal::entityTypeManager()
    ->getDefinition($entity_type_id)
    ->getOriginalClass();

$interface = 'Drupal\Core\Entity\FieldableEntityInterface';

if (in_array($interface, class_implements($class))) {
    ...
}

```

# Answer
> 0 votes
This might be a bit simpler:

```
if (method_exists(\Drupal::entityTypeManager()->getDefinition($entity_type_id)->getOriginalClass(), 'hasField')) {
...
}

```

---
Tags: 8, entities
---


title: How to set the correct RSS row plugin?

text:
# Question
Title: How to set the correct RSS row plugin?
I need to add an image to the RSS feed. So I create a new row plugin for the RSS and it extends `RssFields` row plugin.

```
/**
 * Renders an RSS item based on fields.
 *
 * @ViewsRow(
 *   id = "image_field_rss_fields",
 *   title = @Translation("Fields with image field"),
 *   help = @Translation("Display fields as RSS items with an image item."),
 *   theme = "views_view_row_rss",
 *   display_types = {"feed"}
 * )
 */
class ImageFieldForRssFields extends RssFields {

```

I can select it in the format settings.

And it seems that works perfectly when I update the preview, I can see a new field image on every item of the RSS. But when the RSS feed is rendered, it uses the `RssFields` plugin instead of the `ImageFieldForRssFields` plugin that is setted.

I debugged it and it seems that always renders the `RssFields` plugin even if I delete the `RssFields` plugin, the view tries to locate it.

Am I missing something? How do I have to do to render the correct plugin?

# Answer
There is a patch to add an image as an enclosure field to core here:

https://www.drupal.org/project/drupal/issues/2511878
> 1 votes

---
Tags: views, 8, feeds, plugins
---


title: Change article layout on homepage

text:
# Question
Title: Change article layout on homepage
I would like to change the layout of articles on my homepage. But I cannot find the template hereof.

I've got my page.html.twig, which but that only includes a placeholder "{{ page.content }}" in which all the articles are loaded.

And then I've got node--article--full.html.twig, but the layout there only seems to affect the article pages.

So where can I find the template to adapt the articles and their layout as shown on the homepage? Do I have to create something like page--node--article.html.twig to overwrite the design of something?

# Answer
The list of nodes listed in the homepage by default is from the Frontpage(`/admin/structure/views/view/frontpage`) view. If you'll go to that view, you'll notice on the FORMAT section, under Show, the value is "Content | Teaser". This means that the each node displayed is using a specific View Mode called "Teaser".

Next is to enable twig debugging. Once that's done and you check the homepage's markup, specifically on one of the article listings, you'll see this:

Notice that I'm highlighting one "article teaser" and on the markup you'll see a list of file names i.e. `node.html.twig`, `node--teaser.html.twig` and etc. and the one with the "x" is the default template that is being used.If none of the other files are found then Drupal always goes to the base template which in this case is `node.html.twig`. So if Drupal matches a theme suggestion in the list to a physical file on your theme, that's what it will use.

With those information, you can go to the current template file using the file path(`core/themes/bartik/template/node.html.twig`), copy it into your custom theme, rename it as `node--teaser.html.twig`, do some random edits for initial testing, clear the cache and then visit the homepage again.

You should see that the "x" under "FILE NAME SUGGESTIONS" will now be beside `node--teaser.html.twig` and your changes to the file as well.
> 2 votes

# Answer
I found it, the template to change articles on the homepage is node.html.twig

If I understand correctly, there are other ways to name this template so that it becomes more specific, as node.html.twig is like a base template for all Drupal nodes (although I haven't found the exact definition hereof).
> 0 votes

---
Tags: theming, nodes
---


# Question
Title: Given a book node nid, programmatically get all child node nids
I use the D8 Book module to create books with chapters. Works great.

When an editor makes a certain change to a book node, I need to look at each of its chapter (child) nodes to potentially adjust a field in them.

I know how to detect the book node change in `node_presave()`. I know how to load, modify, and save a child node once I have its nid. What I don't know is how to get a complete list child node nids for the book.

I've read many posts related to this subject, but none that provide a straightforward way to programmatically get a list of child node nids given the parent book node nid. I've also looked at the Book module documentation. I assume I'm just overlooking something simple.

# Answer
To get the complete list of child node nids for the book:
use the `BookOutlineStorage::loadBookChildren` from the `book.outline_storage` service. like the following:

```
/** @var \Drupal\book\BookOutlineStorageInterface $book_outline_storage */
$book_outline_storage = \Drupal::service('book.outline_storage');
$childrens  =  $book_outline_storage->loadBookChildren(NID);

```
> 3 votes

---
Tags: 8
---


# Question
Title: Controller is loading twice after search form is submitted
I created a custom module that I consume an external api. I have also created a custom form (its action points to controller url) which filters the data. However, when I press the search button and the controller is loading, despite I get the right results immediately the controller is reloading and consequently I loose the filtered results.

How I can stop this behaviour?

This is my code so far:

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

    $ada = $form_state->getValue('ada');
    $sector = $form_state->getValue('sector');
    $sub_sector = $form_state->getValue('sub_sector');

if ($sub_sector=='') {
  $subject_unit=$sector;
} else {
  $subject_unit=$sub_sector;
}

    $datefrom = $form_state->getValue('datefrom');
    $dateto = $form_state->getValue('dateto');

    $params=[
    'type'=>$subject_unit,
    'datefrom'=>$datefrom,
    'dateto'=>$dateto,
    'freetext'=>$freetext,
    'ada'=>$ada
  ];

}

```

controller:

```
class DiafaneiaController extends ControllerBase {

  public $filters=[];

  public function getList(Request $request) {

    $filters = \Drupal::request()->request->all();

    $data = array();
    $response = $data = $result = null;

    $page = pager_find_page()+1;
    //echo 'pageNo:'.$page;

    if (function_exists('diafaneia_reponse')) {
      $response = diafaneia_reponse('https://diafaneia.hellenicparliament.gr/api.ashx?q=documents&pageSize=20&pageNo='.$page.'&sector=0216896c-4d26-49de-b896-a2b600ab3843', 'GET',$filters);
    }

    if ($response) {

      $result_docs = json_decode($response);
      $data = array();

      // # add all the data in one multiple dim array
      $data['title'] = 'products to consume REST API';
      $data['docs'] = $result_docs;

$num_per_page = 10;
$offset = $num_per_page * $page;

// Now that we have the total number of results, initialize the pager.
pager_default_initialize($result_docs->TotalRecords, $num_per_page);

$render = [];
$render[] = [
  '#theme' => 'diafaneia_list',
  '#data' => $data,
  '#type' => 'remote',
];

$render[] = ['#type' => 'pager'];

    }
    return $render;
  }

```

# Answer
> 2 votes
It's unclear how both pieces of code are connected with each other.

If you are handling the form values in form submit you need to pass the resulting parameters to the controller:

```
public function submitForm(array &$form, FormStateInterface $form_state) {
  // prepare $params
  $form_state->setRedirect('route_to_controller', [], ['query' => $params]);
}

```

If you are pointing the form action to the controller

```
$form['#action'] = Url::fromRoute('route_to_controller')->toString();
$form['#method'] = 'get';

```

then there is no form submit and you have to process the submitted values in the controller.

---
Tags: forms, page-controller
---


title: How can I send a HTML email?

text:
# Question
Title: How can I send a HTML email?
I am trying to send an email with HTML content. But Drupal is always scrapping my HTML tags.

I see drupal formatting the message in this function:

```
//Class: \Drupal\Core\Mail\MailManager

// Format the message body.
//$message = $system->format($message);
public function doMail($module, $key, $to, $langcode, $params = [], $reply = NULL, $send = TRUE) {
    $site_config = $this->configFactory->get('system.site');
    $site_mail = $site_config->get('mail');
    if (empty($site_mail)) {
      $site_mail = ini_get('sendmail_from');
    }

    // Bundle up the variables into a structured array for altering.
    $message = [
      'id' => $module . '_' . $key,
      'module' => $module,
      'key' => $key,
      'to' => $to,
      'from' => $site_mail,
      'reply-to' => $reply,
      'langcode' => $langcode,
      'params' => $params,
      'send' => TRUE,
      'subject' => '',
      'body' => [],
    ];

    // Build the default headers.
    $headers = [
      'MIME-Version' => '1.0',
      'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
      'Content-Transfer-Encoding' => '8Bit',
      'X-Mailer' => 'Drupal',
    ];
    // To prevent email from looking like spam, the addresses in the Sender and
    // Return-Path headers should have a domain authorized to use the
    // originating SMTP server.
    $headers['Sender'] = $headers['Return-Path'] = $site_mail;
    // Make sure the site-name is a RFC-2822 compliant 'display-name'.
    $headers['From'] = MailHelper::formatDisplayName($site_config->get('name')) . ' <' . $site_mail . '>';
    if ($reply) {
      $headers['Reply-to'] = $reply;
    }
    $message['headers'] = $headers;

    // Build the email (get subject and body, allow additional headers) by
    // invoking hook_mail() on this module. We cannot use
    // moduleHandler()->invoke() as we need to have $message by reference in
    // hook_mail().
    if (function_exists($function = $module . '_mail')) {
      $function($key, $message, $params);
    }

    // Invoke hook_mail_alter() to allow all modules to alter the resulting
    // email.
    $this->moduleHandler->alter('mail', $message);

    // Retrieve the responsible implementation for this message.
    $system = $this->getInstance(['module' => $module, 'key' => $key]);

    // Attempt to convert relative URLs to absolute.
    foreach ($message['body'] as &$body_part) {
      if ($body_part instanceof MarkupInterface) {
        $body_part = Markup::create(Html::transformRootRelativeUrlsToAbsolute((string) $body_part, \Drupal::request()->getSchemeAndHttpHost()));
      }
    }

    // Format the message body.
    $message = $system->format($message);

    // Optionally send email.
    if ($send) {
      // The original caller requested sending. Sending was canceled by one or
      // more hook_mail_alter() implementations. We set 'result' to NULL,
      // because FALSE indicates an error in sending.
      if (empty($message['send'])) {
        $message['result'] = NULL;
      }
      // Sending was originally requested and was not canceled.
      else {
        // Ensure that subject is plain text. By default translated and
        // formatted strings are prepared for the HTML context and email
        // subjects are plain strings.
        if ($message['subject']) {
          $message['subject'] = PlainTextOutput::renderFromHtml($message['subject']);
        }
        $message['result'] = $system->mail($message);
        // Log errors.
        if (!$message['result']) {
          $this->loggerFactory->get('mail')
            ->error('Error sending email (from %from to %to with reply-to %reply).', [
            '%from' => $message['from'],
            '%to' => $message['to'],
            '%reply' => $message['reply-to'] ? $message['reply-to'] : $this->t('not set'),
          ]);
          $error_message = $params['_error_message'] ?? $this->t('Unable to send email. Contact the site administrator if the problem persists.');
          if ($error_message) {
            $this->messenger()->addError($error_message);
          }
        }
      }
    }

    return $message;
  }

```

**How do I avoid this?** I do not want Drupal formatting the content.

My headers:

```
$headers = [
    'MIME-Version' => '1.0',
    'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer' => 'Drupal',
];

```

# Answer
> 7 votes
Use the Mime Mail module

> The Mime Mail module gives Drupal core and other Drupal modules the ability to send HTML email messages. This is an all-Drupal solution that does not require external third-party libraries.

---
Tags: 8, emails
---


# Question
Title: How to remove a role after a user adds a payment method in Commerce?
I am trying to set up a subscription-based site in Drupal 8/Commerce 2.

I'm using Commerce Stripe to process payments. I want to remove a role from a user ("needs to add new card" role) when the user adds a new payment method (credit card via Stripe) on the payment method page (`user/UID/payment-methods`).

I assume I need to write an event subscriber, but I don't know which event to use for adding a payment method.

I tried to read through the code in `commerce/modules/payment/src/EventSubscriber`, but I couldn't find the event I need to hook into to remove the role.

**Background**

When a user's credit card has expired, they need to add a new card (add a new payment method). In this case, I have flagged the users with a role, **Add new card role**.

Then I show a block to users with the **Add new card role** that says "Please update your card info." with a link to add a card.

However, when the user adds a new card, they still see the block asking them to add a new card, which is confusing. So I want to immediately remove the **Add new card role** (to hide the block) as soon as the user adds a new card.

# Answer
commerce doesn't offer the (content-)entity create event. You could use a hook ..

Or setup events for entity creation, see Does Drupal 8 entities have any events I can listen to?
> 1 votes

# Answer
Based on the hint from rémy, here's the actual code I used.

Note that for commerce payment methods, you have to use `hook_entity_insert()` specifically instead of `hook_entity_create()` because `hook_entity_create()` gets called when you go to the payment method add page-- even if you immediately go back without entering any information.

```
/**
 * Remove the 'credit_card_update_role' upon adding a credit card.
 *
 * {@inheritDoc}
 */
function MYMODULE_commerce_payment_method_insert(\Drupal\Core\Entity\EntityInterface $entity) {
  $uid = \Drupal::currentUser()->id();
  $account = User::load($uid);
  if ($account->hasRole('credit_card_update')) {
    $account->removeRole('credit_card_update');
    $account->save();
  }
}

```

I added a redirect because by default users are redirected to the payment method edit page, which will result in an access denied error. To avoid this, I send them to the user profile page with a confirmation that the card was added.

```
/**
 * Redirect users to their profile pages after adding a new card.
 *
 * {@inheritDoc}
 */
function MYMODULE_form_commerce_payment_method_add_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Redirect users to their profile pages.
  $form['actions']['submit']['#submit'][] = '_MYMODULE_commerce_payment_method_insert_form_submit';
}

/**
 * Redirect users to their profile pages when submitting the edit form.
 */
function _MYMODULE_commerce_payment_method_insert_form_submit($form, &$form_state) {
  \Drupal::messenger()->addStatus('Thank you for updating your credit card!');
  $form_state->setRedirect('entity.user.canonical', ['user' => \Drupal::currentUser()->id()]);
}

```
> 0 votes

---
Tags: commerce, event-subscribers
---


# Question
Title: Delay ajax call on textfield to allow for typing
I would like to delay ajax from firing in the same way that the autocomplete seems to work. For example, if a user it typing, the ajax will not run until 500ms has elapsed since the last keyup.

I am currently looking at drupal.behaviors but not able to make it work.

```
Drupal.behaviors.mymodule = {
  attach: function(context, settings) {
    $('input.andtimer', context).delay(500).ajaxStart();
  }
};

```

This is the form element to which the behavior is attached.

```
$form['my_input'] = array(
  '#type' => 'textfield',
  '#default_value' => $value,
  '#ajax' => array(
    'callback' => 'my_callback',
    'event' => 'keyup',
    'wrapper' => 'my_wrapper',
    'trigger_as' => array(
      'name' =>  'my_button',
  ),
  'progress' => array('type' => 'none'),
  ),
  '#attributes' => array(
    'class' => array('andtimer'),
  ),
);

```

This jsfiddle shows what I am trying to achieve.

Would How to override Drupal.ajax.prototype.beforeSend? be a route to take this down?

The following works for the first 'set' of inputs with the class .andtimer. It is not working for any other set, the ajax always continues with the first set. Any ideas how to fix this?

```
(function($, Drupal) {
    Drupal.behaviors.bform = {
        attach : function(context, settings) {

            var events = $('.andtimer').clone(true).data('events');
            $('.andtimer').unbind('keyup');
            var typingTimer;
            var doneTypingInterval = 300;
            $('.andtimer').keyup(function() {
                clearTimeout(typingTimer);
                typingTimer = setTimeout(doneTyping, doneTypingInterval);
                function doneTyping() {
                    $.each(events.keyup, function() {
                        this.handler();
                    });
                }

                return false;
            });
        }
    };
})(jQuery, Drupal);

```

Using $form\['my\_input'\]\['#ajax'\]\['event'\] = 'finishedinput' as suggested and

```
var typingTimer;
var doneTypingInterval = 600;

$('.andtimer').on('keyup', function (e) {
  clearTimeout(typingTimer);
  if ($(this).val) {
    var trigid = $(this);
    typingTimer = setTimeout(function(){
      trigid.triggerHandler('finishedinput');
    }, doneTypingInterval);
  }
});

```

Works for each 'group' of inputs where the count of filled inputs needs to be obtained.

# Answer
> 7 votes
One option is to use a custom jQuery event, eg. something like *finishedinput*. Set `$form['my_input']['#ajax']['event'] = 'finishedinput'` and provide some JS to trigger your custom event after an appropriate delay (similar to the JS in the fiddle).

# Answer
> 3 votes
You can implement your own Jquery event and add logic to delay the triggering.

Add this into `my_module.js`:

```
(function ($, Drupal, drupalSettings) {
  'use strict';
  Drupal.behaviors.my_module_finishedinput = {
    attach: function (context, settings) {
      var typingTimer;
      var delay = 1100;
      $('#form-input-id-goes-here').once('finished_input').on('keyup', function (e) {
        clearTimeout(typingTimer);
        if ($(this).val()) {
          var trigid = $(this);
          typingTimer = setTimeout(function () {
            trigid.triggerHandler('finishedinput');
          }, delay);
        }
      });
    }
  };
})(jQuery, Drupal, drupalSettings);

```

Add js to the page by creating `my_module.libraries.yml`.

```
jquery_event:
  version: VERSION
  js:
    my_module.js: {}
  dependencies:
    - core/jquery
    - core/jquery.once
    - core/drupal
    - core/drupalSettings

```

Attach js to the form

```
$form['myform']['#attached'] = ['library' => ['my_module/jquery_event']];

```

Finally, add this array to the $form

```
'#ajax' => [
        'callback' => '::myFormCallback',
        'event' => 'finishedinput',

```

# Answer
> 0 votes
This approach has both the advantage and disadvantage of being applied for all keyup-triggered AJAX events on any page where this script runs.

```
!function ($) {
  const originalMethod = Drupal.ajax.prototype.eventResponse,
        timeoutDelay   = 500;

  var timeoutId;

  // Override the default event handler
  Drupal.ajax.prototype.eventResponse = function (element, event) {
    const self = this;
    clearTimeout(timeoutId);

    if ('keyup' === this.event) {
      // Fire the original event handler with a delay
      timeoutId = setTimeout(function (element, event) {
        originalMethod.apply(self, [element, event]);
      }, timeoutDelay, element, event);
    }
    else {
      // Fire the original event handler immediately
      originalMethod.apply(this, [element, event]);
    }
  };
}(jQuery);

```

# Answer
> -1 votes
This is the code I wrote:

```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br" lang="pt-br">
<head><title>Submit after typing finished</title>
<script language="javascript" type="text/javascript">
function DelayedSubmission() {
    var date = new Date();
    initial_time = date.getTime();
    if (typeof setInverval_Variable == 'undefined') {
            setInverval_Variable = setInterval(DelayedSubmission_Check, 50);
    }
}
function DelayedSubmission_Check() {
    var date = new Date();
    check_time = date.getTime();
    var limit_ms=check_time-initial_time;
    if (limit_ms > 800) { //Change value in milliseconds
        alert("insert your function"); //Insert your function
        clearInterval(setInverval_Variable);
        delete setInverval_Variable;
    }
}

</script>
</head>
<body>

<input type="search" onkeyup="DelayedSubmission()" id="field_id" style="WIDTH: 100px; HEIGHT: 25px;" />

</body>
</html>

```

# Answer
> -1 votes
I also tried "beforeSend" without much luck. I then stumbled upon "beforeSubmit" and that does the trick for me. You can use this strategy to hook into other Drupal ajax prototype methods too (see /misc/ajax.js for all original methods):

```
(function($, Drupal) {
    var delayedTimeoutId;
    var delayInterval = 500;

    /**
     * Modify form values prior to form submission.
     */
    Drupal.ajax.prototype.original_beforeSubmit = Drupal.ajax.prototype.beforeSubmit;
    Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) {
        // Some console stuff for info purposes:
        if(window.console) {
            console.log('beforeSubmit args:');
            console.log(this); // contains stuff like PHP AJAX callback, triggering selector, etc.
            console.log(form_values); // the form data
            console.log(element); // the triggering element
            console.log(options); // ajax options
        }

        // If it is the triggering selector or callback I want to delay, then do the delay:
        if(this.selector == '#my-text-input-id' || this.callback == '_my_module_ajax_callback') {
            // Clear timeout if it exists;
            clearTimeout(delayedTimeoutId);
            // Start waiting:
            delayedTimeoutId = setTimeout(function(drupalAjax, form_values, element, options) {
                delayedTimeoutId = null;
                // Execute original beforeSubmit:
                drupalAjax.original_beforeSubmit(form_values, element, options);
            }, delayInterval, this, form_values, element, options)
        } else {
            // Continue with original beforeSubmit:
            this.original_beforeSubmit(form_values, element, options);
        }
    };
}(jQuery, Drupal));

```

---
Tags: forms, ajax, javascript
---


# Question
Title: How to get the current field value in Ajax callback?
I 've a problem with Drupal 8 ajax callbacking. I created a multivalue field for country - region listing as new field type using a custom module. In first selectlist I loaded all country codes and I set this field as multivalued.

I wrote the below code in FieldWidgetType Class.

```
     public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
  $element['value'] =  array(
      '#type' => 'select',
      '#title' => 'Select Country',
      '#name' => 'value',
      '#options' => array(
        0 => t('- Select Country -')) + $termNameArr,
      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
      '#ajax' => [
              'callback' => array($this, '_regions_ajax_callback'),
              'event' => 'change',
              'progress' => array(
                 'type' => 'throbber',
                 'message' => t('Please wait.Fetching data...'),
                ),
             ],
      '#suffix' => '<span class="email-valid-message"></span>'
    );
    return $element;
    }

```

I have to load regions of the selected country in an another select box using ajax. The selectbox should populate with the regions of selected country in change event of country select box item (here I'm calling ajax). Or else, can ajax simply return the selected country value to append in span (.email-valid-message) specified in #suffix.

My current callback to return at least the selected country name is:

```
    public function _regions_ajax_callback(&$form, &$form_state) {
      $response = new AjaxResponse();
      $element = $form['value'];
      $default_value = isset($element['#default_value']) ? element['#default_value'] : NULL;
      $value = $form_state->getValue($element['#name']);
      $changed = $default_value == $value;
        if ($changed) {
       $response->addCommand(new HtmlCommand('.email-valid-message', $value));
       }
    return $response;
    }

```

I used namespaces

```
    use Drupal\Core\Ajax\AjaxResponse;
    use Drupal\Core\Ajax\HtmlCommand;

```

What am I doing wrong? How can I change my callback function to get current field value? Did I miss to add any namespace?

# Answer
> 5 votes
in your \_regions\_ajax\_callback()

```
$element = $form_state->getTriggeringElement();
element['#value'] <-- value is in here

```

# Answer
> 1 votes
I did by using getUserInput()

i.e.

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

    $input = $form_state->getUserInput();
    $input = $input['field-name-goes-here'];

    // Sanitize input.
    $input = Xss::filter($input);

    //...

```

---
Tags: 8, ajax
---


# Question
Title: How To print composit element in twig file
I have my twig file for theming pdf submission. In my webform there is a "custom composite" element with three fields, is multivalue and I set to display it as table.

Now, I must to print it in my twig file but I don't know how.

# Answer
This is a solution for my scenario and post it if can help anyone. So, my "custom composite" element is multivalue and for print it in my custom entity-print--webform-submission--test.html.twig file I have insert this code:

```
{% for item in data.my_custom_composite %}
              <tr>
                <td>{{ item.day|date('d.m.Y') }}</td>
                <td>{{ item.from }}</td>
                <td>{{ item.to }}</td>
              </tr>
            {% endfor %}

```
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: Filter by taxonymy ID with multiple field in contextual filter
In drupal 8.9 I need to filter by taxonomy ID over multiple fields in the contextual filter of views.

How to do this ?

# Answer
On the views edit page:

* Under Advanced: Create a relation to the field that holds the refrence to the taxonomy id ("**Taxonomy term referenced from *field\_your\_field\_name\_that\_holds\_the\_reference***")
* Under Advanced: Create a contextual filter for the Term ID and select the previous made relation as relationship. As final step click on "more" on the same page beneith, and select allow multiple.

Now you just add multiple taxonomy id's as 1+2+3 (for OR) or 1,2,3 (for AND).

And if you want to select on multiple fields: Repeat the process to add more fields and then you can do:

/1+2+3/877,454,453/345,345,345 Each slash represents the contextual filter field 1+2+3 is contextual filter one 877,454,453 is contextual filter two Etc.
> 0 votes

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


# Question
Title: Can Onsite PaymentGateway Support Notification
I have seen many implementations of **notification** in **OffsitePaymentGatewayBase** Like **WorldPay**, **QuickPay**

Can I Extend the OnsitePaymentGatewayBase class and use **onNotify()** Method for receiving **Payment** **notification**?

# Answer
I have raised this question to slack for drupal commerce and they responded. the Response is below

**Slack Answer:** *your payment gateway must implement* https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/payment/src/Plugin/Commerce/PaymentGateway/SupportsNotificationsInterface.php *the interface for offsite payment gateway is already extending that. that's why it's available for every offsite gateway, but needs to be added explicitly for onsites*
> 0 votes

---
Tags: commerce, payment-gateways
---


# Question
Title: Modifying only one field with a twig template
I have a content type that has multiple fields. I'm fine with the generic display view for all but one of those fields. Is it possible to use a twig template to modify only one of those fields?

For example:

**Content type**: Stuff and Things with **Fields**: Body, URL, Notes, Status, Peer Review

I want to modify the URL field and leave the rest alone... is this doable, or do I have to render each field in the twig template?

# Answer
> 0 votes
Target the field template instead of node. Enable twig debugger and then inspect element with browser to see all the template files available to use/override.

You'll see you can use `field--[field-name].html.twig` or `field--node--[field-name]--[content-type].html.twig` if you want to be more specific.

---
Tags: 8, theming
---


title: Display webform in a modal

text:
# Question
Title: Display webform in a modal
I am trying to display my webform in a modal (including error/validation messages inside the modal). I am following this approach for a custom drupal form which is not a webform. I am wondering whether this is possible at all with webforms and in case it is, what I need to take into account to make it run?

The first problem I am having is the following code line from the example's `TeacherContactController.php`

```
$modal_form = $this->formBuilder->getForm('Drupal\tl_session\Form\TeacherForm');

```

When I try to use this in my own controller, I cannot get the webform's proper namespace + id. When I check my webform with devel it says:

```
[__CLASS__] => Drupal\webform\Entity\Webform
  [id] => add_news_webform

```

But I get a "The form argument Drupal\webform\Entity\Webform\webform-submission-add\_news\_webform-form is not a valid form" error. I tried many things, but did not succeed.

How can I get the webform with formBuilder and what else am I missing here (like webform specific ajax settings etc.)?

# Answer
Displaying a weform in modal (might be called popup as well) it is a lot simpler than you thought

Lets assume your webform has URL `/contact` than you can create a link in the following manner

```
<a class="use-ajax" data-dialog-type="modal" href="/contact>Contact US</a>

```

Pressing that link will have your form open in a modal with error validation and messages inside the modal

**NOTE:** At least in my case I had to also add the following `hook_preprocess_page` in the `.theme` file

```
function THEMENAME_preprocess_page(&$vars) {
    //custom logic of when to include the library
    // ....
    $vars['#attached']['library'][] =  'core/drupal.dialog.ajax';
}

```

Some people have reported that this is not needed but I assume some other module included this library for them ...
> 14 votes

# Answer
The only solution to load the webform with formBuilder that finally worked for me is based on the following documentation of how to embed a webform. Here's my code:

```
/**
* Callback for opening the modal form to create an article.
*
* @return Drupal\Core\Ajax\AjaxResponse
*   A responseObject for Ajax.
*/
public function addArticle() {
  // Get the currently logged in user account.
  $user = $this->currentUser();
  if ($user->hasPermission('create article content')) {
    $response = new AjaxResponse();
    // Load the webform as indicated here:
    // https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-embed-a-webform
    $output['add_form'] = [
      '#type' => 'webform',
      '#webform' => 'add_news_webform',
    ];
    // Add a modal dialog command to the $response object.
    $response->addCommand(new OpenModalDialogCommand(t('Create Article'), $output, ['width' => '500']));
    return $response;
  }
}

```
> 4 votes

# Answer
Drupal 8 Webform can be opened in modal dialogs using links with the .webform-dialog class

```
a. Common settings Configuration » Forms: /admin/structure/webform/config
    1. FORM DIALOG SETTINGS - Dialog options: set option Enable site-wide dialog support. Do patch for load script by preg_match
    2. Check  Form URL path settings
b. On webform settings Settings » General (example: contact) /admin/structure/webform/manage/contact/settings
    1. Enable options URL PATH SETTINGS: Allow users to post submissions from a dedicated URL
    2. Copy link from DIALOG SETTINGS

```
> 2 votes

---
Tags: 8, webforms
---


# Question
Title: How can I exclude certain routes from maintenance mode?
I am trying to make certain routes exempt from maintenance mode by adding the option \_maintenance\_access to the route and setting it to TRUE.

I think (although I'm not 100%) that this works because in Drupal\Core\Site\MaintenanceMode there is the following method which checks for the \_maintenance\_access option and returns false if it is present -

```
public function applies(RouteMatchInterface $route_match) {
  if (!$this->state->get('system.maintenance_mode')) {
    return FALSE;
  }

  if ($route = $route_match->getRouteObject()) {
    if ($route->getOption('_maintenance_access')) {
      return FALSE;
    }
  }

  return TRUE;
}

```

I have followed this guide on drupal.org on how to alter existing routes

Here is my mymodule.services.yml file

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

```

Here is my MaintenanceModeRouteSubscriber class

```
<?php

namespace Drupal\mymodule\Routing;

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

class MaintenanceModeRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.node.canonical')) {
      $route->addOptions(['_maintenance_access' => TRUE]);
    }
  }
}

```

But this is not working as when viewing this route (any node) it is still in maintenance mode.

# Answer
> 3 votes
You need to override the service directly.

**mymodule.services.yml**

```
services:
  maintenance_mode: # same ID as declared in core.services.yml
    class: Drupal\mymodule\Services\CustomMaintenanceMode # point to your class
    arguments: ['@state']

```

**mymodule/src/Services/CustomMaintenaceMode.php**

```
<?php

namespace Drupal\mymodule\Services;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\MaintenanceMode;

class CustomMaintenanceMode extends MaintenanceMode {

  /**
   * {@inheritdoc}
   */
  public function exempt(AccountInterface $account) {
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface && $node->getType() == 'article') {
      return TRUE;
    }
    else {
      return $account->hasPermission('access site in maintenance mode');
    }
  }

}

```

---
Tags: routes, maintenance-mode
---


title: Drush download, what port does it use?

text:
# Question
Title: Drush download, what port does it use?
I work on a Drupal 7 intranet site for a large company. The firewall on the server it is housed on currently does not allow any access to the Internet. I've been upgrading Drupal core and modules by downloading them to my pc and accessing the server with remote desktop client.

What are the most minimal holes that we'd have to punch in the firewall for Drush to be able to download updates from drupal.org.

Would just opening up port 22 do the trick?

# Answer
For Drush 8.x (the last version compatible with D7), the drush command, `drush pm-download`, can either use HTTP (`wget`) or SSH (`git@git.drupalcode.org`) depending on your `--package-handler` argument. It defaults to HTTP.
> 2 votes

---
Tags: drush
---


# Question
Title: The best way to update existing Paragraphs in Production with newField = TRUE
how are you?

Do you know what's the best way to fill a new field inside of Paragraphs in a Production Environment?

E.g.:

1. I have a Paragraph called "MyParagraph" and this Paragraph has two fields "Title" and "Description";
2. This Paragraph is already present on our Production Environment and there are 500 nodes with this Paragraph filled;
3. I created right now a new field called "Show Description". This field is a checkbox and default is "Checked";

Now I need to update all of these 50 Paragraphs in production with this new field "Show Description" = TRUE

Do you know what's the best option to do that?

I used a simple hook\_update to do this, and another script with a batch process. But I want to see if there is the best solution to do this update.

# Answer
For a no custom code solution, Use Views Bulk Operations with Views Update Fields

Or with Views Bulk Edit, although it's crashing with Paragraphs, so maybe in the future for this particular case.

PS: Do first a dry run on dev/local before doing it on live.
> 0 votes

---
Tags: paragraphs
---


# Question
Title: How can I stop Drupal from sending e-mails of any kind?
I have a dev, staging, and live server workflow set up on Pantheon. My site has a lot of rules that cause members to be e-mailed for various reasons. I sometimes need to work on these on my dev/staging sites but I've realized that, since they have the live data, sometimes users will receive additional or duplicate e-mails when I'm working on something.

Is there any easy way to turn off all e-mailing capability (preferably automatically to prevent me from forgetting) on a dev/staging server? Ideally, I'd like to disable e-mail via a custom module, since I already have steps in place for making sure a custom module is enabled on dev/staging.

# Answer
> 41 votes
As another, quicker, option, you can add the following lines to your site's settings.php file (if you have the Devel module installed, which you certainly should if this is a dev site).

```
$conf['mail_system'] = array(
  'default-system' => 'DevelMailLog',
);

```

That will replace the default mail system with Devel's development mail system, which writes emails to a file log rather than sending them to a recipient. By default the files are stored in `temporary://devel-mails`, but you can alter that by setting another variable, eg.

```
$conf['devel_debug_mail_directory'] = '/path/to/folder';

```

# Answer
> 13 votes
Just a note to add another module to the "There is a module for that" list :

> Reroute email intercepts all outgoing emails from a Drupal site and reroutes them to a predefined configurable email address.

I agree that this functionnality can easily be implemented with a few lines of code, but using this module, you could continue to receive emails to a predefined adress, with details on the original recipient, nice functionnality imho.

# Answer
> 11 votes
Or you can use hook\_mail\_alter to redirect or prevent drupal mails:

```
/**
* Implements hook_mail_alter
*/
function yourmodule_mail_alter(&$message) {
  // set 'To' field to nothing, so Drupal won’t have any address
  $message['to'] = '';
}

```

# Answer
> 6 votes
https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook\_mail\_alter/7

```
<?php
/**
 * Implements hook_mail_alter().
 */
function mymodule_mail_alter(&$message) {
  $message['send'] = FALSE;
}

```

# Answer
> 6 votes
## Drupal 8

For Drupal 8, you can turn on the Devel module mail handler through the configuration system.

With `drush` it would be:

```
drush -y pm-enable devel
drush -y config-set system.mail interface.default devel_mail_log

```

# Answer
> 4 votes
I usually use Reroute Email module for this case. It can reroute all email from dev to certain email. The email sent also specify where this email should be sent to.

# Answer
> 3 votes
I think that Mail Redirect module is perfect for you :) Another dirty way is install the SMTP module and set a wrong smtp ;)

# Answer
> 3 votes
This will work without devel and is safe in all three environments.

Add this in settings.php. Copy it and change the environment to `test` for Test.

```
// Stop email on dev.
if (isset($_SERVER['PANTHEON_ENVIRONMENT']) &&
  $_SERVER['PANTHEON_ENVIRONMENT'] === 'dev') {
  // @see MYMODULE_mail_alter().
  $conf['development_environment'] = TRUE;
}

```

Then in mymodule:

```
function MYMODULE_mail_alter(&$message) {
  if(variable_get('development_environment', FALSE)) {
    // First: Prevent the mail from being sent.
    $message['send'] = FALSE;

    // Next: Log the mail so it can be debugged if necessary
    watchdog('Development Env', 'The following email was not sent: !message', array('!message' => '<pre>' . print_r($message, TRUE) . '</pre>'));
  }
}

```

Credit for the mail alter idea goes to http://www.jaypan.com/tutorial/preventing-emails-being-sent-drupal-7-development-environment.

# Answer
> 2 votes
So you could put this in your settings.php or settings.local.php if you have specific ones for dev, staging & production.

```
if(module_exists('devel')) {
  // Use Devel's maillog
  $conf['mail_system'] = array(
    'default-system' => 'DevelMailLog',
  );
  // To set custom path
  // $conf['devel_debug_mail_directory'] = '/path/to/folder';
}
elseif (module_exists('mail_redirect')) {
  // Enable email rerouting.
  $conf['reroute_email_enable'] = 1;
  // Space, comma, or semicolon-delimited list of email addresses to pass
  // through. Every destination email address which is not on this list will be
  // rerouted to the first address on the list.
  $conf['reroute_email_address'] = "example@example.com";
  // Enable inserting a message into the email body when the mail is being
  // rerouted.
  $conf['reroute_email_enable_message'] = 1;
}

```

# Answer
> 2 votes
Here is the documentation page for this: https://www.drupal.org/docs/develop/local-server-setup/managing-mail-handling-for-development-or-testing

Another way to can do this that I haven't seen mentioned yet here would be to put this on your `settings.php` file:

```
// Prevent sending emails, store it in Drupal within the state system.
// Use drush sget system.test_mail_collector or
// \Drupal::state()->get('system.test_mail_collector', []); to see emails sent.
// @see \Drupal\Core\Mail\Plugin\Mail\TestMailCollector
$config['system.mail']['interface']['default'] = 'test_mail_collector';

```

This way you work around having to depend on an third party module.

This is what core does to test mail functionality, which is pretty nice, have a look at `\Drupal\Core\Test\AssertMailTrait` if you're curious.

# Answer
> 1 votes
Assuming that you are using the Mailsystem module, just go to `admin/config/system/mailsystem` and select `DevelMailLog`.

# Answer
> 1 votes
Set-up your SMTP to `localhost` and install MailCatcher (GitHub) which catches any message sent to it to display in a web interface.

### Installation

1. `gem install mailcatcher`
2. `mailcatcher`
3. Configure your `sendmail_path` in PHP to:

```
sendmail_path = /usr/bin/env catchmail -f some@from.address

```

or in Apache configuration:

```
php_admin_value sendmail_path "/usr/bin/env catchmail -f some@from.address"

```
4. Go to `http://localhost:1080/`
5. Send mail through `smtp://localhost:1025`

---

In Drush you can do like:

```
php -d sendmail_path="$(which catchmail)" drush.php some-command

```

# Answer
> 1 votes
if you do not want to touch Drupal configs, setup MailHog on your server to catch all the e-mails coming out of your application.

# Answer
> -1 votes
Enable SMTP Authentication Support module and you can directly turn off your SMTP Mail Server at `admin/config/system/smtp`.

---
Tags: emails, staging
---


# Question
Title: Tabs: invalidating cache tags does not lead to a rebuild of the tabs
I have a custom route defined with a custom access check. Apart from some more checks one of the rules for accessing the path is that a specific custom entity exists. The access check does the following:

```
  public function access(AccountInterface $account) {
    if ($entity_does_not_exist) {
      return AccessResult::forbidden()->addCacheTags(['my_unique_cache_tag']);
    }
  }

```

In my custom entity class I defined the postSave and postDelete methods to invalidate this tag every time an entity is created or deleted:

```
  public static function postDelete(EntityStorageInterface $storage, array $entities) {
    parent::postDelete($storage, $entities);
    foreach ($entities as $entity) {
      \Drupal::cache('render')->invalidate('my_unique_cache_tag');
    }
  }

  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
    parent::postSave($storage, $update);

    if (!$update) {
      \Drupal::cache('render')->invalidate(ParliamentPeriodCCController::getCacheTag('my_unique_cache_tag');
    }
  }

```

My problem is that my custom route is used as a secondary tab in my\_module.links.task.yml. What I found out so far is that the tabs are rendered in a block which really gets my unique cache tag (as I see in cache\_render table - this is why I defined `\Drupal::cache('render')` above - `\Drupal::cache()` did not work neither) but it seems it never gets invalidated. When I enter a page where the secondary tab was not created because no entity exists it is still not shown when I create the entity afterwards. But when I delete the entry for the block from cache\_render it is rendered correctly.

# Answer
> 1 votes
Two suggestions to improve caching:

1. Even if you don't want to make a decision to allow or deny access you can return a neutral result to add cache metadata.
2. The custom cache tag can be replaced by the list tag ENTITY\_TYPE\_list, which is invalidated automatically when entities are added or deleted.

The resulting code:

```
  public function access(AccountInterface $account) {
    if ($entity_does_not_exist) {
      return AccessResult::forbidden()->addCacheTags(['my_entity_list']);
    }
    return AccessResult::neutral()->addCacheTags(['my_entity_list']);
  }

```

postDelete() and postSave() are no longer necessary.

---
Tags: 8, navigation, caching
---


# Question
Title: Custom view sort plugin not working only when used in table sorting
We have a view of committee memberships (= custom entity). The committee memberships hold references to the committee and the politician and have a field "role". In a view we want to output all committee memberships in a logical order: chairperson first, the vice chairperson, foreperson, spokesperson and member. As you can see alphabetical order is not suitable.

We defined a custom view sort plugin which is playing nice on simple views where the sorting is set in the views configuration. However on a table view when selecting the column for the sorting by role it is not called.

Examples:

We defined the plugin in the following way in a class extending EntityViewsData:

```
$data['committee_membership']['committee_role']['sort']['id'] = 'sort_committee_membership';

```

The plugin is that:

```
/**
 * Sort handler for sorting committee memberships by list key position.
 *
 * @ingroup views_sort_handlers
 *
 * @ViewsSort("sort_committee_membership")
 */
class SortCommitteeMembership extends SortPluginBase {

  public function query() {
    $this->ensureMyTable();
    $field_storage = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('committee_membership')[$this->field];
    $allowed_values = array_keys(options_allowed_values($field_storage));
    $formula = 'FIELD(' . $this->tableAlias . '.' . $this->field . ', ' . implode(', ', array_map(array(Database::getConnection(), 'quote'), $allowed_values)) . ')';

    $this->query->addOrderBy(NULL, $formula, $this->options['order'], $this->tableAlias . '_' . $this->field . '_keys');
  }

}

```

Is there something missing which is needed to implement when the sorting is exposed?!

# Answer
> 3 votes
The problem is that for click sorting it seems that not the view sort plugin is used but the field handler which holds a method `clickSort`

So here is the solution:

1.) I defined a custom field handler. This can be done in hook\_views\_data or hook\_views\_data\_alter. I did it in my custom views EntityViewsData extending class:

```
$data['custom_entity']['committee_role']['field']['id'] = 'committee_role';

```

2.) Then I defined the field handler class where clickSort can be overwritten.

```
use Drupal\Core\Database\Database;
use Drupal\views\Plugin\views\field\EntityField;

/**
 * @ingroup views_field_handlers
 *
 * @ViewsField("committee_role")
 */
class CommitteeRole extends EntityField {

  public function clickSort($order) {
    // No column selected, can't continue.
    if (empty($this->options['click_sort_column'])) {
      return;
    }

    $this->ensureMyTable();
    $field_storage = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('committee_membership')[$this->field];
    $allowed_values = array_keys(options_allowed_values($field_storage));
    $formula = 'FIELD(' . $this->tableAlias . '.' . $this->field . ', ' . implode(', ', array_map(array(Database::getConnection(), 'quote'), $allowed_values)) . ')';

    $this->query->addOrderBy(NULL, $formula, $order, $this->tableAlias . '_' . $this->field . '_keys');
  }
}

```

After clearing the caching the results in the table are sorted the same way as in the other view. Strange that there is an additional sorting logic in views when a table display is used and the sorting is done via column headers.

# Answer
> -1 votes
A solution could be, to take use of the search\_api module. After you've indexed the entities you want to display in the view, you can create a view based of the indexed items. That way you can get rid of the key, and only use the values. And no programming required.

As a bonus you get all kinds of sorts and facets to play around with.

---
Tags: 8, views
---


# Question
Title: Prevent Entityform Duplicate Submissions
I have a simple text entityform setup on my drupal website. I was wondering if there was a way to prevent users from submitting a submission that has already been submitted. I am new to using Rules, but my guess would be there is a way to do so using that.

Thanks

# Answer
You can try the Hide Submit moddule:

> Some users accidentally click the submit button more than once while waiting for their post to be saved. In some cases this may result duplicate postings or duplicate e-commerce orders.
>
> There are few ideas on how to solve duplicate postings but none is perfect. One of the solutions is a bit of jQuery to hide or disable the submit button after it has been clicked and replace it with an informative text such as "Processing..." .
>
> This module wraps that jQuery code and provides some options. Of course this, too, is not a perfect solution as it requires Javascript to be enabled. For browsers with Javascript disabled this module will have no effect at all.
> 1 votes

# Answer
Given that you'd like to avoid form submissions with similar data (which really means a combination of fields that are unique), I think the best option would be the Entity Unique module.
> 0 votes

---
Tags: forms, entities
---


title: Convert node ID from string to integer

text:
# Question
Title: Convert node ID from string to integer
Retrieve a node based on condition:

```
$query = \Drupal::entityQuery('node')
->condition('type', 'my_content_type')
->condition('title', 'my node title');
$nid = $query->execute();

```

The result of $nid is the correct node ID but the format is a string, (es: "123")

When I want to load the node by its ID, I write:

```
$node_id = Node::load($nid);

```

Doing this, the result I get is NULL because the variable $nid is holding a string (not integer). If I write the code like this:

```
$node_id = Node::load(123);

```

I get the node loaded.

How can I convert the variable string ($nid) as an integer ? I tried:

```
$nid_int = (int) $nid;
$node_id = Node::load($nid_int);

```

also I tried:

```
$nid_int = intval($nid);
$node_id = Node::load($nid_int);

```

But I alwas get result NULL

Thanks for your help

# Answer
> 2 votes
the `$query->execute();` return an array of key/value like `[KEY => nid1]`:
if you are sure you have only one node with that tittle you should get the first element of the array it's your nid try with:

```
 $query = \Drupal::entityQuery('node')
  ->condition('type', 'my_content_type')
  ->condition('title', 'my node title');
$nids = $query->execute();
// Get the nid in the array.
$nid = reset($nids);
$node = Node::load($nid);

```

---
Tags: 8, nodes
---


# Question
Title: How to attach variables to drupalSettings with ajax?
With the `page attachments` function, I can easily attach a library or some variables to drupalSettings.

Now however, I want to replace some HTML code with ajax AND attach some variables to drupalSettings. While the ajax call does work in replacing HTML, it does not work in attaching or passing along the variables to drupal Settings.

Is there a way I can do both? Here is my code.

```
public static function AddAJAXResponseCommands(AjaxResponse $response = NULL, array $params = []) {

  $modalSettings = [
    'id' => 1,
    'status' => true,
  ];

  $sample = [
    '#type' => "html_tag",
    '#tag' => "div",
    '#attributes' => ['class' => ['context-menu']],
    '#value' => "Dashboard",
  ];

  $sample['#attached']['library'][] = 'mylibrary/dashboard-js';
  $sample['#attached']['drupalSettings']['dashboard']['myVariables'] = $modalSettings;

  $response->addCommand(new ReplaceCommand('.context-menu', $sample));
  return $response;
}

```

When I attempt to access drupalSettings.dashboard.myVariables which I confirmed already works when I use the page attachment function, it does not work when using ajax calls. Instead I get myVariables is undefined.

I console logged drupalSettings and sure enough, my variables are no where to be found in there. How can I get it added? Is page attachment the only way to do this?

# Answer
> 6 votes
Use the SettingsCommand

```
$settings=['ajax_forms_test' => ['foo' => 42]]; /* An array of key/value pairs of JavaScript settings. */
$merge=TRUE; /* (Optional) Booleen Whether the settings should be merged into the global drupalSettings. */
$response->addCommand(new SettingsCommand($settings,$merge));

```

So your code would become something like this:

```
public static function AddAJAXResponseCommands(AjaxResponse $response = NULL, array $params = []) {

  $modalSettings = [
    'id' => 1,
    'status' => true,
  ];

  $sample = [
    '#type' => "html_tag",
    '#tag' => "div",
    '#attributes' => ['class' => ['context-menu']],
    '#value' => "Dashboard",
  ];

  $sample['#attached']['library'][] = 'mylibrary/dashboard-js';
  $merge = TRUE;
  $settings['dashboard']['myVariables'] = $modalSettings;
  $response = new AjaxResponse();
  $response
    ->addCommand(new ReplaceCommand('.context-menu', $sample))
    ->addCommand(new SettingsCommand($settings, $merge));
  return $response;
}

```

Dont forget to add use statement at the top. use Drupal\Core\Ajax\SettingsCommand;

---
Tags: 8, javascript, ajax
---


# Question
Title: Combine multivalue field rows with copy of same multvalue field
Having a list of pdfs using pdfpreview for image-preview I want to add an additional formatted text-field to this ouput. That's why I've created a copy of this field with a different formatter (e.g. rendered entity).

As this is a multivalue field I want to combine the values means having the new text-field underneath every preview-picture instead of having all preview pictures first and all rendered entities afterwards.

# Answer
> 0 votes
I've found the solution via media entities and "media pdf thumbnail"

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


title: Order a text field numerically in views

text:
# Question
Title: Order a text field numerically in views
I need to reorder my views results before display it.

This is my query

```
SELECT
commerce_product_field_data_field_magazine__field_data_field_numero.field_numero_value AS commerce_product_field_data_field_magazine__field_data_field, node.nid AS nid
FROM
{node} node
LEFT JOIN {field_data_field_magazine} field_data_field_magazine ON node.nid = field_data_field_magazine.entity_id AND (field_data_field_magazine.entity_type = 'node' AND field_data_field_magazine.deleted = '0')
INNER JOIN {commerce_product} commerce_product_field_data_field_magazine ON field_data_field_magazine.field_magazine_product_id = commerce_product_field_data_field_magazine.product_id
INNER JOIN {field_data_field_tipo} field_data_field_tipo ON node.nid = field_data_field_tipo.entity_id AND (field_data_field_tipo.entity_type = 'node' AND field_data_field_tipo.deleted = '0')
LEFT JOIN {field_data_field_numero} commerce_product_field_data_field_magazine__field_data_field_numero ON commerce_product_field_data_field_magazine.product_id = commerce_product_field_data_field_magazine__field_data_field_numero.entity_id AND (commerce_product_field_data_field_magazine__field_data_field_numero.entity_type = 'commerce_product' AND commerce_product_field_data_field_magazine__field_data_field_numero.deleted = '0')
WHERE (( (node.status = '1') AND (node.type IN  ('magazine')) AND (field_data_field_tipo.field_tipo_value IN  ('rivista', 'dvd')) ))
ORDER BY commerce_product_field_data_field_magazine__field_data_field ASC

```

and it works fine but I need the same view with a different ordering

```
ORDER BY ABS(commerce_product_field_data_field_magazine__field_data_field)

```

because the result's now order like

```
1 10 11 2 3 4 ..

```

but I need

```
1 2 3 4 10 11 ..

```

How can I achieve this changing of ordering?

ps\_ I can't change the text field type to int because I have some value like '5-6'

# Answer
> 1 votes
Can you use views instead? The Views Natural Sort module may help you

Otherwise, in drupal 7 you can go with

```
$query->orderby( 'CAST(n.title AS SIGNED)', 'ASC');

```

Check also CAST Mysql documentation

# Answer
> 0 votes
for the Drupal8 we can do like:

```
$query->addExpression('CAST(n.title AS SIGNED)', 'title_as_int');
$query->orderby( 'title_as_int', 'ASC');

```

---
Tags: 7, views
---


# Question
Title: When confirming installation of modules, I get a server error (500)
I setup my D7 websites using MAMP and since a while I failed to activate modules... Whenever I save certain modules, I get a 500-error.

I don't think it has something to do with a `memory_limit` since the error appears almost instant...

I already tried to increase the permissions (777) on the `sites` folder, but no luck there.

This is what my `apache_error.log` says:

Any advice?

# Answer
> 0 votes
Hoeray! I found it myself :) It appears, you can increase the limit on multiple places like described on this page.

Thanks @Clive for the effort though!

# Answer
> 0 votes
I had the same error, and in my case the error was in my.ini (using Xamp here) the setting in question was max\_allowed\_packet which was too small! changing it seems to have fixed a lot of tiny error i had been getting including the error 500 when enabling any module.

EDIT : whoa i just noticed that was from 7 years ago... not sure what the policies are about answering year old posts... crazy that I was having the "same" issue today in 2020... anyway maybe it might help someone else one day :)

---
Tags: 7
---


# Question
Title: How to override the system timezone in settings.php?
I'm trying to override the site's timezone in settings.local.php.

Looking at the config file, this should be simple:

```
$ more system.date.yml
country:
  default: ''
first_day: 0
timezone:
  default: UTC
  user:
    configurable: true
    warn: false
    default: 0

```

but I've trying various combinations of this and none of them work:

```
$config['system.date']['timezone']['default'] = 'Europe/London';
$config['system.date.timezone.default'] = 'Europe/London';

```

# Answer
The first example (`$config['system.date']['timezone']['default'] = 'Europe/London';`) is the correct way to override config values in your settings.php file.

It sounds like you've hit an issue noted in the config override system docs:

> Note that values overridden via $config within `settings.php` **will not be viewable from the Drupal administration** interface (until #2408549: There is no indication on configuration forms if there are overridden values is fixed, until then you can use Configuration Override Warn or Config Override Inspector) or from inspection via drush (unless you add the `--include-overridden` flag). The administration interface displays the values stored in configuration so that you can stage changes to other environments that don't have the overrides.

So if you view `/admin/config/regional/settings` page or the `drush cget system.date timezone.default` command, it won't show the overridden value.

You can try something like `drush cget --include-overridden system.date timezone.default` or `drush eval 'print \Drupal::config("system.date")->get("timezone.default");'` to confirm your overridden value is actually being set in your settings.php
> 2 votes

---
Tags: configuration
---


# Question
Title: Content editor cannot view unpublished taxonomy terms when editing a node
We have a custom content type that has a Entity Reference field to a taxonomy vocabulary. The content editor is presented a list of check boxes to select their terms to attach to the node. Some of our terms are published and some aren't. When I am logged in as admin (user 1), I can see ALL of the terms to select from, but when a content editor is logged in, they are only seeing the published terms to select from. We want the editor to still be able to tag content with unpublished terms. I have tried every permission I can think of without just opening it up fully to a content editor. We have content moderation in place so the editors have semi locked down permissions in order to allow a content manager to review and publish the content.

Does anyone know the specific permission that would allow editors to see unpublished taxonomy terms on the node edit page?

# Answer
> 0 votes
You don't need to use permissions, just adjust the field's reference method.

Add a new entity reference display view that returns all taxonomy of the given type with the published = 1 filter removed (so it display all terms regardless of publish status).

Edit your entity reference taxonomy field for the relevant node type. Under the **Reference Type**, adjust **Reference method** to *Views: Filter by an entity reference view*, then select your newly created view.

After saving the field settings, the node form should display all taxonomy regardless of user permissions on viewing unpublished content.

---
Tags: taxonomy-terms
---


title: How to be sure that views are saved?

text:
# Question
Title: How to be sure that views are saved?
I just had a terrible learning experience. I spent several days building up a bunch of views, only to find that they vanished entirely from my site when I synchronized my configurations to handle another issue. They're gone. I have a dump of the db, but they're not on there either.

The funny thing is that not all of the views are gone. Some that I made several weeks ago are there, but the more recent ones are irrevocably lost.

And yes, I clicked "Save" on each view when I was creating it.

How can I be sure that this never happens again? What steps do I need to take save the views permanently in the db?

Version: Drupal 8.9.6

# Answer
> 3 votes
Shawn Conn's answer is what I needed. Going forward, I will now make it part of my routine to take snapshots of my configuration with `drush cex` and commit the changes. My mistake was believing that the views would be saved in the database.

---
Tags: views
---


# Question
Title: How do I name a mimemail-message.tpl.php template to be used with a specific webform?
I cant seem to get the naming of the `mimemail-message.tpl.php` correct in Drupal 7. I know the naming scheme says `"mimemail-message--[module]--[key].tpl.php"` but either I'm not understanding what the brackets represent or I'm doing something else wrong.

I've tried:

```
mimemail-message--webform--mywebformname.tpl.php
mimemail-message--webform--250.tpl.php

```

Just `mimemail-message.tpl.php` works, but I need different template layout depending on which webform is used.

Also, is mime mail not supposed to make use of `webform-mail-250.tpl.php` at all?

# Answer
As you can see in line 264 of webform.submissions.inc Webform uses `submission` as the key.

Thus it needs to be named

```
mimemail-message--webform--submission.tpl.php

```

There is no way to target a specific webform without some extra custom code work.

**mymodule.module**

```
function mymodule_mail_alter(&$message) {
  if ($message['module'] == 'webform') {
    $nid = $message['params']['node']->nid;
    $message['key'] = $nid; // set key to nid
  }
}

```

Now you can do

```
mimemail-message--webform--250.tpl.php

```
> 2 votes

---
Tags: 7, theming, webforms, mimemail
---


# Question
Title: Private filesystem does fire 403 on every role and file
Like the title might expect I am not able to view any file that i am delivering through the private file system. Only if I bypass the access check via role settings.

I tested it a minute ago with a fresh d8.9 installation. Here images are are delivered (statuscode: 200). I my main project I receive a 403. Why is that so ?

Drupal does create the private files and as admin (bypassing) I also can see the file. As non admin (authenticated user) I cannot.

How can I debug this issue? A theory I have read said something about varnish setting... I searched the whole project without finding any script mentioning "varnish". I spend now good 6 hours... checked roles, scripts and so on. I could now start a crazy adventure by deinstalling 80+ modules until it might work or somebody could give me a hint how I debug this madness?

Thanks in advance

Guests on the left | authenticated users on the right

# Answer
If you need to debug access at the Drupal application level, then look at `FileDownloadController::download`; it's the controller method for the `/system/files/{filepath}` path; you can use your tool of choice to inspect the execution flow from request to the returned response object.

If the issue is outside the Drupal application level (e.g. web server, varnish) then it will require further stack troubleshooting.
> 0 votes

---
Tags: 8, files
---


# Question
Title: Where to view Google Analytics "Track clicks on outbound links" results?
I am using Drupal's Google Analytics module 8.x-2.5. The module configuration has a check box for "Track clicks on outbound links", which I checked since the module was installed. However, I don't see outbound link stats in Google Analytics - am I missing something? Is there something else that needs to be done for setup?

# Answer
> 1 votes
The module tracks outbound links via GA event tracking. It will send a click action to GA under the **Outbound links** category. The metrics for this event category can be found in the **Behavior \> Events** menu in the GA interface.

---
Tags: google-analytics
---


# Question
Title: How to patch a file that is not in a module's git repo?
I want to patch `CheckoutCartEventSubscriber.php`, which can be found in `/web/modules/contrib/commerce/modules/checkout/src/EventSubscriber` when installed via composer.

So I cloned Commerce from the drupal.org git repository, navigated to the `/modules/checkout/src/`, and found that there is no **EventSubscriber** directory. All the other directories that can be found in the composer install exist except **EventSubscriber**.

The github repo browser doesn't show the EventSubscriber directory, either.

So where is this directory? How can I find the file to patch it?

# Answer
> 1 votes
That gihub repository looks to be outdated, as the last commit was made May 15, 2020

To see a module's repository, go to the projects page and click on on "Browse code repository"

Which will take you to the GitLab repository.

---

> So where is this directory?

Well... that directory doesn't exist. Maybe your composer.json already contains a patch that creates it? OR someone manually added that folder and file, as that folder and file is not officially part of Commerce.

---
Tags: commerce
---


# Question
Title: Returning custom array in lazy builder callback
I have to return a custom array from a lazy builder callback and then loop through that array in a Twig template for a custom block. Here is my code so far:

Custom block:

```
public function build() {

return [
  '#theme' => 'custom_theme',
  '#variables' => [
    '#lazy_builder' => [static::class . '::lazyBuilder', []],
    '#create_placeholder' => TRUE,
  ],
];
}

```

The callback

```
  public static function lazyBuilder() {

  //code above
      foreach ($vars as $var) {
        $arr[] = [
          'title' => $var->getTitle(),
          'body' => $var->body->value),
          'summary' => $var->summary->value,
        ];
      }
    }

    sleep(3); // For testing only
    return $arr;
  }

```

In my twig template

```
{% for var in variables %}
  <div>{{ var.title }}</div>
{% endfor %}

```

For each item I want to display its title, body and summary. Everything works fine if I return from the callback an array which has #markup inside, but I need to return my custom array.

If that's not possible it would be also OK if a lazy loaded the whole block not just the content inside it.

Thank you.

# Answer
> 2 votes
> I have to return a custom array from a lazy builder callback

You can return multiple `#markup` elements nested in the render array, also other render elements like `#plain_text`, which is more safe to output a title containing user input:

```
  'title' => ['#plain_text' => $var->getTitle()],

```

For the body field you need a more complex render element, see How to safely render node body on a custom variable?

---

> and then loop through that array in a Twig template

You can't loop through the array in the theme because you have set-up the variable to be lazy-built. The array doesn't exist at this point, only the placeholder. The array needs to be a proper render array which can be rendered recursively as explained above.

---

> If that's not possible it would be also OK if a lazy loaded the whole block not just the content inside it.

Blocks are lazy-built by default and placeholdered when meeting the auto-placeholder conditions. See https://www.drupal.org/docs/8/api/render-api/auto-placeholdering

---
Tags: views, blocks, caching
---