# Question
Title: How to get a section of the menu tree based on the current node?
I am currently struggling to wrap my head around how the menu tree and menu link services work for outputting part of a menu with some custom requirements. Admittedly I don't have to do this very often, but it seems like there must be a way.

I tried with Menu Block, but that does not seem to be able to do what I need to do.

First, when I am on level 3 and a certain content type, (or the parent route is nolink), I need to print the current level of the menu like this:

The menu links represent what is under the current page.

Second, if it is level 2+ (and *not* a certain content type), the section parent needs to sit on the top as a blue link, in a different treatment:

Third, if the current page in the menu is active, no siblings are printed, only this page menu link and its children:

I started here, in a menu block:

```
/** @var \Drupal\Core\Menu\MenuLinkManager $menu_link_manager */
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
$route_params = array('node' => $node->id());

$menu_links = $menu_link_manager->loadLinksByRoute('entity.node.canonical', $route_params, 'main');

// Attach the top parent, if we are at level 3 (for a project) or level 2 (for a basic page)
// top parent cannot go above level 3.... but also level 2?
// show the current node menu tree and its siblings
// show the siblings if the current page has no children

$parent = reset($menu_links)->getParent();
$uuid = str_replace('menu_link_content:', '', $parent);
$parent_menu_content = current(\Drupal::entityTypeManager()
  ->getStorage('menu_link_content')
  ->loadByProperties(array('uuid' => $uuid)));

$params = new MenuTreeParameters();
$params->setRoot($parent);
$params->setActiveTrail([$parent, reset($menu_links)->getPluginId()]);

$tree = $this->menuTree->load($parent, $params);
$built_tree = $this->menuTree->build($tree);

$link = end($parent_menu_content->link->getValue())['uri'];

$element = $this->menuTree->build($tree);
$build['#items'] = $element['#items'][$parent]['below'];

if ($link != 'route:<nolink>') {
  $build['#top_parent'] = $element['#items'][$parent];
}

if (empty($build['#cache']['contexts'])) {
  $build['#cache']['contexts'] = ['user.permissions'];
  $build['#cache']['tags'] = ['config:system.menu.main'];
}

return $build;

```

But the children of a link (in `below`) don't render correctly in Twig, its blank, and I am not sure if there is some easier way to do this.

`top_parent` is a new theme variable I have added to `menu` so I can render it separately in Twig.

Edit: `below` now renders right - I forgot to `{% import _self as menus %}` in my second macro.

# Answer
Found a way to satisfy all the cases without having to create multiple blocks (visibility rules would be odd) or create different menus. I could not achieve this by assuming a content type like in the question, because you could have the same content type nested until multiple areas of the menu, and not really know if the current depth you were at for it qualified as the parent (where the menu block should "begin" - not necessarily the parent of the page).

I decided to cheat a bit and use the URL and the alias pattern. If the current path matched a pattern, and the URL consisted of a certain amount of segments, I could tell I was in a specific part of the menu where the behavior should be different than others. In this case, it should use the current page and its children, instead of the parent of the current page and its siblings:

```
class MenuBlockEnhanced extends MenuBlock {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $node = \Drupal::routeMatch()->getParameter('node');

    // If we are not on a node route, get out.
    if (!$node) {
      return parent::build();
    }

    // If the menu being rendered is not specifically the sub nav, get out.
    if ($this->configuration["suggestion"] != 'subnav') {
      return parent::build();
    }

    $current_path = \Drupal::request()->getRequestUri();
    $parts = explode('/', $current_path);
    $build = parent::build();

    /** @var \Drupal\Core\Menu\MenuLinkManager $menu_link_manager */
    $menu_link_manager = \Drupal::service('plugin.manager.menu.link');
    $route_params = array('node' => $node->id());
    $menu_links = $menu_link_manager->loadLinksByRoute('entity.node.canonical', $route_params, 'main');
    $set_parent = TRUE;

    $params = new MenuTreeParameters();

    // I don't really know of another way to 'tell' we are on a project, since
    // a project can have projects under it. We can only rely on the path and
    // how many 'parts' are in the path - anything over 4 parts would be anything
    // nested in this section.
    if (preg_match('/programs-projects/i', $current_path) && count($parts) == 4) {
      $parent = reset($menu_links)->getPluginId();
      $set_parent = FALSE;
    } else {
      $parent = reset($menu_links)->getParent();
    }

    $uuid = str_replace('menu_link_content:', '', $parent);
    $parent_menu_content = current(\Drupal::entityTypeManager()
     ->getStorage('menu_link_content')
     ->loadByProperties(array('uuid' => $uuid)));

    $params->setRoot($parent);
    $params->setActiveTrail([$parent, reset($menu_links)->getPluginId()]);
    $tree = $this->menuTree->load($parent, $params);

    // Transform the tree using the manipulators you want.
    $manipulators = array(
      // Only show links that are accessible for the current user.
      array('callable' => 'menu.default_tree_manipulators:checkAccess'),
      // Use the default sorting of menu links.
      array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
    );
    $tree = $this->menuTree->transform($tree, $manipulators);

    $link = end($parent_menu_content->link->getValue())['uri'];

    $element = $this->menuTree->build($tree);
    $build['#items'] = $element['#items'][$parent]['below'];

    if ($link != 'route:<nolink>' && $set_parent) {
      $build['#top_parent'] = $element['#items'][$parent];
    }

    if (empty($build['#cache']['contexts'])) {
      $build['#cache']['contexts'] = ['user.permissions'];
      $build['#cache']['tags'] = ['config:system.menu.main'];
    }

    return $build;
  }

}

```

The caching strategy comes right from what would normally be there, frankly I probably do not even need to specify it since I am already calling `parent::build()` and just reduce that code.

In the template, I resolve the "do I print just siblings, or this page and its children?" by using the `in_active_path` check, and faking a control break in Twig macro (see: `break = true`):

```
{% import _self as menus %}

{{ menus.menu_links(items, attributes, 0, top_parent) }}

{% macro menu_links(items, attributes, menu_level, top_parent) %}
  {% import _self as menus %}

  {% if items %}
    {% if top_parent %}
      <ul class="secondary-nav__list">
        {%
          set parent_list_classes =
          [
            'secondary-nav__item',
            'secondary-nav__item--parent'
          ]
        %}

        {% set parent_link_classes =
          [
            'link',
            'link--left-arrow',
          ]
        %}

        <li{{ top_parent.attributes.addClass(parent_list_classes) }}>
          {{ link(top_parent.title, top_parent.url, { 'class': parent_link_classes }) }}
          {{ menus.menu_child_links(items, attributes, 0) }}
        </li>
      </ul>
    {% else %}
      {{ menus.menu_child_links(items, attributes, 0) }}
    {% endif %}
  {% endif %}
{% endmacro %}

{% macro menu_child_links(items, attributes, menu_level) %}
  {% import _self as menus %}

  <ul class="secondary-nav__list">
    {% set break = false %}
    {% for item in items if not break %}
      {%
        set list_classes =
        [
          'secondary-nav__item',
          item.in_active_trail ? 'is-active'
        ]
      %}

      <li{{ item.attributes.addClass(list_classes) }}>
        {{ link(item.title, item.url) }}

        {% if item.below and item.in_active_trail %}
          {% set break = true %}
          {{ menus.menu_child_links(item.below, attributes, menu_level + 1) }}
        {% endif %}
      </li>
    {% endfor %}
  </ul>
{% endmacro %}

```

The menu works exactly as asked for all cases, and will go all the way down to its maximum depth and back up the chain (with the parent blue link appearing up top).
> 3 votes

---
Tags: 8, navigation
---


# Question
Title: Preventing redirects from being cached for anonymous users
I have a content type that needs to redirect only when it is tagged as "External". All of these "External" items have a field where a URL is supplied for the redirect.

During initial setup of the content type the redirection was being done in the .theme file in preprocess\_html but we discovered that after the first time someone was redirected when accessing one of these nodes, it would get cached and the redirection would not longer happen.

I then built a module to do the redirection with and event subscriber and this fixed the problem when logged in as an admin but not for anonymous users.

For the third iteration, I built a module to set up middleware that implements HttpKernelInterface in order to do the redirection there. This particular content type had a url pattern so I used that to determine when the middleware should run based on the `$request->getPathInfo();` and then testing for the node type and the "External" tag being applied to it. That solved all of the redirection problems, but other started to pop up. For example, the edit form for all of the nodes started displaying on the the title field and nothing else and views using the content type would start displaying as empty as well.

Is there a more effective way of doing this redirection and avoiding the page cache than doing it with middleware or has anyone experienced an issue like this when implementing HttpKernelInterface?

handle function being used in the middleware:

```
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {

$newsPrefix = "/news";

$current_uri = $request->getPathInfo();
if(substr($current_uri, 0, strlen($newsPrefix)) === $newsPrefix){
  $path = \Drupal::service('path.alias_manager')->getPathByAlias($current_uri);

  if(preg_match('/node\/(\d+)/', $path, $matches)) {
    $node = \Drupal\node\Entity\Node::load($matches[1]);

    if (isset($node)) {

      $nodeType = $node->getType();
      if($nodeType === 'news'){

        if(isset($node->news_type_of_content) && isset($node->news_type_of_content->target_id)){
          $typeID = $node->news_type_of_content->target_id;

          if(isset($typeID)){
            $term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($typeID);
            $name = $term->getName();
          }

          if(isset($name) && $name === "External" && isset($node->news_source_url->value)){

            $response = new RedirectResponse($node->news_source_url->value, 302);
            $response->send();
            exit;
          }
        }
      }
    }
  }
}
return $this->httpKernel->handle($request, $type, $catch);

```

}

# Answer
> 2 votes
Solution ended up being an event subscriber with a cacheable response:

```

<?php

namespace Drupal\news_redirect\EventSubscriber;

use Drupal\Core\Routing\TrustedRedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class NewsRedirectSubscriber implements EventSubscriberInterface {

  public function redirectMediaCoverage(GetResponseEvent $event) {

    $node = \Drupal::routeMatch()->getParameter('node');
    if (isset($node) && $node instanceof \Drupal\node\NodeInterface) {

      $nodeType = $node->getType();

      if($nodeType === 'news'){

        $typeID = $node->news_type_of_content->target_id;

        if(isset($typeID)){

          $term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($typeID);
          $name = $term->getName();

        }

        if(isset($name) && $name === "Media Coverage" && isset($node->news_source_url->value)){

          $url = $node->news_source_url->value;

          if(isset($url)){

            $response_headers = [
              'Cache-Control' => 'no-cache, no-store, must-revalidate',
            ];

            $response = new TrustedRedirectResponse($url, '302', $response_headers);
            $response->addCacheableDependency($node);
            $event->setResponse($response);
          }

        }

      }

    }

  }

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

}

```

---
Tags: 8, caching
---


# Question
Title: Hide contextual filter parameter from view url
I'm using Views to create a view which shows list of contents. The requirements of the view is something like this:

* The page display url must be `/mycontents`
* The contents must be filtered by current user(The content's author must be current user).

And what I did:

* Set `Page settings > Path` to `/mycontents`
* In `Advanced` \> `Contextual Filters` , add `Authored by`
* In the contextual filter's `When the default value is not in the url` section, checked `Provide default value` and selected `User ID from logged in user`.

The problem is that after saving the view, the actual url of the view becomes `/mycontens/{uid}`. Is there any way to remove the `{uid}` from the path?

# Answer
> 1 votes
I don't think this is possible if you show the view as a page, but you might be able to solve the problem by creating a custom route and rendering the view on that page, where you fetch the `uid` programatically.

You must do something like this in your Controller:

```
$user_id = 1;
$args = [$user_id];
$view = Drupal\views\Views::getView('my_view_id');
if (is_object($view)) {
  $view->setArguments($args);
  $view->setDisplay('page');
  $view->preExecute();
  $view->execute();
  return $view->buildRenderable('page', $args);
}

```

# Answer
> 0 votes
Jdrupal's answer totally makes sense, but as some custom modules in my site implements hook\_query\_alter, I used it again to keep it easy to understand for other developers. The code goes like this:

```
/**
 * Implements hook_views_query_alter().
 */
function MY_MODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() !== 'MY_VIEW') {
    return;
  }
  $uid = \Drupal::currentUser()->id();
  $snipped = "node_field_data_node_field_revision.uid = $uid";
  $query->addWhereExpression(0, $snippet);
}

```
* I took `node_field_data_node_field_revision.uid` from SQL query shown in the view preview (which needs to be enabled in `/admin/structure/views/settings`).
* If you add a filter this way, the contextual filter needs to be deleted.

---
Tags: 8
---


# Question
Title: How do I add an AJAX action on a select element in a ContentEntityForm to change the value of another select element
I have a ContentEntityForm with two select elements category and data\_type. I want to load the options for the second select element when the first select element changes. I have tried to add the following in the buildForm function of the ContentEntity form but this does not seem to be adding the ajax trigger to the element. Any thoughts on what I am doing wrong?

```
$form['category']['#ajax'] = [
  'callback' => '_ajax_form_category_change',
  'event' => 'change',
  'wrapper' => 'ajax_id_data_type',
  'method' => 'replace',
];
$form['data_type']['#prefix'] = '<div id="ajax_id_data_type">';
$form['data_type']['#suffix'] = '</div>';

```

\_ajax\_form\_category\_change is a function in my module

```
function _ajax_form_category_change($form, $form_state) {
  return $form['data_type'];
}

```

I have also added a form\_alter in my module to change the options of $form\['filing\_type'\].

# Answer
**SOLUTION**: Got this working with the following. You have to set the `#ajax` property on the `widget`

```
// Set the ajax function to run on the change of filing category.
$form['category']['widget']['#ajax'] = [
  'callback' => '_ajax_form_category_change',
  'event' => 'change',
  'wrapper' => 'ajax_id_data_type',
  'method' => 'replace',
];

```
> 0 votes

---
Tags: 8, ajax
---


# Question
Title: Change field value with hook_views_pre_render()
I'm using Views in 8.4.0 and attempting to change the output of a field value with hook\_views\_pre\_render(). The default value of the field is a node ID. The intent is to replaced the value with a static string depending on a whether or not it's contained in a predefined array using in\_array().

The aforementioned is relatively straightforward.

I begin by looping through the results:

```
  for ($i = 0; $i < count($view->result); $i++) {
    if (isset($view->result[$i]->node_field_data_node__field_lesson_nid)) {
      $viewed = in_array($view->result[$i]->node_field_data_node__field_lesson_nid, $viewed) ? 'yes' : 'no';
      // Replace the default Node ID value with $viewed.
      ...
    }
  }

```

The array $viewed contains a list of predefined node IDs. If the node ID exists in the array "yes" is output otherwise "no".

The problem is how to output the value for each row of results within the View object.

I tried the following at the above ellipsis:

```
      $view->field['nid_2']->options['alter']['text'] = $viewed;
      $view->field['nid_2']->options['alter']['alter_text'] = TRUE;

```

"nid\_2" is the token for node\_field\_data\_node\__field\_lesson\_nid.

The problem is this changes the field value for every row. The last row in the results determines the value. (The View also has multiple joins (relationships) which further compounds the complexity.)

So my dilemma is where to replace the value within each row of the $view-\>result.

# Answer
> 0 votes
I was trying to do something similar as well. I had an integer field and I wanted to replace the integer column with a string value. That was not working. So I had to add a separate string field, maintained the integer field as a hidden field and then overwrote the string field. The code that worked is given below.

```
function module_views_pre_render(ViewExecutable $view) {
  // Change the comments column in the list of filings table in the view case
  if ($view->id() == 'my_view') {
    foreach ($view->result as $key => $value) {
      $custom_id = $value->_entity->get('custom_id')->value;
      $string = convert_id_to_string_get_user_name($custom_id);
      $value->_entity->set('string_field', $string);
    }
  }
}

```

There is documentation and sample snippets here but looks like it needs more documentation.

https://api.drupal.org/api/drupal/core!modules!views!views.api.php/function/hook\_views\_pre\_render/8.2.x

---
Tags: views, hooks
---


# Question
Title: Displaying a block only for nodes of a specific content type, how do I check the content type using PHP?
I have a block which I would only like displayed on a KYN node. I'm currently using the option to display the block only on pages with "node/\*" which worked when I only was using one node type but now that I have two (kYNs and Pages) I need to come up with a solution.

I'd like to use some PHP that returns `TRUE` when the content type of a node *KYN*.

How can I achieve this?

# Answer
> 11 votes
```
// Only show if $match is true
$match = FALSE;

// Which node types
$types = ['kYn'];

// Match current node type with array of types
if (arg(0) == 'node' && is_numeric(arg(1))) {
  $nid = arg(1);
  $node = node_load($nid);
  $type = $node->type;
  $match |= in_array($type, $types);
}

return $match;

```

source : http://drupal.org/node/115419

# Answer
> 2 votes
To expand on sheena\_d's comment:

In Drupal 7 showing a block for one or more specific node types is available out of the box, with no need to write any PHP.

Where you would normally add PHP in the block 'visibility settings' select 'content types' from the menu on the left. Then select the content types you wish the block to display on.

I hope this helps simplify this for someone.

# Answer
> 1 votes
Blocks don't know nothing about the content area, so you have to check other conditions, like the current Drupal path:

```
$is_kyn_page = false;

if (arg(0) == 'node' && is_numeric(arg(1))) {
  $node = node_load(arg(1));
  if ($node && $node->type == 'kYN') {
    $is_kyn_page = true;
  }
}

```

Note that `'kYN'` is the machine name of the node type, not the human readable name.

# Answer
> 0 votes
If you are asking as administrator of a Drupal site, you don't need to write PHP code to achieve what you described: Whenever it's a block you created from the UI, or it's a block implemented from a module, you can change for which content types the block is shown.

On admin/structure/block, find the block you want to show only for some content types. (In the following screenshots, I will use the *System help* block as example.)

>

Click on the *configure* link that you find at the right side. You will access the settings for that block.

>

Click on *Content types*. You will get the list of content type defined in the site.

>

As the description says, selecting a content type will make the block appear on the nodes of those content types. Not selecting any content type will make the block appear on every node. (It means, there isn't the need to select every content type to show the block for all the nodes.)

If you are asking for a block implemented by a module you develop, then you can decide when the block is shown, in `hook_block_view()`.

```
function mymodule_block_view($delta = '') {
  switch ($delta) {
    // Replace 'block_id' with the block identifier.
    case 'block_id':
      // $node->type is case sensitive; use the exact content type identifier.
      if ($node = menu_get_object() && $node->type == 'KYN') {
        // Add the block title in $block['subject'],
        // the block content in $block['content'], and return $block.
      }
      break;
  }
}

```

I used `menu_get_object()` because it loads the correct node object, even when the page is for a node revision (for example, /node/1/revisions/2/view).

---
Tags: 7, nodes
---


title: Need help with twig test template

text:
# Question
Title: Need help with twig test template
I'm trying to create a test twig template in drupal 8, I followed "Create custom twig templates for custom module" from their website but it's not working for me for some reason. This is what I have:

Contents of folder test\_twig\_template:

test\_twig\_template.info.yml:

```
name: Test Twig Theme
type: module
description: Module to test if twig theme is working as intended
package: Custom
version: 1.0.0
core: 8.x

```

test\_twig\_template.module:

```
<?php
function test_twig_template_theme($existing, $type, $theme, $path) {
  return [
    'my_template' => [
      'variables' => ['test_var' => NULL],
    ],
  ];
}

```

test\_twig\_template.routing.yml:

```
test_twig_template.theme:
      path: /twig
      defaults:
        _controller: Drupal\test_twig_template\Controller\TestTwigTemplateController::content
        _title: 'Twig title'
      requirements:
        _permission: 'access content'

```

Code inside test\_twig\_template/src/Controller/TestTwigTemplateController.php:

```
<?php
namespace Drupal\test_twig_template\Controller;
use Drupal\Core\Controller\ControllerBase;

class TestTwigTemplateController extends ControllerBase {
  public function content() {
    return array(
      '#title' => 'Test Twig title',
      '#theme' => 'my_template',
      '#test_var' => $this->t('Test Value'),
    );
  }
}

```

And finally inside test\_twig\_template/templates/my-template.html.twig I have:

```
  <p>Test twig template!</p>
  <p>test_var: {{ test_var }}</p>

```

Thing is if I remove this "'#title' =\> 'Test Twig title'," from my controller nothing gets displayed on my custom page. Otherwise it just displays this title "Test Twig title". Am I missing a call for twig somewhere or are my hooks\_theme() not properly set up?

# Answer
It looks like you are messing around with your naming.

Since your module is called `test_twig_template` you must use that name for hooks and namespaces etc.

Fix these things and it should work.

> * Rename your `hook_theme()` from `test_twig_theme` to `test_twig_template_theme`.
> * Call your route `test_twig_template.theme`.
> * Your controller definition in your route must look like this, `_controller: \Drupal\test_twig_template\Controller\TestTwigThemeController::content`.
> * The namespace in your controller must be `namespace Drupal\test_twig_template\Controller;`.
> * Rename `test_twig_template/src/Controller/TestTwigController.php` to `test_twig_template/src/Controller/TestTwigThemeController.php` (the file name must match the class name).

That should be all, since your module is called `test_twig_template` it's important to use that name in all namespaces for your code to work properly :)

And then as @Hudri mentions your template shall only contain:

```
<p>Test twig template!</p>
<p>test_var: {{ test_var }}</p>

```

Head and body tags are provided by a general template in your theme.
> 1 votes

---
Tags: 8, theming
---


# Question
Title: How can I get the content type of a node given its node ID?
I have a URL like *track-new/15/51*. `arg(2)` returns `51`.

How can I check if the content type of the node whose ID is `51` (the value returned from `arg(2)`) is `'artist'`?

# Answer
If the value returned from `arg(2)` is a node ID, you can load the node with `node_load()`. This will return a node object, which contains its content type.

```
$node = node_load(arg(2));
$content_type = $node->type;

```
> 5 votes

# Answer
Although I am a big fan of `node_load()`, it is possible to get the `type` of a node from a node `nid` in a more resource friendly way. Here's a helper function to get a node's `type` given a `nid`:

```
/**
 * Given a node id, this returns the node's type or NULL if it doesn't exist.
 * @param $nid
 * @return {String|NULL}
 */
function example_get_node_type($nid) {
  $query = db_select('node', 'n')
    ->fields('n', array('type'))
    ->condition('n.nid', $nid)
    ->execute();
  $result = $query->fetchObject();
  return $result->type;
}

```

Then you can use it with something like:

```
if (example_get_node_type(arg(2)) == 'artist') {
  // Do something...
}

```

Or if you already have the node id, something like this:

```
$nid = 123;
if (example_get_node_type($nid) == 'artist') {
  // Do something...
}

```
> 2 votes

# Answer
Use `menu_get_object()` to retrieve data loaded by the current menu-router item. In your case you can get to the node like this:

```
$node = menu_get_object('node', 2);
$node->type;

```
> 1 votes

# Answer
A bit of validation before calling **node\_load** is never harmful:

```
if (arg(2) && is_numeric(arg(2)) {
    $node = node_load((int) $a2);
    $type = $node->type;
}

```
> 1 votes

# Answer
You can use something like this:

```
$menu_item = menu_get_item();

    // Test if this is a term page.
    if (!strncmp($menu_item['path'], 'taxonomy/term/%', 15)) {
        $obj = menu_get_object('taxonomy_term', 2);

```
> 0 votes

# Answer
If the route for that path is, for example, track-new/%/%node or track-new/%user/%node, I would use the following code.

```
if ($node = menu_get_object('node', 2)) {
  $content_type = $node->type;
}

```

If the route for that path is, for example, track-new/%/% or track-new/%user/%, I would use the following code.

```
$nid = arg(2);
if (!empty($nid) && is_numeric($nid) && ($node = node_load($nid))) {
  $content_type = $node->type;
}

```

`menu_get_object('node', 2)` doesn't work with a route like track-new/%/% because it expects the load function for the last part of the path to be `node_load()`, which isn't true for a route like track-new/%/%.
In fact, the code used from `menu_get_object()` is the following one.

```
  $router_item = menu_get_item($path);
  if (isset($router_item['load_functions'][$position]) && !empty($router_item['map'][$position]) && $router_item['load_functions'][$position] == $type . '_load') {
    return $router_item['map'][$position];
  }

```

I would always use `node_load()` when I want to load the node object associated with the current path independently from how the route has been defined.

I am using `node_load()` instead of querying directly the database because:

* It's possible that I would need other node properties, even if that could happen in future versions of the module I am writing
* The nodes loaded with `node_load()` are cached in memory, which means that the code I am using could not even cause any database query
> 0 votes

---
Tags: 7, nodes
---


# Question
Title: How to declare one custom module's dependency on another custom module
I'm developing a set of site-specific custom modules, and one of them depends on the other one being enabled.

I'd like to declare this dependency in the `.info.yml` file, but the docs only show how to declare dependencies on contrib projects:

> Dependencies should be namespaced in the format {project}:{module}, where {project} is the project name as it appears in the Drupal.org URL (e.g. drupal.org/project/views) and {module} is the module's machine name.

How do I declare a dependency on a module that is only found in the local codebase?

# Answer
Try this just like contrib projects.

```
dependencies:
  - your_module_name

```
> 13 votes

# Answer
Below is the more specific answer to load specifc library

```
dependencies:
  - <your_module_name>/<library_name>

```

Hope this gives an idea to load a specif library from the list of libraries in \*.libraries.yml file
> 1 votes

---
Tags: 8
---


# Question
Title: Is there any way to adjust the items per block options?
In Drupal 8, whenever you create a view block, you have the option to specify the number of items displayed in that view block which is awesome.

Currently, you can choose between 1, 5, 10, and 20. Is there any way to change this to include 1, 2, 3, 4, 5" or just be able to manually enter a number?

I was really excited about this feature and need to use it, but I need to really choose between 1, 2 or 3 items per block.

Edit: I'm referring to the block management screen, not the views configuration screen.

# Answer
> 3 votes
Thanks to the answer @Berdir provided, I've been able to replace the restrictive select field with a more flexible number field.

## In mymodule.module

The `form_id` is `block_form` (and`panels_edit_block_form` and `panels_add_block_form` for Panelizer). Change the `#type` to `number` to make it so that you can input a number. Unset the `#options` to avoid validation errors (Invalid choice).

```
/**
 * Implements hook_form_alter.
 *
 * Changes the input type of the "Items per block" setting of
 * a view-block in Blocks/Panelizer from 'select' to 'number',
 * so that amounts other than 5, 10, 20 and 40 can be chosen.
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if (in_array($form_id, ['block_form', 'panels_edit_block_form', 'panels_add_block_form'])) {
    if (isset($form['settings']['override']['items_per_page'])) {
      $form['settings']['override']['items_per_page']['#type'] = 'number';
      unset($form['settings']['override']['items_per_page']['#options']);
    }
  }
}

```

# Answer
> 2 votes
Yes, the options are hardcoded in `\Drupal\views\Plugin\views\display\Block::blockForm()` (located in core/modules/views/src/Plugin/views/display/Block.php). It should be relatively possible to customize them with a form alter though, other than in there, the options are nowhere expected to be those values, I think.

# Answer
> 1 votes
If i understood correctly, you are talking about the "Items per block" when we create the views block. But I am getting the option of 0,1,2,3,4.....as shown in the first image. Moreover if this is the issue, you can even change this setting after entering to the views user interface under PAGER option(as shown in second image), items per page.

# Answer
> 0 votes
I think I understand this issue and can help solve it without hard coding. Unfortunately if you management doesn't want to do the adjustment in views this wont work for you. Simply set the block configuration for items per block for default setting first. Then go to your view and under pager set at display a specified number of items and set the number of items to the actual number you want. Save the view and to check to see if it is set, return to your block configuration and you should see your number set in the block.

# Answer
> 0 votes
It's obviously a good idea to re-use a views block in several places without the need to create display copies only because the desired number of items is different.

There's a good chance this patch makes it into Drupal core 8.9: https://www.drupal.org/project/drupal/issues/3083379

(Allowing 1, 2, 3, 4, 5, 6, 10, 12, 20, 24, 40, 48 items per block).

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


# Question
Title: How can I see a log of emails that Drupal has sent?
How can I see a log of emails that Drupal 7 has sent? It would be handy for things like troubleshooting registration issues... to see that registration emails are actually being sent.

# Answer
Drupal doesn't keep hold of that information, so your server mail logs are the place to look.

Some email operations are recorded to the watchdog, but not all. You can get a look at a few of those ops with a simple query like this

```
SELECT * FROM watchdog WHERE message LIKE '%email%'

```

That'll get you false positives, but also should show you what operations are actually recorded (welcome message sent, new password sent, etc.).

For future reference, you can use either of these modules to log outgoing mail:
> 6 votes

# Answer
There is also the mail\_logger module
> 0 votes

---
Tags: 7, users, emails
---


# Question
Title: Paragraph image URI with image styles in paragraphs-item.tpl
I have Paragraph bundle with Multi Value Image Field which is limit of 3 numbers. i tried to print these three images separately because i want to used different image styles for each images. I tried like this:

```
<img src="<?php print image_style_url('size_400x600', $node->field_image['und'][0]['uri']); ?>"/>
<img src="<?php print image_style_url('size_750x524', $node->field_image['und'][1]['uri']); ?>"/>
<img src="<?php print image_style_url('size_550x365', $node->field_image['und'][2]['uri']); ?>"/>

```

In the code it display the uri without the file name like this:

```
<img src="http://localhost/drupal/sites/default/files/public/styles/size_400x600/public?itok=3dkOjU1O">

```

What will be the correct way to do this?

# Answer
> 1 votes
Probably your best bet is to have something along the following in the 'paragraph--ptype.tpl.php' file:

```
<?php print theme('image_style', array('style_name' => 'size_400x600', 'path' => $field_image['und'][0]['uri'])); ?>
<?php print theme('image_style', array('style_name' => 'size_750x524', 'path' => $field_image['und'][1]['uri'])); ?>
<?php print theme('image_style', array('style_name' => 'size_550x365', 'path' => $field_image['und'][2]['uri'])); ?>

```

Where ptype is obviously the paragraph type that has this field.

*I originally answered for Drupal 8 because I missed the D7 tag. Doh! I'm leaving the original answer below for reference.*

---

First, a good way to apply an image style in an image field template:

```
{% for item in items %}
  {{ item.content|merge({'#image_style': 'size_400x600'}) }}
{% endfor %}

```

For your use case, you could do something like:

```
{% for item in items %}
  {% set style = 'size_400x600' %}
  {% if loop.index0 == 1 %}
    {% set style = 'size_750x524' %}
  {% elseif loop.index0 == 2 %}
    {% set style = 'size_550x365' %}
  {% endif %}
  {{ item.content|merge({'#image_style': style}) }}
{% endfor %}

```

However, since the twig code is starting to get complicated, you should probably think about handling it in a preprocess function.

Alternatively, you can do some of this at the paragraph template level (assuming the image field is on the paragraph):

```
{% if not paragraph.field_image.isEmpty() %}
  {% if not paragraph.field_image[0].entity.uri.isEmpty() %}
    {% set img_url = paragraph.field_image[0].entity.uri.value | image_style('size_400x600') %}
    <img src="{{ img_url }}">
  {% elseif not paragraph.field_image[1].entity.uri.isEmpty() %}
    {% set img_url = paragraph.field_image[1].entity.uri.value | image_style('size_750x524') %}
    <img src="{{ img_url }}">
  {% elseif not paragraph.field_image[2].entity.uri.isEmpty() %}
    {% set img_url = paragraph.field_image[2].entity.uri.value | image_style('size_550x365') %}
    <img src="{{ img_url }}">
  {% endif %}
{% endif %}

```

You will need the twig\_tweak module for that. Some of the safety checks in there may be extraneous. YMMV. As before, the complex twig code means this would be good to put into a preprocess function.

# Answer
> 1 votes
This is working code on how to do this in Twig without contrib. You can change the '#style\_name' parameter to play with making this dynamic for a multifield.

```
  {% for item in content.field_image['#items'] %}
    {% set image = {
      '#theme':      'image_style',
      '#style_name': 'medium',
      '#uri':        item.entity.uri.value,
      '#alt':        item.alt,
      '#width':      item.width,
      '#height':     item.height
    } %}
    {{ image }}
  {% endfor %}

```

---
Tags: 7, theming, paragraphs
---


title: menu access callback per role

text:
# Question
Title: menu access callback per role
I'm trying to implement an access callback per role for a specific menu item, but other roles can view that menu item also. Any tip is welcome.

```
/**
 * Implements hook_menu();
 */
function MODULENAME_menu() {

  global $user;

  $items['admin/backoffice/production/taxonomie'] = array(
    'title' => 'Taxonomie',
    'type' => MENU_LOCAL_TASK,
    'weight' => 0,
    'page callback' => 'MODULENAME_backoff_taxonomy',
    'access callback' => 'MODULENAME_user_has_role',
    'access arguments' =>  array($user, array('éditeur taxonomie', 'administrator')),
    );

  return $items;
}

function MODULENAME_backoff_taxonomy(){
  module_load_include('inc', 'taxonomy', 'taxonomy.admin');
  $form = drupal_get_form('taxonomy_overview_vocabularies');
  drupal_set_title('Backoffice - Taxonomie');
  return drupal_render($form);
}

function MODULENAME_user_has_role($user,$roles) {
  foreach ($roles as $role) {
    if (in_array($role, $user->roles)) {
      return TRUE;
    }
  }
  return FALSE;
}

```

# Answer
To have a single `access callback` handle a dynamic number of roles which varies per menu link, try something like this in `hook_menu()`...

```
// hook_menu()
$items['foo'] = array(
  /* ... */
  'access callback' => 'MODULENAME_user_has_role',
  'access arguments' =>  array('éditeur taxonomie', 'administrator'),
);
$items['bar'] = array(
  /* ... */
  'access callback' => 'MODULENAME_user_has_role',
  'access arguments' =>  array('some other role'),
);

```

Then your `access callback` implementation:

```
function MODULENAME_user_has_role() {
  global $user;
  $roles = func_get_args();
  foreach ($roles as $role) {
    if (in_array($role, $user->roles)) {
      return TRUE;
    }
  }
  return FALSE;
}

```

That should do it.

**Some alternatives**

Remove the `global $user` and `access arguments` from `hook_menu()`.

Then change your `access callback` function implementation to this:

```
function MODULENAME_user_has_role() {
  global $user;
  $roles = array('éditeur taxonomie', 'administrator');
  foreach ($roles as $role) {
    if (in_array($role, $user->roles)) {
      return TRUE;
    }
  }
  return FALSE;
}

```

Since `hook_menu()` is invoked only when the menu router is being rebuilt (e.g. a cache clear, typically done by an admin or drush), `global $user` is not usually very useful from within that function. Instead, an `access callback` function is invoked at a more appropriate time (i.e. when the page is being viewed, or a menu link is about to be shown \[or not\] in a menu), at this point it is much easier to make a decision about the current user's context.

To make the `access callback` more generic, and be able to handle multiple menu link paths, I'll typically use a switch/case on an `arg()` to further curate the context:

```
switch (arg(3)) {
  case 'taxonomie':
    // do stuff...
    break;
}

```
> 2 votes

# Answer
A small addition I would make would be to do a check for UID = 1 like the rest of D7. A little late but hope it might helps some one.

```
function MODULE_user_has_role() {
  global $user;
  if ($user->uid == 1) {
    return TRUE;
  }
  $roles = func_get_args();
  foreach ($roles as $role) {
    if (in_array($role, $user->roles)) {
      return TRUE;
    }
  }
  return FALSE;
}

```
> 1 votes

---
Tags: users, routes
---


# Question
Title: Entity reference view depending on other field
I have a custom content type that contains an entity reference field (field\_referencefield) and one more field as select box (field\_triggerfield).

The values of field\_referencefield should depend on the selection of field\_triggerfield. This should happen in the create node form. I.e. If I change the selected item in field\_triggerfield during node creation, different values for field\_referencefield should be available. Maybe this can be achieved using views reference.

# Answer
### Step 1

On the field definition for the reference field that is dependent on another field you are going to change the reference method to views

### Step 2

1. You'll need to create a reference view for this data.
2. Make sure to add a contextual field/relationships/etc on the reference view that takes the other value from your form that helps it pre-filter the autocomplete results.

### Step 3

in a module or wherever hook into hook\_form\_alter and replace the reference field

```

/**
 * implements hook_form_alter
 *
 * @param array $form
 * @param array $form_state
 * @param string $form_id
 */
function my_module_form_alter(&$form, $form_state, $form_id) {

  if (in_array($form_id, ['node_mycontenttype_form', 'node_mycontenttype_edit_form'])) {
    // Add a wrapper around the reference field.
    $form['field_referencefield']['#prefix'] = '<div id="some-wrapper">';
    $form['field_referencefield']['#suffix'] = '</div>';

    // Add an ajax callback that replaces the contents of the wrapper.
    $form['field_triggerfield']['widget'][0]['target_id']['#ajax'] = [
      'callback' => 'mymodule_field_mycontenttype_trigger',
      'wrapper' => 'some-wrapper',
      'event' => 'autcompletechange autocompleteclose',
      'progress' => [
        'type' => 'throbber',
        'message' => t('Fetching filtered content...'),
      ],
    ];

    $field_triggerfield_value = $form_state->getValue('field_triggerfield');
    if (!empty($field_triggerfield_value)) {
      $contextual_filter_value = $field_triggerfield_value[0]['target_id'];
      $form['field_referencefield']['widget'][0]['target_id']['#selection_settings']['view']['arguments'][0] = $contextual_filter_value;
    }
  }
}

function mymodule_field_mycontenttype_trigger(array $form, $form_state) {
  return $form['field_referencefield'];
}

```

so what this is doing (I've assumed node edit form and node add form for a content type):

1. putting a wrapper around the reference field whose available values should change
2. adding an ajax callback to the trigger field that should cause the reference field to filter (the contextual field)
3. when the trigger field changes
    * add a new contextual value to the view reference field's view from the trigger field
    * replace the contents of the wrapper field in the form
> 7 votes

---
Tags: views, 8, entities
---


# Question
Title: How do I remove all references to the Sample DB when using the Forena reports module on a server without PDO Sqllite?
We have Forena installed on a server that doesn't have the PDO driver for Sqllite and would like to remove all references to the Sample DB repository so that Forena pages don't display an error about the missing driver. The users see a lot of:

> PDO driver support for sqlite not installed

I first tried removing permissions on the SampleDB repository as mentioned in one thread in the issue queue. This had no effect and the error message was still displayed.

I have tried using drupal\_alter to remove the repos:

```
function mymodule_forena_repos_alter(&$repos) {
  if(isset($repos['forena_help'])){
    unset($repos['forena_help']);
  }
  if(isset($repos['sampledb'])){
   unset($repos['sampledb']);
 }

```

}

I then get a new error:

> Undefined repositorysampledb
>
> Undefined repositoryforena\_help

I have tried patching the Forena module to unset the `settings.php` variables inside the sampledb folder. That also gives a new error along the lines of "PDO Driver not found".

How do I remove all references to the SampleDB repo? I would also like to remove the *Forena Help* and *Drupal Admin* repos if possible.

# Answer
Quote from Dave's (Forena maintainer) comment in a related Support Issue:

> ... You might uncheck permissions associated with accessing sample reports to make sure other users don't see this error.

Using this approach you should be OK when upgrading to future versions.

Disclosure: I'm a co-maintainer of Forena (and contributed quite a bit of the content of that `forena_help` repo you seem to be strugling with).
> 2 votes

---
Tags: forena
---


title: Using IN clause in db_query

text:
# Question
Title: Using IN clause in db_query
I can't figure out how to add an IN clause in my query, using placeholders.

I'd want it to be something like:

```
$nids = array(1, 2, 3);
$result = db_query('SELECT * FROM {node} WHERE nid IN :nids', array(':nids' => $nids));

```

Can't find any documentation on this simple task. What's the proper way to achieve this?

# Answer
You are missing the braces.

Try this:

```
$nids = array(1, 2, 3);
$result = db_query('SELECT * FROM {node} WHERE nid IN (:nids)', array(':nids' => $nids));

```

For more information, see http://drupal.org/node/310072, especially the chapter on Placeholder arrays:

> Placeholder arrays
>
> Drupal's database layer includes an extra feature of placeholders. If the value passed in for a placeholder is an array, it will be automatically expanded into a comma separated list as will the corresponding placeholder. That means developers do not need to worry about counting how many placeholders they will need.
>
> An example should make this behavior clearer:
>
> ```
> <?php
> // This code:
> db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => array(13, 42, 144));
>
> // Will get turned into this prepared statement equivalent automatically:
> db_query("SELECT * FROM {node} WHERE nid IN (:nids_1, :nids_2, :nids_3)", array(
>   ':nids_1' => 13,
>   ':nids_2' => 42,
>   ':nids_3' => 144,
> ));
>
> // Which is equivalent to the following literal query:
> db_query("SELECT * FROM {node} WHERE nid IN (13, 42, 144)");
> ?>
>
> ```
> 47 votes

# Answer
### Drupal 8

Use the entity query class.

```
$query = \Drupal::entityTypeManager()->getStorage('entity_type')->getQuery();
$query->condition('field/property', [1, 2, 3], 'IN');
$ids = $query->execute();

```

To directly query the entity database table, the code is essentially the same for other database tables.

```
$query = \Drupal::database()->select('table', 't');
$query->condition('column', [1, 2, 3], 'IN');
...

```

### Drupal 7

See Berdir's answer.

### Drupal 6

You can use code similar to the following one.

```
$nids = array(1, 2, 3);
$placeholders = db_placeholders($nids);
$result = db_query("SELECT * FROM {node} WHERE nid IN ($placeholders)", $nids);

```

`db_placeholders()` is needed in Drupal 6 to create the string that holds the values needed for the array. Drupal 7 handles all this internally as Berdir describes.
> 19 votes

# Answer
In Drupal 7, you can use `db_select()` instead of `db_query()`.

```
$nids = array(1, 2, 3);
$query = db_select('node', 'n')
  ->fields('n')
  ->condition('n.nid', $nids, 'IN')
  ->execute();
$nodes = $query->fetchAll();

```
> 13 votes

# Answer
In Drupal 6, if your array contains strings, you need to tell `db_placeholders()`.

```
$colours = array('red', 'yellow', 'blue');
$placeholders = db_placeholders($colours,'text');
$result = db_query("SELECT * FROM {bricks} WHERE colour IN ($placeholders)", $colours);

```
> 1 votes

# Answer
Drupal 8 update.

Also valid.

```
$nids = db_query("SELECT nid FROM node_field_data WHERE nid IN (:nids[]) AND status = 1", [
  ':nids[]' => $nids
])->fetchCol();

```
> -1 votes

---
Tags: database
---


title: Drush Not detect Database connection

text:
# Question
Title: Drush Not detect Database connection
I'm using Acquia DevDesktop application on Mac, I installed a new website on that , everything seems Ok but when I got to the installed path and try to update Drupal core with `drush up` faced with

```
➜  thunder-8.x-1.0-core drush up
Command pm-update needs a higher bootstrap level to run - you will need to invoke drush from a more functional Drupal         [error]
environment to run this command.
The drush command 'up' could not be executed.                                                                                [error]
Drush was not able to start (bootstrap) the Drupal database.                                                                  [error]
Hint: This may occur when Drush is trying to:
 * bootstrap a site that has not been installed or does not have a configured database. In this case you can select another
site with a working database setup by specifying the URI to use with the --uri parameter on the command line. See `drush topic
docs-aliases` for details.
 * connect the database through a socket. The socket file may be wrong or the php-cli may have no access to it in a jailed
shell. See http://drupal.org/node/1428638 for details.

Drush was attempting to connect to:
 Drupal version         :  8.2.5
 Site URI               :  http://default
 PHP executable         :  /usr/bin/php
 PHP configuration      :
 PHP OS                 :  Darwin
 Drush script           :  /Users/yms/.composer/vendor/drush/drush/drush.php
 Drush version          :  8.1.10
 Drush temp directory   :  /tmp
 Drush configuration    :
 Drush alias files      :
 Drupal root            :  /Users/yms/Sites/devdesktop/thunder-8.x-1.0-core
 Drupal Settings File   :  sites/default/settings.php
 Site path              :  sites/default

```

**In the issues reported I found about this problem, adding Mysql path to PATH resolve the problem, but in my case when I type `mysql` on command prompt it works correct and that means The mysql path is added to PATH. but I don't know why Drush couldn't find the database connection.**

**Also in my connection to db Acquia used 127.0.0.1 So changing localhost to 127.0.0.1 is not the solution**

# Answer
> 3 votes
After wasting a few hours I resolve it with adding `driver` property to `$databases` in `settings.php` .

```
$databases['default']['default'] = array (
  'database' => 'XXX',
  'username' => 'XXXX',
  'password' => 'XXX',
  'prefix' => '',
  'host' => '127.0.0.1',
  'port' => '33067',
  'driver' => 'mysql',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
);

```

I hope this could save another guys time in future in the same problem.

# Answer
> 2 votes
Using Acquia DevDesktop application on Mac OS, drush could not find database settings. My solution was to comment out `<DDSETTINGS>` and copy the connection details directly into `settings.php` :

```
// <DDSETTINGS>
// Please don't edit anything between <DDSETTINGS> tags.
// This section is autogenerated by Acquia Dev Desktop.
// if (isset($_SERVER['DEVDESKTOP_DRUPAL_SETTINGS_DIR']) && file_exists($_SERVER['DEVDESKTOP_DRUPAL_SETTINGS_DIR'] . '/loc_1sexshop2018_dd.inc')) {
//   require $_SERVER['DEVDESKTOP_DRUPAL_SETTINGS_DIR'] . '/loc_mysite_dd.inc';
// }
// </DDSETTINGS>

// DDSettings
// Copied from $_SERVER['DEVDESKTOP_DRUPAL_SETTINGS_DIR'] . '/loc_mysite_dd.inc' in order to work with drush
$databases['default']['default'] = array(
  'driver' => 'mysql',
  'database' => 'mydb',
  'username' => 'drupaluser',
  'password' => '',
  'host' => '127.0.0.1',
  'driver' => 'mysql',
  'port' => 33067 );

if (empty($config_directories['active']))
  $config_directories['active'] = "sites/default/files/config_...my_config.../active";
if (empty($config_directories['staging']))
  $config_directories['staging'] = "sites/default/files/config_...my_config.../staging";

if (empty($settings['hash_salt']))
    $settings['hash_salt'] = '...myhash...';
// /DDSettings

```

# Answer
> 1 votes
You will have to give root path and URI in your drush command

e.g

```
`drush --root=/path/to/drupal-installation --uri=youdomain.com <command>`

```

---
Tags: 8, drush
---


title: Load term by name

text:
# Question
Title: Load term by name
In Drupal 7, we can load the term using name for ex. `taxonomy_get_term_by_name($name)`

Is there any way to load term via given name in Drupal 8?

# Answer
> 29 votes
This functionality appears to be deprecated in Drupal 8.
Use the taxonomy\_term\_load\_multiple\_by\_name function instead.

Example

```
<?php

  /**
   * Utility: find term by name and vid.
   * @param null $name
   *  Term name
   * @param null $vid
   *  Term vid
   * @return int
   *  Term id or 0 if none.
   */
  protected function getTidByName($name = NULL, $vid = NULL) {
    $properties = [];
    if (!empty($name)) {
      $properties['name'] = $name;
    }
    if (!empty($vid)) {
      $properties['vid'] = $vid;
    }
    $terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadByProperties($properties);
    $term = reset($terms);

    return !empty($term) ? $term->id() : 0;
  }

?>

```

# Answer
> 38 votes
You can use snippet code like by using entityTypeManager :

```
$term_name = 'Term Name';
$term = \Drupal::entityTypeManager()
      ->getStorage('taxonomy_term')
      ->loadByProperties(['name' => $term_name]);

```

# Answer
> 9 votes
To load a single term ID by term name and vocabulary in Drupal 8 you can use the following snippet.

```
$term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')
  ->loadByProperties(['name' => $term_name, 'vid' => 'job_category']);
$term = reset($term);
$term_id = $term->id();

```

# Answer
> 2 votes
As per Renamed the taxonomy functions that returned multiple values, `taxonomy_get_term_by_name($name, $vocabulary = NULL)` has been renamed `taxonomy_term_load_multiple_by_name($name, $vocabulary = NULL)`. If you look at the code of the first function and you compare it with the code of the second function, you will notice that the most relevant difference is having replaced the call to `taxonomy_term_load_multiple(array(), $conditions)` with the call to `entity_load_multiple_by_properties('taxonomy_term', $values)`.

```
// Drupal 7
function taxonomy_get_term_by_name($name, $vocabulary = NULL) {
  $conditions = array('name' => trim($name));
  if (isset($vocabulary)) {
    $vocabularies = taxonomy_vocabulary_get_names();
    if (isset($vocabularies[$vocabulary])) {
      $conditions['vid'] = $vocabularies[$vocabulary]->vid;
    }
    else {
      // Return an empty array when filtering by a non-existing vocabulary.
      return array();
    }
  }
  return taxonomy_term_load_multiple(array(), $conditions);
}

```

```
// Drupal 8
function taxonomy_term_load_multiple_by_name($name, $vocabulary = NULL) {
  $values = array('name' => trim($name));
  if (isset($vocabulary)) {
    $vocabularies = taxonomy_vocabulary_get_names();
    if (isset($vocabularies[$vocabulary])) {
      $values['vid'] = $vocabulary;
    }
    else {
      // Return an empty array when filtering by a non-existing vocabulary.
      return array();
    }
  }
  return entity_load_multiple_by_properties('taxonomy_term', $values);
}

```

Since `taxonomy_term_load_multiple_by_name()` has not been marked as deprecated, you can still use that function where you used to use `taxonomy_get_term_by_name()`. They both require the same arguments, so converting code for Drupal 7 in code for Drupal 8, in this case, is just matter of replacing the function name.

# Answer
> 1 votes
You can also use entity field queries to load by fields on the term

```
$result = \Drupal::entityQuery('taxonomy_term')
          ->condition('field_my_field_name', 'Whatever Value')
          ->execute();

```

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


title: How to show an image in an image style

text:
# Question
Title: How to show an image in an image style
I'm creating a custom twig for my node 1, as node--1.twig.html.

In this I'm showing the image uploaded in the node as

```
<div class="diversity-image">
    {{ set image = content.field_main_image|merge({'#style_name': 'header_image'}) }}
    {{ image }}
</div>

```

But it is not giving me the image of that image style, header\_image.

How do I do that in twig?

# Answer
In twig you can only merge the top level of an array. So you need two steps, first get the image from the content array and then overwrite `#image_style`.

**node.html.twig**

```
{% set image = content.field_image.0 %}
{% set image = image|merge({'#image_style': 'thumbnail'}) %}

```

You can now display the image a second time in the changed image style:

```
{{ image }}

```
> 5 votes

# Answer
In twig, we can get the path -

```
<img src="{{ node.FIELD-IMAGE-NAME.entity.uri.value | image_style('news_image_full_width') }}" alt="">

```
> 1 votes

---
Tags: theming, 8, media
---


# Question
Title: How do I construct an authenticated HTTP request in Postman?
I have Drupal 7 installed locally on my computer with the domain set to http://drupal.local.

I am trying to prepare an external script in PHP or Python (or even in pure Bash using curl, if it does not require a lot of extra work), which will successfully execute an HTTP request by default available only for the logged in user.

To understand what such a HTTP request should look like, I am first trying to perform such a HTTP request using Postman, but all my attempts failed.

This is what I've done so far:

1. In the browser, I logged in as administrator of the Drupal 7 site
2. I opened the browser on http://drupal.local/en/node/add/article and I received status 200 (The page is displayed correctly in my browser.)
3. In Postman I set:
    * request method on: GET
    * URL: http://drupal.local/en/node/add/article
    * Headers: I set all headers identically to those in the browser including the current cookies containing the session key with its value
4. I don't have access to this page and I receive a 403 error

How do I construct an authenticated HTTP request in Postman that will work for Drupal 7?

# Answer
You can make use of Token authentication but be careful:

From module description:

> Be careful with what paths you expose to Token Authentication, as it is effectively a very simple, very low security password mechanism. You can expose Administration pages through bad configuration.

1. Install / enable Token authentication Module.
2. Go to *admin/config/services/tokenauth*
3. Add the path you want to give access to with token.  in the example below i added all add content pages.
4. Go to *admin/people* edit the user you want to generate token.
5. Generate Token by clicking on `Token authentication` tab it will give a token for that user like `?token=tuvj7cMwauxStWGVQYfo`.
6. Then you can use it with postman.

**Note:** it may not be the best way.
> 0 votes

---
Tags: 7, authentication-authorization
---


# Question
Title: How to add field content as class in Twig?
I want to add the content of a field (i.e. "workshop") as a class in field-html.twig

i tried

```
{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
    'icon-' ~ item.content,
  ]
%}

```

but it only shows "icon-" as a class.

# Answer
`item.content` works only in the items loop, but don't try to put rendered output in a class name. Use the field value instead, which you can get through the field object `#items` stored in a field template inside of the variable `element`:

```
{{ element['#items'].value }}

```

or from a different field of the parent entity:

```
{{ element['#object'].field_example.value }}

```

Depending on the field type replace `.value` with a different property, for example for a reference field to get the target id or the label of the target with `.target_id` or `.entity.label`.

When you have found the field value build your class name:

```
{%
  set classes = [
    ...
    'icon-' ~ element['#items'].value|clean_class,
  ]
%}

```
> 1 votes

---
Tags: 8, theming
---


# Question
Title: Where to put #Ajax Callback in webform twig file
I would like to add the Ajax callback settings to my custom composite webform element in the twig file. Is this possible? The callback function is in my custom module. This is NOT a computed twig situation. The Webform is created entirely from D8 webform GUI.

Custom composite has qty, code, description, price. Using the callback to verify code and update the description and price. Could something like below be put in the twig file?

```
'#ajax' => (
    'callback' => 'validate_srvform_items',
    'event' => 'change',
    'progress' => array(
      'type' => 'throbber',
      'message' => t('Populating line item...'),
    )

```

# Answer
You can create a form alter function in your module file and then add the callback property to the respective field

```
$form['actions']['submit']['#ajax'] = [
  'callback' => 'callback',
  'event' => 'click',
];

```

See also
> 3 votes

---
Tags: 8, webforms
---


# Question
Title: How can my JavaScript-function access the Web Property ID from the Google Analytics module?
I use the GoogleAnalytics module in most of my projects and have often the same issue:

Due to my countries policy requirements, every user has to be able to deactivate google-analytics cookies. To do so I need a little JavaScript to disable the cookie wich contains the UA/property ID, which is provided by the module.

Normaly such configs are set in the `drupal-settings-json` at the end of the page but there is no property-id in sight.

```
<script type="application/json" data-drupal-selector="drupal-settings-json">{"path":{"baseUrl":"\/","scriptPath":null,"pathPrefix":"","current....

```

is there any way for my JS-function to access this infirmation, or do I need to write an extra function to read the property ID and parse it to the drupal-settings-json somehow?

# Answer
> 0 votes
The most popular Google Analytics module (google\_analytics) relies on generating inline JavaScript snippets for initializing tracking, which can make altering its behaviour difficult - likely requiring patching the module.

Googalytics is a more flexible alternative for Google Analytics in Drupal 8

* `drupalSettings` is used to pass data to the front end. This removes the use of inline JS, also making the module compitible with Content Security Policy.
The data structure isn't intended to be modified on the front-end by JS, but hopefully the improved control possible in the back-end makes it unnecessary.
* There's an open issue (with a patch currently needing feedback) for integrating with the EU Cookie Compliance module. If this matches your use case you may not need to write any custom code, otherwise it may provide a template for how to override the module's JS library for your needs.

---
Tags: 8, javascript, google-analytics
---


# Question
Title: How to get a taxonomy custom image field URL value
I've created an image 'field\_term\_preview' field on the taxonomy vocabulary and trying to get this URL in my custom module:

```
$terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, 0, null, true);

foreach ($terms as $term) {
    if ($term->getName = 'Term with preview')
    {
        foreach ($term->getFields(true) as $field)
        {
            if ($field->getName() == 'field_term_preview')
            {
                var_dump($field->getValue());
            }
        }
    }
}

```

This code shows only target\_id, alt, height, etc.

How to get the URL to the preview image?

# Answer
> 1 votes
In Drupal images are File entities, the `target_id` is the File ID. So...

```
$fid = $field->getValue()[0]['target_id']; // File ID,

// Note the [0] in the array. We assume there is always going to be 1 image here.
// If your field allows more than 1 image, you will need to loop through each $field->getValue()

$file = \Drupal\file\Entity\File::load($fid); // load File entity object

$file_url = $file->url(); // get the URL.

```

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


# Question
Title: How to store temporary metadata for the remainder of a request?
I am looking for a way to store some additional metadata for the remainder of a request, that should be removed after the request has finished. Sessions or SharedTempStore store persistent data across requests, which is not desirable.

The main problem is that I am working on an inbound PathProcessor, which after some path modifications needs to check if a valid path remains by using `\Drupal::service('path.validator')->isValid($path)`. This in turn calls all PathProcessors again, leading to infinite processing. I wish to store some sort of metadata in the request, so that the PathProcessor is aware that it is ran for a second time and does nothing.

Obviously, for subsequent requests the metadata should initially be empty again so that the processing is done for each request.

# Answer
Drupal introduced the `Drupal\Core\Cache\MemoryCache\MemoryCache` class to, as Added memory cache says, allow classes that would previously maintain state on a protected property (as a static cache to avoid persistent cache or database lookups) to inject a service to hold that state instead.

Drupal core implements two services that use that class, one of them is the *entity.memory\_cache* service, which is defined from the following code.

```
entity.memory_cache:
  class: Drupal\Core\Cache\MemoryCache\MemoryCache

```

The other service using that class is the *cache.jsonapi\_memory* service, which is defined from the following code.

```
cache.jsonapi_memory:
  class: Drupal\Core\Cache\MemoryCache\MemoryCache
  public: false

```

A module that needs to store data that is valid only for the current request can define a similar service. Setting the service as private is optional, but it avoids other modules uses it, making the stored data private for the module.
> 1 votes

---
Tags: 8, routes
---


title: Form submission handler is not executed

text:
# Question
Title: Form submission handler is not executed
In a module, I am using the following code.

```
function mysimple_form($form, &$form_state) {
  $form['#method'] = 'get';
  $form['#action'] = '/buy/{_val_}';
  $form['search_location'] = array(
    '#type' => 'textfield',
    '#title' => 'Search',
    '#default_value' => t('kathmandu'),
    '#size' => 60,
    '#maxlength' => 128,
    '#required' => TRUE,
    '#attributes' => array(
      'placeholder' => t('Search')
    )
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Search'),
  );

  $form['#submit'][] = 'mysimple_form_submit';
  return $form;
}

function mysimple_form_submit($form, &$form_state) {
  krumo('asdsads');
  die();
}

```

I am using that form in `hook_node_view()`.

```
function mymodule_node_view($node, $view_mode, $langcode) {
  $form = drupal_get_form('mysimple_form');
  $node->content['simpleform'] = array(
    '#weight' => -1,
    '#markup'=> drupal_render($form)
  );
}

```

The form is displayed perfectly, but the callback function doesn't seem to work. I also tried `$form['actions']['#submit][] = 'mysimple_form_submit';` and `$form['actions']['submit']['#submit][] = 'mysimple_form_submit';` but the form submission handler is still not invoked.

# Answer
> 1 votes
There is two problems:

1. You form method is **GET** so form submit action will be the actual path with the params like `node/10?search_location=kathmandu&op=Search&form_build_id=form-s4JrAE91au_BWakeBLD7RUsktRTBXFCpJQrnHGiOjg8&form_token=ES2W0RDpLOnWZUsXOnP4f9gBmSXcYLvqhO9uy1ee4Vk&form_id=d7_exp_form`
2. The second one you set your action to `'/buy/{_val_}'` so automatically after the submit you will redirect to `/buy/{_val_}` without invoke the submit handler.

**Suggestion:**

1. If you want to invoke the submit handler remove the `$form['#method']` and `$form['#action']`, so your form will be with post method and your submit handler will invoked.
2. Remove only `$form['#method']` and create menu entry `/buy/%` and you can do your submit handler logic in the `/buy/%` callback function.

# Answer
> 0 votes
In your case, you don't need to specify custom submit handler because if your form ID is `mysimple_form`, Drupal should use `mysimple_form_submit` as default form submission function.

For more info see the https://api.drupal.org/api/drupal/developer!topics!forms\_api\_reference.html/7.x#submit\_property

---
Tags: 7, forms
---


# Question
Title: Why would all theme background colors disappear after moving to different server?
A site using MAYO 7.x-1.2 was moved from a Windows IIS to a Linux server. Shortly thereafter, all background colors defined in MAYO settings (and also any custom CSS) have disappeared. Also gone is the custom background color for dropdown Nice menus – it just goes transparent. Other than the bg color, main content and layout are OK. Perhaps there is no relationship of this to the server change, but in any case I haven't been able to debug this with anything I tried. The PHP version is now 7.2, maybe that is related, and I'm not sure what it was under the Windows server. Site needs to stay in D7 for now, although a D8 upgrade is planned.

Also note, I was aware that this is an old version of MAYO that should have been updated long ago. I hesitated to update because I had modified the template file to get an additional region, and wasn't sure how to apply the update while preserving the custom region. (Could use some advice there.) In reading the docs about the security update, it seems the circumstances for risk don't really apply for this site.

Advice on either of these issues will be much appreciated.

# Answer
> 1 votes
First , Check Administrator -\> Configuration -\> Media -\> File System to personalize your `tmp` path. Make sure to use relative paths and have the right privileges for your webserver.

After than Check permission of the `/sites/default/files` and make sure it's **writeable** by your web server.

---
Tags: theming, migrations
---


# Question
Title: How do I know when another contributed module deletes a block?
I have written a Drupal 7 module that adds about ten fields to the block administration configuration form and saves the values for those fields in its own database table. My module does not create blocks, but rather extends the functionality of any block, regardless of what module created it.

My module should delete the data in its own table when **any** module deletes a block from the *block* table. However, how would my module know when this happens? Is there a hook or other "universal" method available to know when a block has been deleted?

There isn't a `hook_block_delete()`, even though there are `hook_node_delete()` and `hook_entity_delete()`.
I've looked at development guides about creating blocks for some clues, but none of the ones I've found give examples of how they should be deleted. I've also looked at the source code of modules that create/delete blocks, like the Views module, but I can't tell how, or if, they send a notice that they have deleted a block.

# Answer
> 1 votes
There is no hook fired in delete of block, as you can see in the list of block hooks here block.api.php.

There is a topic in Drupal forum here.

I think the best way to handle this is by `hook_form_alter` something like.

```
/**
 * Implements hook_form_alter().
 */
function YourModule_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'block_custom_block_delete') {
    // You get all information here of the concerned block in $form.
  }
}

```

---
Tags: 7, blocks, hooks
---


# Question
Title: Notice: Trying to get property 'nid' of non-object
In Drupal\rsvplist\Form\RSVPForm-\>buildForm(), I wrote this to get the current nid:

```
$node = \Drupal::routeMatch()->getParameter('node');
$nid = $node->nid->value;

```

I get this error:

> Notice: Trying to get property 'nid' of non-object in Drupal\rsvplist\Form\RSVPForm-\>buildForm() (line 30 of modules\custom\rsvplist\src\Form\RSVPForm.php).

I am a new module developer. How to get the current nid in drupal 8?

# Answer
> 5 votes
You will need to check if the $node variable is actually an instance of node object.

```
if ($node instanceof \Drupal\node\NodeInterface) {
  // You can get nid and anything else you need from the node object.
  $nid = $node->id();
}

```

See

How do I get the current node ID?

---
Tags: 8, uri
---


title: Photo gallery with taxonomy filter

text:
# Question
Title: Photo gallery with taxonomy filter
It's not easy to explain so I made simple example below. I'm making a gallery in Drupal 8. First I made articles with taxonomy term: animals, forest or people. Some of articles have two or three taxonomy terms. Each article contains 1-5 photos. The main page (gallery) displays a main photo from each article (picture 1). As you can see when you click FOREST gallery shows all articles contain 'forest' taxonomy (picture 2). When someone click on a thumbnail from the forest gallery then a page (picture 3) appears and we can see our tree with 2 more photos (for example colorbox) plus some comments and thumbnails of articles with forest taxonomy above. Picture 4 is easy to understand. Additionaly when you click on a thumbnail from NEWEST(ALL) gallery the next and previous articles has to include all taxonomy terms or just all photo articles.

I've made a few projects but none of them can do this all same time. Is there a way to make this photo gallery? It looks like a basic gallery but I couldn't find solution or module.

**EDIT 2019-11-27:** From the beginning: I have articles (with photos) that have taxonomy term.I have views for each taxonomy term. For example, for the "People" category, I have a view that displays the title and thumbnail photo from each article that has "People" taxonomy. If the article has two taxonomy terms, its thumbnail is displayed, for example, in the "People" view and the "Forest" view. And that's ok. I also have a pager for every taxonomy, made by the Entity pager module, which is a block. I would like this pager to be displayed in the article. But now, if I have an article that has two taxonomy term, it displays two pagers. I would like only one to be displayed. If I click on the article shortcut in the "People" view (and this article has the taxonomy term "People" and "Forest") I would like this article to display the "People" pager only. If I click the same article thumbnail, but in the "Forest" view, I would like only the "Forest" pager to be displayed in this article. Is it even possible to do this?

# Answer
This is quite a bit more complicated than your previous question.

My best advice would be that in order to get each content node to have a gallery with multiple images, each Article node should use an image field with multiple values.

These "child sideshows" will be completely separate from the "parent slideshow" which is the one using Views with the taxonomy filters (e.g., "Previous / Next Forest").

You should still be able to make the "child slideshow" into a scrollable gallery as you show in your thumbnails (e.g., "Previous / Next image in Article") by using a library like SlickSlider.

This Drupal.org issue queue talks about setting up Slick without Views as a "multi-imagefield single-node slick on D8" so it can definitely be done. (The Slick Extras module may help, but I haven't tried it so I'm not sure.)

It will be a bit more work this way, and not all the advice you find online will be completely applicable to your situation. If you get stuck, I recommend following the Javascript code in the Slick demos rather than any Drupal-specific walkthroughs.

Good luck!

**EDIT 2019-11-27:** Thanks, the comment below helps me to understand what you're trying to do.

The real problem is that your data model is a mess: you want to apply the taxonomy terms to the Article (child slideshows) content type, and also to the individual photos within the Articles. You apparently *don't* want to display all the photos in each Article, but only the individual photos that match the selected taxonomy term in the parent. That wasn't very clear from your earlier description.

To accomplish that, I think you'll need to implement the term filters (Animals, Forest, People) as an exposed filter on the child slideshow. You can't filter by the taxonomy terms on the child node because you want to jumble terms together at both levels.

This is made more complex by the fact that you want the same buttons to act as exposed filters on two different Views. No wonder you are having trouble.

Maybe you can use a contextual filter on the child slideshow that refers to the value of the exposed filter on the parent.
> 0 votes

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


# Question
Title: How can I display the block title when rendering a block using Twig Tweak?
Block title when using twig-tweak plugin, not showing. I created a block-type view. And using the module's cheat sheets, I called:

```
{{ drupal_view('views_name', 'block_1') }}

```

# Answer
You'll have to manually type it on your twig, as per https://www.drupal.org/project/twig\_tweak/issues/2738781

If you don't want to type it on twig, a work around would be to add a "Text area" to your view's Header and use replacement patterns, `<div class="view-title">[view:title]</div>`.

---

Alternatively, you could ditch Twig Tweak and do it yourself by creating a variable:

```
function MY_THEME_preprocess_HOOK(&$variables) {
    // replace HOOK with the template file you're trying to add it to. Ex: node, page, block etc..
    $view  = views_embed_view('view_name', 'block_1');
    $variables["my_view"] = \Drupal::service('renderer')->render($view);
}

```

Then in the template file you just do `{{ my_view }}`
> 3 votes

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


title: Link to node in View with TWIG

text:
# Question
Title: Link to node in View with TWIG
I have a set of nodes, some of which are just a title, while others have body and other content.

I'm trying to create a view, which lists the node titles. If the body of the node contains content, the title should link to the node, but if the node body is empty, it should just display the title as plain text.

I think I can achieve this by rewriting the title field in the view with TWIG.

I've got it working so it detects the body and displays a link, but I'm not sure what to put for "url" in the link.

```
{% if body|render|trim is not empty %}
<a href="{{ url }}">{{ title }}</a>
{% else %}
{{ title }}
{% endif %}

```

How can the TWIG code get the url of the node to link to?

# Answer
> 3 votes
In the view fields search for "Link to content", add the field, exclude this from presentation and move it to the top, and now you can use:

```
{% if body|render|trim is not empty %}
  {{ view_node }}
{% else %}
  {{ title }}
{% endif %}

```

---
Tags: views, 8
---


title: Views footer include twig

text:
# Question
Title: Views footer include twig
Is there any way to include an if condition in views footer. I have to check the total rows

```
{% if [view:total-rows]  > 6 %}
<div class="btn">View AllEvents</div>
{% endif %}

```

But this is not working.

# Answer
> 1 votes
What is the name of your template file? Depending on what template you use,

```
{% if view.total_rows > 6 %}
  <div ...
{% endif %}

```

should work.

# Answer
> 0 votes
I recommend reading this page.

Install the twig tweak module. And use the link described above.

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


# Question
Title: How do I print individuals fields in block.html.twig when is a node in a block?
How do I print individuals fields in block.html.twig when is a node in a block?

The template is working fine. I can hard code some random text and it is displayed. I just can't display the field values.

I have already tried

```
{{content.my_field.0}}
{{content.my_field[0]}}
{{node.my_field.0.value}}
{{ content.my_field }}

```

But, after clear the cache doesnt work

# Answer
You have to set "node" in the twig-variables of your block. I.e. you can do this in a template\_preprocess hook like so:

```
function mytheme_preprocess_myBlock(&$variables) {
  $variables['node'] = Node:load(50);
}

```

Then you can access the "node" in your template like `{{node.my_field.value}}`.

The hard part is to find which node to load in the preprocess function :-)
> 0 votes

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


# Question
Title: How can I disable meta tags provided by the Metatag module for a custom route?
I have created a custom module for displaying the players information. Module will create dynamic pages and each page will display players stats. With the help of the following links, I was able to add meta tags to my module.

1. How to add meta tag in head
2. Adding meta tags

Since each of the page generated by my module for separate meta information, I was not able to use page\_attachement\_hooks. Using the above links, I was able to add meta information in my controller itself.

But, I am using Meta tag drupal module for generating meta information for other pages. Now I am getting multiple meta tags with same property name. Global configurations of meta tag module is displaying along with my meta tags.

I read in some blog that if multiple meta tags found with same property, few crawlers will ignore them. How do I keep only my meta tags?

I saw this post which says how to override the meta tags. But there the code has to be placed in the module and it will be static. I wanted dynamic meta tags for each page. How will I achieve it?

Here is my code.

PlayerController.php

```
<?php

namespace Drupal\player\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal;

class PlayerController extends ControllerBase {

  public function content($player) {
    $result = [];
    /* --------------
     code logic here
    ------------------ */
    return [
      '#type' => 'markup',
      '#markup' => $result,
      '#attached' => [
        'html_head' => [
        [
         [
          '#tag' => 'meta',
          '#attributes' => [
            'property' => 'og:description',
            'content' => $result->player_details,
          ],
        ],
        'player',
      ],
    ],
  ],
    ];
  }

}

```

For reference, I am adding link to my old question regarding how to add meta tags in dynamic module. It have more codes in case you need.

# Answer
**Edit** – @AlfredArmstrong pointed me to the hooks provided by the Metatag module itself. And there's `hook_metatags_alter()` you can implement to completely disable all meta tags added by the Metatag module. Much shorter than my original answer.

```
/**
 * Implements hook_metatags_alter().
 */
function MYMODULE_metatags_alter(array &$metatags, array &$context) {

  // Exclude meta tags on 'player' route.
  if (\Drupal::routeMatch()->getRouteName() === 'player') {
    $metatags = NULL;
  }
}

```

---

**Original answer** – I've had similar problems before. You can override or unset meta tags added by the Metatag module implementing `hook_page_attachments_alter()` like in the following example.

```
/**
 * Implements hook_page_attachments_alter().
 */
function MYMODULE_page_attachments_alter(array &$attachments) {

  // Check for the route you want to override.
  if (\Drupal::routeMatch()->getRouteName() === 'player') {

    // An array of tags you want to unset.
    $unset = [
      'description' => 1,
      'abstract' => 1,
      'keywords' => 1,
    ];

    $meta_tags = $attachments['#attached']['html_head'];
    foreach ($meta_tags as $key => $meta_tag) {

      // And now unset them.
      if (isset($unset[$meta_tag[1]])) {

        unset($attachments['#attached']['html_head'][$key]);
      }
    }
  }
}

```
> 4 votes

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


title: Load Media File in Webform Mail Handler

text:
# Question
Title: Load Media File in Webform Mail Handler
I want to use a single webform to send download links with specific media files to visitors that fill out that form. For example on an URL like this:

```
https://example.com/downloads?media=1234

```

The media parameter will be the ID of an media entity type like "Download". Now I want to send the mail with the name of the media entity and a link to the file of that entity.

How could I get this done? Mail handler and a custom Twig template is what I think about, but how do I get the data of the media entity? Any ideas? Thanks for every helpful comment ;)

# Answer
> 1 votes
```
$media_id = \Drupal::request()->get('media'); // get value of media query param

$media = Drupal\media\Entity\Media::load($media_id); // load the Media entity

$media_name = $media->getName(); // get the media item name

$media_field = $media->get('field_media_image')->first()->getValue(); // get media field

$file_id = $media_field['target_id']; // get the File ID

$file =  Drupal\file\Entity\File::load($file_id); // load File entity

$image_url = $file->url(); // get image url

```

---

You could take this shortcut instead of writing the last 4 lines.

```
$image_url = $media->get('field_media_image')->entity->url();

```

---
Tags: 8, media, webforms, emails
---


# Question
Title: Is the tags section valid in the info.yml file?
I see in the devel.info.yml file a section named tags

```
tags:
- developer

```

But I can't find it on the documentation page. Is the tags section valid in the info.yml file or is it just an error?

# Answer
> 4 votes
I do not think it is valid yet. There is an issue on this

https://www.drupal.org/project/drupal/issues/1868444

---
Tags: 8, .info
---


# Question
Title: How do I programmatically save "2019-11-04 07:30:00+01"?
I have "2019-11-04 07:30:00+01" as datetime value. I am not getting how to handle the `"+1"` part in a Drupal 8 date field.

I am using this code, but it's not giving me any value.

```
use Drupal\Core\Datetime;

$userTimezone = new DateTimeZone(drupal_get_user_timezone());
$gmtTimezone = new DateTimeZone('GMT');
$myDateTime = new DateTime($item['start_date'], $gmtTimezone);
print_r($myDateTime);
die;

```

# Answer
> 1 votes
There is no `DateTime` class in `Drupal\Core\Datetime` you should use `DrupalDateTime` class instead try with.

```
    use Drupal\Core\Datetime\DrupalDateTime;
   //$userTimezone = new DateTimeZone(drupal_get_user_timezone());
    $gmtTimezone = new DateTimeZone('GMT');
    $myDateTime = new DrupalDateTime($item['start_date'], $gmtTimezone);
    $dateTime = $myDateTime->getPhpDateTime();

```

# Answer
> 0 votes
There are three errors in that code:

1. `use` requires the fully qualified name of a class, not its namespace.
2. Drupal doesn't have any `Drupal\Core\Datetime` class. There is the `Drupal\Core\Datetime\DrupalDateTime` class, which is the class you want to use.
3. The second argument of the constructor of `DrupalDateTime` isn't necessary since, as the documentation for `DrupalDateTime::__construct()` says, it's not used when the string passed as first argument specifies a timezone.

> **mixed `$timezone`**: PHP DateTimeZone object, string or `NULL` allowed. Defaults to `NULL`. Note that the `$timezone` parameter and the current timezone are ignored when the `$time` parameter either is a UNIX timestamp (e.g. @946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00). @see http://php.net/manual/datetime.construct.php

The code you should use is then the following one.

```
use Drupal\Core\Datetime\DrupalDateTime;

$myDateTime = new DrupalDateTime($item['start_date']);

```

The code you are using doesn't return any value because you are using a class that doesn't exist. It should raise an error, as the code is referring a class that PHP cannot find.

As side note, the `DrupalDateTime` class should be used when a class, a method, or a function requires an instance of that class, you need a class that is more flexible than the `DateTime` class, or you need one of the methods that Drupal extends, for example `DrupalDateTime::format()`.
In the other cases, you should use the `DateTime` class implemented in PHP.

See also the documentation for `DateTimePlus`, which makes the difference between the PHP class and the Drupal classes clearer.

> This class wraps the PHP `DateTime` class with more flexible initialization parameters, allowing a date to be created from an existing date object, a timestamp, a string with an unknown format, a string with a known format, or an array of date parts. It also adds an errors array and a `__toString()` method to the date object.
>
> This class is less lenient than the `DateTime` class. It changes the default behavior for handling date values like '2011-00-00'. The `DateTime` class would convert that value to '2010-11-30' and report a warning but not an error. This extension treats that as an error.
>
> As with the `DateTime` class, a date object may be created even if it has errors. It has an errors array attached to it that explains what the errors are. This is less disruptive than allowing datetime exceptions to abort processing. The calling script can decide what to do about errors using `hasErrors()` and `getErrors()`.

---
Tags: datetime
---


# Question
Title: Drush install on RedHat 6 seems to do nothing
I'm trying to get drush installed on a RHEL6 server. I've done the install via pear and also by unpacking the tar ball to /usr/local/share. Both methods result in the same result: typing "drush" from any location does nothing. To be more specific it hangs without any errors that I can see.

It doesn't give any error about not finding it in the path, it just hangs.

I have had it working on other RHEL6 machines, but I haven't been able to pin down any differences between the installs to give me an idea what's wrong with this one.

# Answer
> 1 votes
Easiest way is to use the package manager:

```
yum -y install php-drush-drush

```

Alternatively, if it's installed in `/usr/local/share` then make a symbolic link:

```
sudo ln -s /usr/local/share/drush/drush /usr/local/bin/drush

```

Then, verify it works with:

```
which drush

```

# Answer
> 0 votes
The commands below have been tested successfully on Debian, Ubuntu, CentOS, RedHat and other linux systems.

1. `sudo wget --quiet -O - http://ftp.drupal.org/files/projects/drush-7.x-5.6.tar.gz | sudo tar -zxf - -C /usr/local/share`
2. `sudo ln -s /usr/local/share/drush/drush /usr/local/bin/drush`
3. `drush`

The last line drush is command. If it displays a list of drush command, it means drush was installed successfully!

# Answer
> 0 votes
Use Drush Luncher

it can be easily installed on each linux distributes by :

```
wget -O drush.phar https://github.com/drush-ops/drush-launcher/releases/download/0.6.0/drush.phar

chmod +x drush.phar
sudo mv drush.phar /usr/bin/drush

```

**old method, with using `yum`**

```
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E '%{rhel}').noarch.rpm

```

then

```
sudo yum install drush

```

---
Tags: drush, installation
---


# Question
Title: How can I programmatically create a Profile 2 profile?
I am taking a look in the Profile 2 API documentation: http://api.drupalhelp.net/api/profile2/function

I guess `profile_create()` or `profile2_save()` are what I need. But I have read somewhere `profile_create()` is deprecated.

Any example for how to create a Profile 2 profile programmatically?

# Answer
Yes `profile_create()` is deprecated. You should use `profile2_create()` instead.

See the *profile2.module* file:

> ```
> /**
>  * Deprecated. Use profile2_create().
>  */
> function profile_create(array $values) {
>   return new Profile($values);
> }
>
> ```
> 2 votes

---
Tags: 7, users
---


# Question
Title: How can I disply the regex match in a view?
This is a Drupal 7/Views 3 question.

I am using a regex as a filter in a view to select Body fields with certain characteristics. However, when it comes to displaying the field, I don't want to display the entire body, just the match or matches.

For instance, for the following filter on the Body field for a match on regex:

```
<h[23456]>[^<]*[.!?:;,][^<]*</h[23456]>

```

I want to display a views Body match column which only displays any regex matches, not the entire Body field. So in this case I only want to display headings that have punctuation in them which are contained within the body.

This will not display to the public, so I'm not concerned with whether it's pretty, only whether it's readable. So it doesn't matter whether it displays HTML as HTML or as plain text.

However, the Rewrite Results field in the fields edit does not provide an option to match on regex for displaying the text.

How can I accomplish this?

# Answer
You can create your own module that adds a field formatter for the `text_with_summary` field type. At the bare minimum you will need to implement the following hooks:

Here is an example that will do what you are asking for, but still requires a lot more work before you should use it in production. For example, it doesn't validate the pattern, and does not have an input field to enter the regex pattern in the Manage Display page for content types, even though it can be selected as a formatter.

```
/**
 * Implements hook_field_formatter_info().
 */
function my_module_field_formatter_info() {
  return array(
    'my_module_regex_formatter' => array(
      'label' => t('Regex matches'),
      'field types' => array('text', 'text_long', 'text_with_summary'),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function my_module_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  $element = array();

  if ($display['type'] == 'my_module_regex_formatter') {
    $pattern = FALSE;
    if (isset($settings['my_module_regex_pattern'])) {
      $pattern = $settings['my_module_regex_pattern'];
    }
    if ($pattern) {
      foreach ($items as $delta => $item) {
        $matches = _my_module_get_regex_matches($pattern, $item['value']);
        $element[$delta] = array('#markup' => $matches);
      }
    }
  }

  return $element;
}

/**
 * Returns regex pattern matches.
 */
function _my_module_get_regex_matches($pattern, $subject) {
  $result = '';
  $regex_result = preg_match_all($pattern, $subject, $matches);
  if ($regex_result) {
    $result = '<ul>';
    foreach ($matches[0] as $match) {
      $result .= '<li>' . check_plain($match) . '</li>';
    }
    $result .= '</ul>';
  }
  return $result;
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function my_module_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $default = '';
  if (isset($settings['my_module_regex_pattern'])) {
    $default = $settings['my_module_regex_pattern'];
  }
  $element = array();
  if ($display['type'] == 'my_module_regex_formatter') {
    $element['my_module_regex_pattern'] = array(
      '#type' => 'textfield',
      '#title' => t('Regex pattern'),
      '#default_value' => $default,
    );
  }

  return $element;
}

```

This will add *Regex matches* as an option in the *Formatter* select box within the Views configuration form for text fields, including the `Body` field. When you select the *Regex matches* formatter, a text input field will appear with the label *Regex pattern*. The pattern needs to include delimiters, and be properly escaped. The pattern in your question would look like this:

```
/\<h[23456]\>[^\<]*[\.!?:;,][^\<]*\<\/h[23456]\>/

```
* The pattern is surrounded by a delimiter: `/`
* All brackets are escaped: `\<h`, `\>`
* The period is escaped: `\.`
* The forward slash is escaped: `\/h`

`preg_match_all()` is used to perform a global regular expression match. The matches are outputted as an unordered list of escaped html (i.e. you will see the header tags in the output).
> 1 votes

---
Tags: 7, views
---


title: Use of Twig template for webform email

text:
# Question
Title: Use of Twig template for webform email
I'm trying to help my father out by building a webform (D8 version) for the 4 theaters his Old Abbey Friends are putting up.

I've made the webform, now i'm setting up an email handler so that people get a confirmation email. Straightforward enough, however, i'm getting lost when using the twig template option of that email handler on following items:

* how do i check if there's at least one checkbox checked in a checkbox element (containing 4 checkboxes)?
* how do i check which of the checkboxes is checked in the above element?
* how do i get the number in a number element that's part of a custom composite? I tried using the data.composite\_elementkey.elementkey syntax, but that just shows up blank.

Any feedback much appreciated!

# Answer
> 0 votes
Alright, after a lot of searching and testing things out i've found the following things to work:

1. For the checkbox it won't work with the data.element\_name syntax (or at least in any variation that tried, and that's a couple dozen). What will work is this: `{{ webform_token('[webform_submission:values:ticketselectie]', webform_submission) }}`. In this example "ticketselectie" is the name of the checkbox element with 4 checkboxes in it (options). What you get from this is a string containing the option text for each checked checkbox, seperated by comma.
    2. You can use the twig split filter to extract an array out of checked checkboxes.
    3. Turns out you need to use data.custom\_composite\_element.0.element\_key as the syntax. given that a custom composite element only ever has one row, it's always the 0 delta you need, and then the name of the key behind that. So given a custom composite with the name "abonnementen", and in there two number fields with the names "minderjarigen" and "anderen", that leaves with the following syntax: `data.abonnementen.0.anderen or data.abonnementen.0.minderjarigen`

That's it really. Took way too long to find that, and it's kind of weird to me that the "data." syntax didn't work for the checkbox element. So if anyone knows a better way, please do reply.

# Answer
> 0 votes
I suppose the elements documentations is a bit misleading. You can always try debugging like this:

```
{{ context|keys|join('+') }}
{{ data|keys|join('+') }}
{{ data|join('+') }}

```

which brought me to conditions like

```
{% if data.mycheckboxes %}

{% if mykey in data.mycheckboxes %}

```

---
Tags: 8, theming, webforms, emails
---