# Question
Title: Is there a way to disable cache only for a single template file?
For my view I need to update my fields dynamically, for this reason I need to disable cache for views-view-field.html.twig, as it takes the parameter from a contextual filter.
I send an argument from `template_preprocess_views_view_field()` to the template file.

I know how to disable the caching of template files for developers, but I cannot use it on the production system, as it may affect the performance. So the issue for me is disabling the cache only for a single template.

# Answer
> 0 votes
I believe you can use the value of your field to set a custom cache tag in your view, that should invalidate the cache whenever your field value changes.

```
template_preprocess_views_view_field(&$variables) {
  $view = $variables['view'];
  $parameter = 'my_custom_field_that_is_sent_as_argument_to_twig';
  $view->element['#cache']['tags']['custom_parameter:' . $parameter];
}

```

---
Tags: 8, caching
---


# Question
Title: How to get the parent entity title inside image.html.twig
I want to get the node title inside an image.html.twig override so I can use it to replace the 'title' and 'alt' attributes of the image. So far I was able to pass simple variables with THEME\_preprocess\_image(&$variables) but no luck getting the title of the parent node.

# Answer
The cleanest solution that I could find is to get `node` object in `image-formatter.html.twig` which is a wrapper to `image.html.twig`.

Add `THEMENAME_preprocess_image_formatter` to your `THEMENAME.theme`

```
function THEMENAME_preprocess_image_formatter(&$variables) {
  $variables["node"] = $variables['item']->getEntity();
}

```

Copy `core/themes/classy/templates/field/image-formatter.html.twig` into your `THEMENAME/templates` directory.

Now you can get the node title in this twig file using `{{node.getTitle()}}` or `{{node.label()}}`

The twig file might look like this

```
Node title: {{node.getTitle()}}

{% if url %}
  <a href="{{ url }}">{{ image }}</a>
{% else %}
  {{ image }}
{% endif %}

```

Don't forget to rebuild cache (clear cache) for the changed hooks/twig files to be seen by your Drupal installation.

**Alternatively** if you want to just change the `alt` and `title` attributes of your image based on the node title here is one way to do it (covers question in the comments)

```
function THEMENAME_preprocess_image_formatter(&$variables) {
  $node = $variables['item']->getEntity();
  $variables["image"]["#alt"] = $node->label();
  $variables["image"]["#title"] = $node->label();
}

```
> 1 votes

---
Tags: theming
---


title: Price before/above add-to-cart button

text:
# Question
Title: Price before/above add-to-cart button
Have struggled with this for a couple of days and find no easy solution (TWIG?) Drupal commerce 2.X (D8)

I need to move the price before/above add-to-cart button Like this: Color: Red Size: Medium Price: $ 49,00

Add to cart

I need to do this because the price of the product changes when you choose variation.

Thanks!

# Answer
> 1 votes
Yes indeed. a major frustration and it just makes no sense the way it is. i asked this same question a year ago and it has still not been solved. if you solve it please put the solution here.

meantime, you can use jquery appendTo() to solve it in a very ugly way. the price will initially load above the attributes and then jump down to the correct place above the cart button. it is not a pretty site but at least it works.

---
Tags: commerce
---


# Question
Title: Grouping a View by Taxonomy term with multiple values without listing the term more than once
How do I stop a Taxonomy vocabulary's terms being listed multiple times when I group a view's results by Taxonomy term and instead list the content type multiple times under single terms.

For example, this setup...

Produces this result...

Whereas what I need is it to produce a result like this... (I might have mixed up some of the categories, I did use Paint after all)

To explain the context: I have a view that lists all 'clients' that have registered to us (I have used a custom Content Type 'Client', Node Limit module and custom permissions/roles ('Client') to have a 'Client' node double as a pseudo person/business.

I have used the Taxonomy module to create a 'Clients categories' vocabulary. The terms in this vocabulary categorise Clients, however Clients **may** exist in more than one category and so a real-life client **may** check multiple checkboxes of these terms. So I have setup the content type Client's 'Number of Values' as 'Unlimited'.

## The view (exported)

```
$view = new view();
$view->name = 'Clients_index';
$view->description = 'Page view showing all Clients';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Clients Index';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Clients Index';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'domain';
$handler->display->display_options['access']['domains'] = array(
  1 => 0,
  2 => '2',
  3 => '3',
  4 => '4',
);
$handler->display->display_options['access']['domain_strict'] = 0;
$handler->display->display_options['access']['domain_member'] = 0;
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'none';
$handler->display->display_options['pager']['options']['offset'] = '0';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['style_options']['grouping'] = array(
  0 => array(
    'field' => 'term_node_tid',
    'rendered' => 1,
    'rendered_strip' => 0,
  ),
);
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'Clients' => 'Clients',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['defaults']['hide_admin_links'] = FALSE;
$handler->display->display_options['defaults']['header'] = FALSE;
/* Header: Global: Text area */
$handler->display->display_options['header']['area']['id'] = 'area';
$handler->display->display_options['header']['area']['table'] = 'views';
$handler->display->display_options['header']['area']['field'] = 'area';
$handler->display->display_options['header']['area']['empty'] = TRUE;
$handler->display->display_options['header']['area']['content'] = '<h2 class="block-title">Clients\' directory</h2>
<p>Welcome to the Clients\' . Here you can find a relevant Client by product category or by name, or search for a specific company using the search box.</p>';
$handler->display->display_options['header']['area']['format'] = 'full_html';
$handler->display->display_options['defaults']['empty'] = FALSE;
/* No results behavior: Global: Text area */
$handler->display->display_options['empty']['area']['id'] = 'area';
$handler->display->display_options['empty']['area']['table'] = 'views';
$handler->display->display_options['empty']['area']['field'] = 'area';
$handler->display->display_options['empty']['area']['empty'] = TRUE;
$handler->display->display_options['empty']['area']['content'] = '<p>To register as a Client, please contact us</p>';
$handler->display->display_options['empty']['area']['format'] = 'full_html';
$handler->display->display_options['defaults']['fields'] = FALSE;
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
$handler->display->display_options['fields']['title']['element_label_colon'] = FALSE;
/* Field: Content: All taxonomy terms */
$handler->display->display_options['fields']['term_node_tid']['id'] = 'term_node_tid';
$handler->display->display_options['fields']['term_node_tid']['table'] = 'node';
$handler->display->display_options['fields']['term_node_tid']['field'] = 'term_node_tid';
$handler->display->display_options['fields']['term_node_tid']['label'] = '';
$handler->display->display_options['fields']['term_node_tid']['exclude'] = TRUE;
$handler->display->display_options['fields']['term_node_tid']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['term_node_tid']['limit'] = TRUE;
$handler->display->display_options['fields']['term_node_tid']['vocabularies'] = array(
  'Clients_categories' => 'Clients_categories',
  'tags' => 0,
);
$handler->display->display_options['path'] = 'Clients';
$handler->display->display_options['menu']['type'] = 'normal';
$handler->display->display_options['menu']['title'] = 'Clients';
$handler->display->display_options['menu']['description'] = 'Clients\' directory';
$handler->display->display_options['menu']['weight'] = '-47';
$handler->display->display_options['menu']['name'] = 'main-menu';
$handler->display->display_options['menu']['context'] = 0;

```

# Answer
The answer is from Szerge who posted on drupal.org. I have added one more relevant step.

1. Create a *Content: Taxonomy terms on node* relationship (which is well explained in different posts like https://www.drupal.org/project/views/issues/1239278#comment-5515924)
2. Display a field with the *taxonomy term: (term) Taxonomy term: Rendered Taxonomy term* (and the field containing the taxonomy terms with MULTIPLE FIELD SETTINGS "Display all values in the same row" unchecked)
3. Add the *(term) Taxonomy term: Name (asc)* sort criteria
4. Lastly, ensure your "Format" format settings for the entire view are grouped in *Grouping field Nr.1* according to the *taxonomy term: (term) Taxonomy term: Rendered Taxonomy term*
> 0 votes

# Answer
So in the end I created a View of Taxonomy terms based on the above requirements, I then (at least first off, to get it done quickly) created a Views template specific to this (and only this) purpose.

In that template I added code after the printing of the terms that loaded the node title by taking the term id from the `$row` variable. Using `db_select()` on the `taxonomy_index` table to get the associated node ids (`nid`). I then Used `$node = node_load($nid)` to load the node and get the title `$node->title`. I have clean URLs and Pathauto installed so I had to hardcode the `/clients` portion of the required URL and passed `$node->title` through a Pathauto function `pathauto_cleanstring()` to create the alias path. Finally I used `url()` and `l()` as described in this article.

For the most part I followed this process but it's a very specific implementation so others might not want to follow it as a tutorial.
> 0 votes

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


# Question
Title: How do I pass a variable from a custom module to a template defined in a theme?
I have a theme installed to my Drupal website. The theme contains templates for both page--front.html.twig and page.html.twig. The content of the *page--front.html.twig* file is the following.

```
<div id="page-wrapper">
  <div id="page">
    <header id="header" class="header" role="banner" aria-label="{{ 'Site header'|t }}">
      <div class="section layout-container clearfix">
        {{ page.secondary_menu }}
        {{ page.header }}
        {{ page.primary_menu }}
        <div class="navigation-toggler"><i class="fa fa-bars"></i></div>
      </div>
    </header>
    {% if page.highlighted %}
      <div class="highlighted">
        <aside class="layout-container section clearfix" role="complementary">
          {{ page.highlighted }}
        </aside>
      </div>
    {% endif %}
    {% if page.featured_top %}
      <div class="featured-top">
        <aside class="featured-top__inner section layout-container clearfix" role="complementary">
          {{ page.featured_top }}
        </aside>
      </div>
    {% endif %}
    <div id="main-wrapper" class="layout-main-wrapper layout-container clearfix">
      <div id="main" class="layout-main clearfix">

        {{ page.breadcrumb }}
        <main id="content" class="column main-content" role="main">
          <section class="section">
            <a id="main-content" tabindex="-1"></a>
            {{ page.front_page }}
          </section>
        </main>

        {% if page.bottom %}
          {{ page.bottom }}
        {% endif %}
      </div>
    </div>

    <footer class="site-footer">
      <div class="layout-container">
        {% if page.footer_first or page.footer_second or page.footer_third %}
          <div class="footer-top">
            <div class="footer-top-inner">
              {{ page.footer_first }}
              {{ page.footer_second }}
              {{ page.footer_third }}
            </div>
          </div>
        {% endif %}

        {% if page.footer_left or page.footer_right %}
          <div class="footer-bottom">
            <div class="footer-bottom-inner">
              {{ page.footer_left }}
              {{ page.footer_right }}
            </div><!-- /.footer-bottom-inner -->
          </div>
        {% endif %}
      </div>
    </footer>
  </div>
</div>

{% if social %}
  <ul class="social-links">
    {% if social.facebook %}
      <li class="facebook"><a href="{{ social.facebook }}"><i class="fa fa-facebook"></i></a></li>
    {% endif %}

    {% if social.twitter %}
      <li class="twitter"><a href="{{ social.twitter }}"><i class="fa fa-twitter"></i></a></li>
    {% endif %}

    {% if social.pinterest %}
      <li class="pinterest"><a href="{{ social.pinterest }}"><i class="fa fa-pinterest"></i></a></li>
    {% endif %}

    {% if social.google %}
      <li class="google"><a href="{{ social.google }}"><i class="fa fa-google"></i></a></li>
    {% endif %}

    {% if social.youtube %}
      <li class="youtube"><a href="{{ social.youtube }}"><i class="fa fa-youtube"></i></a></li>
    {% endif %}
  </ul>
{% endif %}

{% if to_top %}
  <div id="to-top">
    <i class="fa fa-chevron-up"></i>
  </div>
{% endif %}

```

How should I add the *page* variable?
That is being used throughout the template from a custom module I created. I think I need to use some sort of hook like `hook_preprocess_html()`, but I am not quite sure how to proceed.

# Answer
In my *.module* file inside my\_module, I added the following:

```
function business_listing_preprocess_page(&$variables) {
  //check if current page is front page
  if (\Drupal::service('path.matcher')->isFrontPage()){
      $front_page = \Drupal::theme()->getActiveTheme()->getRegions('front_page');
    foreach (\Drupal::theme()->getActiveTheme()->getRegions() as $region) {
      if (!isset($variables['page'][$region])) {
        $variables['page'][$region] = [];
      }
    }
  }

```
> -1 votes

---
Tags: theming
---


title: Create dropdown list from values DB

text:
# Question
Title: Create dropdown list from values DB
I got some values from the database

```
        $result = db_select('node', 'n')
        ->condition('type', 'staff_members')
        ->fields('n', array('nid', 'title'))
        ->execute();

        $options = array();

        while($row = $result->fetchAssoc()) {
            $options[] = array("nid"=>$row['nid'], "title"=>$row['title']);
        }

```

What I try to do is implement this results into my dropdown list, so I can select the node wich I need. But it's important that the title is related with the Nid, as value.

```
        $form['staff_member_options'] = array(
            '#type' => 'value',
            '#value' => array('Nid from array' => t('Title from array'))
        );

```

I don't how this is possible because I can't make a while loop in the array, I guess?

# Answer
> 1 votes
Your $options should be:

```
while($row = $result->fetchAssoc()) {
  $options[$row['nid']] = $row['title'];
}

$form['staff_member_options'] = array(
 '#type' => 'select',
 '#title' => t('title of the select')
 '#options' => $options
);

```

---
Tags: 7, database
---


title: Cannot get value of Node object

text:
# Question
Title: Cannot get value of Node object
I'm trying to retrieve a value from a Node object. It looks like the value is there, when debugging and checking out the object. But somehow it cannot be accessed.

Trying to get the field:

```
// $this->entityManager is an instance of EntityTypeManagerInterface
$node = $this->entityManager->getStorage('node')->load($nodeId);

// hasField always returns FALSE
$node->hasField('field_google_hire_identifier');
// $node->get('field_google_hire_identifier'); returns unknown field error

```

Debugging $node-\>hasField, looking inside getFieldDefinition:

```
  public function getFieldDefinition($name) {
    if (!isset($this->fieldDefinitions)) {
      $this->getFieldDefinitions();
    }
    if (isset($this->fieldDefinitions[$name])) {
      // This code should be executed, but it is not.
      return $this->fieldDefinitions[$name];
    }
  }

```

The second if statement content is not executed, with my understanding it should be.

The node was created with migrate.

I disabled APC and Opcache.

# Answer
The field name string contained a right to left mark. See https://stackoverflow.com/questions/54653637/cannot-get-array-key-array-key-not-set/54655517#54655517 to find out how to remove it
> 1 votes

---
Tags: nodes
---


# Question
Title: How to change view mode of view row using hook_views_pre_render?
Is it possible to change the view mode of a view result in `hook_views_pre_render`?

For example I have 3 different view modes (teaser, teaser-full, teaser-short). The goal is to have the view repeat these 3 teaser templates in the view page/listing, but I'm firstly struggling to change the view mode at all.

I tried the below, but it doesn't seem to do anything.

```
function themename_views_pre_render(ViewExecutable $view) {
  foreach ($view->result as $index => $row) {
    $view->row_index = $index;
    $view->rowPlugin->options['view_mode'] = 'teaser';
  }
}

```

**Note**: If I drop a breakpoint into the code, it is being hit. But still gets rendered out as default view mode.

# Answer
I was able to change the view mode in the hook\_views\_pre\_execute() hook. I believe \_views\_pre\_render() is too late.

```
function custom_module_views_pre_execute(ViewExecutable $view) {
  // Some logic to determine view mode...

  $view->rowPlugin->options['view_mode'] = 'list';
}

```
> 4 votes

# Answer
I wasn't able to get custom\_module\_views\_pre\_execute(ViewExecutable $view) example to work.

After inspecting with xdebug, I was able to use this:

```
function custom_module_preprocess_views_view(&$variables) {
  /** @var \Drupal\views\ViewExecutable $view */
  $view = $variables['view'];
  if ($view->id() == 'view_name' && $view->current_display == "display_name") {
    if (count($view->result) == 1) {
      // Change view mode to teaser when there is only 1 item.
      $variables['rows'][0]['#rows'][0]['#view_mode'] = 'teaser';
    }
  }
}

```
> 3 votes

# Answer
The Views Parity Row solves this problem. Worked well for my needs, I just wanted a different view mode for first row item so had to apply this patch for Drupal 8. Works well for other use cases.
> 1 votes

# Answer
You could do it using the Views UI:

1. Install Entity API module
2. Make Fields your format
3. Since you have Entity API, you can add *Rendered Entity* as a field.

4. Select your view mode.

5. Add more render entity fields for your other view modes (repeat steps 3 and 4).
> 0 votes

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


title: Get node id from a grid view

text:
# Question
Title: Get node id from a grid view
I am new with D8

I have a view which lists some content about a specific content type.

I made a plugin that permit to add a custom drop button for each view rows

This button has to make some control and then redirect to a new content type or form.

This part is OK

But

I would like to know how is it possible, in the button context, I can get the node\_id of the specific content :

the button in first row will return the node\_id of content of row 1 the button in second row will return the node\_id of content of row 2 ...

# Answer
so after several hours i found the good solution ! Simple solution for people not new like me on drupal. lol

In my view I added the field "Content:id" of my content\_type And checked "Exclude from display"

In my plugin .php file in the method render(ResultRow $row) i got the famous id like this :

```
$nid = $this->getEntity($row)->id();

```

that's all !!
> 1 votes

---
Tags: views, 8
---


# Question
Title: Downloaded Drupal 8 with composer, now what?
I'm a complete Drupal newbie trying to install Drupal 8 for the first time on a new server. I downloaded the software following the instructions in section 3.5 of the User Guide, but there doesn't seem to be a next step. Section 3.6 seems to be an alternate method of downloading, and nothing in 3.7 seems to be a continuation of 3.5. How do I get back on track?

Further information: In 3.7, it says to go to the URL I set up for the site. When I do this, I get an index of the directory with these files and directories in it:

```
LICENSE
README.md
composer.json
composer.lock
[DIR] drush/
load.environment.php
[DIR]   logs/
phpunit.xml.dist
[DIR]   scripts/
[DIR]   vendor/
[DIR]   web/

```

I'm installing on Ubuntu 18.04 with Apache 2.4, MariaDB 10.1 and php 7.2.

# Answer
Composer installs all dependencies for you

Next steps

* setup a database with user and pass
* setup so that your apache/nginx see /web as the webroot (revisit/fix this step so you can get on next step)
* visiting the URL should bring up the installation procedure which should ask for DB/user/pass, follow the instructions to complete the installation
> 2 votes

---
Tags: installation
---


# Question
Title: How to limit access to vocabulary term by role?
We have two roles: `Reviewer` and `Editor` along with two content types: `Basic` and `Article`. We have a couple vocabulary terms and taxonomy fields on each content type. Currently only users with `Administer vocabularies and terms` and `Use the administration pages and help` can edit those `vocabulary` terms, but they have access to `add/edit/delete` all Vocabulary terms (something we don't want).

**How can we selectively allow only users with `Editor` role to be able to `add/edit/delete` any values in just the `Tag` vocabulary term?**

**Basic Content Type:**

Fields:

1. Category (field\_category) -\> Taxonomy term field -\> linked to `Category` vocabulary
2. Title
3. Description

**Article Content Type:**

Fields:

1. Article Tags (field\_article\_tags) -\> Taxonomy term field -\> linked to `Tags` vocabulary
2. Title
3. Description

**Desired outcome:**

1. Users with `Reviewer` role cannot access anything other than the nodes. (this is already done)
2. Users with `Editor` role should be able to access only the `admin/structure/taxonomy/manage/tags/overview` page (`Tags overview page`)
3. While on the `Tags Overview page`, users with `Editor` role should only be able to access that link and no other admin pages.
4. While on the `Tags Overview page`, users with `Editor` role should only be able to `add/edit/delete` any terms in the `Tags vocabulary`.

# Answer
Have you tried taxonomy\_access\_fix? It allows you to manage permission for each vocabulary for each role.
> 2 votes

---
Tags: 8, users, taxonomy-terms, hooks
---


# Question
Title: Inline class annotation with /** @var or just comments?
I found in some drupal commerce modules class comments in way I haven't seen so far

```
/** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
$payment = $this->entity;
/** @var \Drupal\commerce_paypal\Plugin\Commerce\PaymentGateway\ExpressCheckoutInterface $payment_gateway_plugin */
$payment_gateway_plugin = $payment->getPaymentGateway()->getPlugin();

```

I am not sure what to google to get to know more about this, why was it used like that and is this annotation or just plan comment?

# Answer
> 1 votes
I checked more about annotations and it doesnt makes sense to have them in places other then outside the class, as stated on d.org, so this is just plain comment for IDE's to connect what is used there.

> In addition, there is a performance bonus as it makes Drupal use less memory when discovering plugins. The original implementation had a getInfo() method on each class, similar to Drupal 7 test classes. This meant each class had to be loaded into memory to get its information and the memory was not freed until the end of the request, thus greatly increasing the peak memory requirement for PHP. Instead, the implementation used by Drupal to parse the annotation simply tokenizes the text of the file without including it as a PHP file, so memory use is minimized.

---
Tags: 8
---


# Question
Title: How to get programatically 'display_options' for a specific page in Views
I am a bit confused on how I should code this...
I have a view based on a custom content entity with 4 displays: default (hidden), Page (page\_1), Export Entité (rest\_export\_1) and Export pour Maps (rest\_export\_2).

Devel shows this for this view:

I'd like to get the value of the path for 'rest\_export\_1' to use it in `$name`.
My code:

```
function association_exportCSV($view, $page)
{
  $view = \Drupal\views\Views::getView($view);
  $name = ???
  $page = $view->preview($page);
  file_unmanaged_save_data($page , 'private://' . $name . '.csv', FILE_EXISTS_REPLACE);

}

```

What should I do next? How to get $name from 'path'?

# Answer
Try with:

```
function association_exportCSV($view, $page) {
  $view = \Drupal\views\Views::getView($view);
  // $display_id in this case is  'rest_export_1
  $view->setDisplay($page);
  $path = $view->getPath();
  file_unmanaged_save_data($page, 'private://' . $path . '.csv', FILE_EXISTS_REPLACE);
}

```
> 0 votes

# Answer
```
function association_exportCSV($view, $page)
{

  $view = \Drupal\views\Views::getView($view);

//Solution 1
  $display = $view->storage->getDisplay($page);
  $path = $display['display_options']['path'];

//Solution 2
  $view->setDisplay($page);
  $path = $view->getPath();

  $data = $view->preview($page)['#markup'];
  file_unmanaged_save_data($data , 'private://' . $path, FILE_EXISTS_REPLACE);

}

```
> 0 votes

---
Tags: views, 8
---


title: Converting iso code to name

text:
# Question
Title: Converting iso code to name
How can i convert country iso code to country name while creating a node programatically using node\_save? I am creating nodes programatically by fetching contents from secondary database of drupal. When i do this way, am getting country iso code in the country field instead want the name of the country. How can i achieve this?

# Answer
You can use

```
$name = location_country_name($iso_code);

```

For reference http://www.drupalcontrib.org/api/drupal/contributions%21location%21location.inc/function/location\_country\_name/7
> 1 votes

# Answer
```
$countries = country_get_list();
$country_name = $countries[$country_iso_code]

```

Example: if $country\_iso\_code is 'ES' then the above will return 'Spain' in $country\_name
> 0 votes

---
Tags: location
---


# Question
Title: Single content type with urls that can differ
A site I am working on has a content type called `property` with a large number of fields within where the data is brought in from a 3rd party API.

Currently we use `pathauto` for generating alias urls of our content and has admirably filled our needs, except for the property content type which has a number of conditions which can determine what its url is and I am unsure that pathauto can do what is required.

We are using Drupal 8, latest version.

A properties url will contain the location, the listing type (sale, rental, auction or new-home) and the title of the property in its url.

So for example, a property with title `ABC` which is been `sold` in `henley` would have a url along the lines of `http://example.com/property-for-sale/henley/abc`.

But a property `xyz` on `auction` in `basingstoke` would be along the lines of `http://example.com/auctions/basingstoke/xyz`

Is there a hook/module or Drupal way (Views?) of handling this please? IF I remember Drupal 7 had `hook_url_inbound_alter` but I cannot find this in the D8 API.

Any enlightenment would be appreciated.

Grateful Grasshopper/John

# Answer
If your Location, Listing type, and title are Fields in your Content type you can use Pathauto Patterns options (`/admin/config/search/path/patterns`) to automatically generate the aliases from values in nodes.

You use tokens available for the content type to construct the pattern. You can browse through (a very long) list of tokens to find the one you're looking for. Maybe it would be something like:

`[node:field_type]/[node:field_location]/[node:title]`
> 0 votes

---
Tags: 8
---


# Question
Title: Multilingual site, always use language path prefix (no bare URLs)
I have a Drupal 8 site with two languages, Japanese (default language) and English.

By default, the default language pages are available at both `/` and `/ja`.

For example, `/about` and `/ja/about` both go to the Japanese "about" page.

I want to get Drupal to force the path prefix so that the URL is always shown as `/ja/about` and never just `/about`.

**Interface text language detection** settings

* URL (path prefix, english: en, Japanese: ja)
* Selected language (Japanese)

How can I do this?

**For Drupal 7:** see this question

# Answer
1. Select "English" as the default language and save
2. Select "Japanese", again, as the default language and save

This way, you will force Drupal to prefix the URL's by the language id, even for the default language.
> 4 votes

# Answer
Here the steps:

1. Install Redirect module.
2. Enable the module `/admin/modules`
3. Go to admin page `/admin/config/search/redirect/settings`.
4. Ensure **Enforce clean and canonical URLs** is checked.
> 6 votes

# Answer
Prefix - suffix configuration is moved to the URL language detections settings at Drupal 8 Please, use this path to edit suffixes for each language:

```
admin/config/regional/language/detection/url

```

And dont forget to move up URL detection rule
> 2 votes

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


title: Translated Nodes Redirect To Homepage

text:
# Question
Title: Translated Nodes Redirect To Homepage
I'm using Drupal 8.6.9 and have four languages setup:

* English *(Default)*
* Spanish
* German
* French

When I create a node of any content type and publish it as each one of these languages, everything seems fine when logged in. When I log out and view these pages they're fine again, but only for the default language. If I try to view a translated version of a node I just get redirected to the site's root back on the default translation.

I'm using URL detection which works when logged in fine.

There are no custom permissions setup and everything is properly published.

I can see that the redirect is a `308 Permanent Redirect` from looking at the dev tools.

I've tried rebuilding permissions, clearing the cache etc with no success, any help would be much appreciated!

Thanks

# Answer
Solved. The issue was arising from a change I'd made to the KernelRequestSubscriber where I was redirecting users that hit the homepage that wasn't on the actual root of the site (to stop the homepage from being accessible from multiple routes - duh).
> 0 votes

---
Tags: 8
---


title: Debug plugin discovery

text:
# Question
Title: Debug plugin discovery
A plugin that I have written is not being discovered.

For eg : https://www.drupal.org/node/2847639

Is there a general suggestion for debugging failing plugin discovery?

# Answer
Most of the time it is because the file is not picked up, there are a few common cases for that:

1. Ensure that the filename matches the class name exactly, case sensitive. Without the extension of course.
2. Ensure that the namespace matches the folder path exactly, case sensitive.
3. Restart Apache to clear apcu cache, I've had issues with this when renaming/moving files with a class quite a bit in Drupal 8. Also setting class\_loader\_auto\_detect to FALSE in settings.php should solve this one.

There are even more things to check if you're actually the one providing the plugin type such as the plugin manager.
> 6 votes

# Answer
Additionally to the bullet points in the accepted answer...

Ensure that the structure of the comment is correct, not only the layout of the annotation section, but the layout of the comment block itself (including the number of asterisk) is also important. Remembering the Annotation class is itself an annotated class.

I was having the same issue as this question, and ended up with 'print\_r' statements littered throughout the getDefinitions() function mentioned in a comment in the first question to determine where it falied. That made me look at my Annotation class and realize the comment block was started with '/\*' instead of '/\**'

I would put this a comment, but I don't have the required reputation.
> 3 votes

---
Tags: 8, debugging, plugins
---


# Question
Title: How to get a second join into hook_views_data?
I am trying to make the value of a string (name) found in `mymodule_names.name` available to **Views** by means of `hook_views_data()`.

To get the name, I need to first look up the `nid` of the node I want to view in a table named `mymodule`. This tells me the *email-address* of user who authored the node. Then I need to look up the email address in the table `mymodule_names`, by finding the row where the *same* email address is in the column `mymodule_names.email`. What I want returned is the user name attached to that email-address, which the value of `mymodule_names.name` in the same row.

The code below is how far I have been able to get. This makes the value of `mymodule_names.email` available - but getting that is just an intermediary step. I think I need a *second* join to get the user name. I am unable to figure out how to do do that. How should I modify this code to get the data from the second table?

```
/**
 * Implements hook_views_data().
 */
function mymodule_views_data() {
  $data = array();
  $data['mymodule']['table']['group'] = t('MyModule');
  $data['mymodule']['table']['base'] = array(
    // This is the identifier field for the view.
    'field' => 'nid',
    'title' => t('MyModule'),
    'help' => t('Table contains ...'),
    'weight' => -10,
  );

  // This table references the {node} table. The declaration below creates an
  // 'implicit' relationship to the node table, so that when 'node' is the base
  // table, the fields are automatically available.
  $data['mymodule']['table']['join'] = array(
    'node' => array(
      // Primary key
      'left_field' => 'nid',
      // Foreign key
      'field' => 'nid',
    ),
  );
  $data['mymodule']['nid'] = array(
  'title' => t('Title'),
    'help' => t('Help.'),
  );
  // Join with the email field.
  $data['mymodule']['email'] = array(
    'title' => t('Email'),
    'help' => t('Author email.'),
    'field' => array(
      'handler' => 'views_handler_field',
      // This is used by the table display plugin.
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_string',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    ),
  );
  return $data;
}

```

(This is a non-standard setup where `node.uid` cannot be used to get the node author UID.)

I know how to get the name by inserting a subquery with `hook_views_query_alter()` (see: this answer). The question is about doing *without* using subquery.

# Answer
```
$data['mymodule']['table']['join']['node'] = [
  //Second table for Join
  'left_table' => 'foo',
  'left_field' => 'nid',
  'field' => 'nid',
]

```

more info: https://api.drupal.org/api/drupal/core%21modules%21views%21views.api.php/function/hook\_views\_data/8.6.x
> 1 votes

---
Tags: 7, views
---


# Question
Title: How can I add a class to a view list item that has a moderation state of draft
I have a view that outputs a list of nodes for a menu. The view displays the title linked to the node. The View allows published nodes or nodes in the moderations states draft or review. How can I add a class around the titles that are in draft or review. I would like to style these differently. I am using drupal\_view to print the block inside a template. Can this be done in a theme preprocess or custom module?

# Answer
> 1 votes
This can be done through the Views interface.

You can add classes based on existing Field values to entire **rows** in `Format > Settings`, or you can add classes to **individual Fields** (you mentioned title) under `Style settings` wrapper or field HTML options.

Tokens to use in all of these cases can be found in the settings of the Field according to which you want to style the rows/other fields. The settings are under `Rewrite results > Override the output of this field with custom text > Replacement patterns` options.

You don't have to actually keep the rewrite enabled, you just need to temporarily reveal and uncollapse to copy the tokens you need.

Then add CSS for those classes to your subtheme as usual, or through CSS editor module. You can hide the field ("Exclude from display") but it needs to be there on the list, arranged before any other fields that may use its value for classes.

---
Tags: views, 8
---


title: How to get Ajax to load first?

text:
# Question
Title: How to get Ajax to load first?
After updating module `webform_paymethod_select` I noticed that Ajax on webforms stopped working. I was unable to edit any existing webforms or create new ones. This happens when JS Aggregation is enabled. Clearing caches did not help.

Console shows two error messages:

```
TypeError: D.ajax is undefined
  var beforeSerialize = D.ajax.prototype.beforeSerialize;

TypeError: Drupal.ajax is undefined
  Drupal.ajax.prototype.commands['getBlock'] = function(ajax, response, status) {

```

The first error is coming from jQuery update and the second one is coming from the `boxes` module. Disabling boxes module worked for me but it left an important part of my site broken.

I believe the reason is that Ajax is unable to load before `boxes` requires it. After this Ajax just does not load at all.

If anybody can help me out, I would appreciate it.

EDIT:

I couldn't quite figure out how to get Ajax to load before everything. I tried changing its weight in `drupal_add_js()` and modifying `hook_boot()` to get it to load first. This seemed dangerous as i couldn't guarantee that it would only apply to the pages i needed Ajax to be first in. I then turned to figuring out how to encapsulate the `boxes` modules' JavaScript code that was throwing this error. I noticed that the code was being encapsulated with the following:

```
(function ($) {
  ..
})(jQuery);

```

Drupal suggests using :

```
(function ($) {
  // All your code here
}(jQuery));

```

That didn't work either, so i used the following instead and this made the error go away (except for the error jQuery Update is throwing):

```
jQuery(function($){
  ..
});

```

I am now able to edit existing webforms. I don't really understand why this worked, so if anybody can provide some insight i would appreciate it.

# Answer
> 1 votes
It could help.

add php function:

use Drupal\Core\Ajax\AjaxResponse;

Class AnyClass extends FormBase {

public function buildForm(array $form, FormStateInterface $form\_state) {

```
/**
 * Running the library drupal core ajax
 */
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';

```

}

}

---
Tags: 7, ajax, webforms, blocks
---


# Question
Title: How can I leave Subject as blank when fill nothing in the subject field of a comment?
When we fill nothing in the subject field of comment, drupal will use the comment body as the value of subject. See the code in `CommentForm::buildEntity`

```
// Validate the comment's subject. If not specified, extract from comment
// body.
if (trim($comment->getSubject()) == '') {
  if ($comment->hasField('comment_body')) {
    // The body may be in any format, so:
    // 1) Filter it into HTML
    // 2) Strip out all HTML tags
    // 3) Convert entities back to plain-text.
    $comment_text = $comment->comment_body->processed;
    $comment->setSubject(Unicode::truncate(trim(Html::decodeEntities(strip_tags($comment_text))), 29, TRUE, TRUE));
  }
  // Edge cases where the comment body is populated only by HTML tags will
  // require a default subject.
  if ($comment->getSubject() == '') {
    $comment->setSubject($this->t('(No subject)'));
  }
}

```

I still need to show Subject if it's been filled, while leave the Subject as blank when the user fill nothing in. To programmatically change the default behavior, we may need to override the function after `buildEntity` take place, otherwise `buildEntity` will override it again to the comment body. Is it possible to do that?

# Answer
> 0 votes
After codes pile up, the issue comes back again. Maybe some other function definition causes the above code of @Jdrupal lose its effect. I now use a reverse process of `buildEntity` in `hook_ENTITY_TYPE_presave` to achieve my purpose. Though not neat, it works:

```
$subject = strip_tags($entity->get('comment_body')->value);
if(strpos($entity->getSubject(),$subject) !== false)
  $entity->setSubject('');

```

# Answer
> 1 votes
You can use `hook_ENTITY_TYPE_presave` to do this, just call

```
 if (!$entity->getSubject()) {
   $entity->setSubject('');
 }

```

if it isn’t filled.

Hope it makes sense.

---
Tags: 8, entities, comments
---


# Question
Title: Redirecting to a page based on the sub-domain
How can I redirect visitors to a specific page based on the sub-domain? For example:

* www.site.com goes to frontpage
* checklist.site.com goes to checklist.site.com/checklist

My server is set to work with a wildcard (\*.site.com). All sub-domains point to the same Drupal site.

I found Redirect based on query string about redirecting in Drupal 8, but I am not able to achieve what I want following what reported there.

# Answer
The linked post points in the right directions, but contains a lot of code you don't need. Use this change record https://www.drupal.org/node/2013014 instead and check $request-\>getHost():

```
  public function checkForRedirection(RequestEvent $event) {
    if ($event->getRequest()->getHost() == '...') {
      $event->setResponse(new RedirectResponse('http://example.com/foo/'));
    }
  }

```

For a non-coding solution you can try **Redirect Domain**, a submodule of Redirect.
> 0 votes

---
Tags: 8, redirection
---


# Question
Title: How can I know which button was clicked?
I have a form with a "Submit" and a "Cancel" buttons. In `hook_submit()`, how do I know which button was clicked?

# Answer
You must use the `triggering_element` from the `$form_state['triggering_element']`.

Best practice is to define a `#name` attribute for your button, so you can have this value in the `triggering_element`.

For example:

```
$form['delete'] = array(
  '#type' => 'submit',
  '#value' => t('Delete'),
  '#name' => 'delete',
);

```

If you don't define this attribute `triggering_element` will hold the button's `#value` (the text that user can read), but this is discouraged as other modules may change this value or be changed by the localization).

You may use `$form_state['clicked_button']` too, but this is **deprecated**.

You can read more info at the drupal\_build\_form function documentation page.
> 27 votes

# Answer
`$form_state['clicked_button']['#value']` will tell you which button was clicked on the form.
> 7 votes

# Answer
# **UPDATE 2016 Drupal 8**

For those still trying to figure out how to access the triggered event here is the Drupal 8 solution.

`$form_state->getTriggeringElement()`

This returns the array of the triggering submit element. If you add a markup called `#name` then you would access it with the following way.

`$button_clicked = $form_state->getTriggeringElement()['#name']`

The reason behind this change is that `FormStateInterface` is now a `readOnly` file in which only classes that extend `FormStateInterface` can access the variables. So you have to use accessor methods like `getTriggeringElement()` in order to access the variable.
> 6 votes

# Answer
Name the buttons with the `#name` attribute, like this:

```
$form['delete'] = array(
    '#type' => 'submit',
    '#value' => t('Delete'),
    '#name' => 'delete',
);

```

and then use:

```
$values = $form_state['input'];
if (isset($values['delete'])) // 'delete' button was pressed.

```
> 3 votes

# Answer
Compare these values in `$form_state` I have been doing in Drupal 6 and would be same in Drupal7

```
if($form_state['values']['ok'] == $form_state]['clicked_button']['#value']){
    //Process if OK is pressed
}else if($form_state['values']['cancel'] == $form_state]['clicked_button']['#value']) {
    //Process if Cancel is pressed
}

```
> 2 votes

# Answer
In Drupal 8.4.4 `$form_state->getTriggeringElement()['#name'];` gives you the value of `op`. When you look for that key in the form state's values array, you get the `#value` key of the button form element-- in other words, the string that the end users sees on the button on the page.

I don't know if `$form_state->getValues()['op']` is universal for all forms, but I'm hard-coding it in my module's form.
> 2 votes

# Answer
**Drupal 8.6.7**

Create button something like below.

```
$form['my_button'] = [
    '#type' => 'button',
    '#value' => t('Custom Button'),
    '#name' => t('customButton'),
    '#weight' => 0,
    '#attributes' => [
      'class' => ['populate-bib-button', 'btn', 'btn-primary'],
    ],
  ];

```

In your submit function get button name like below code.

```
$input = $form_state->getUserInput();
print $input['_triggering_element_name']; // customButton

```

Comparison can be done like

```
if ($input['_triggering_element_name'] == 'customButton') {
  // Do something.
}

```

#Drupal8
> 0 votes

---
Tags: 7, forms
---


# Question
Title: How do I get the requirements in a module's composer.json merged into the consolidated composer.json?
I am trying to use *composer* correctly to install a library named `nikic/php-parser`.

Thanks to helpful comments by *Clive*, I now understand that when a Drupal 7 module comes with a `composer.json` file, that file is supposed to be merged into a consolidated `composer.json`-file, and from then on things will be taken care of more or less automatically.

That things are *supposed* to work that way also follows from this note on the **Composer Manager** project page:

> Composer Manager allows each contributed module to ship with its own composer.json file, listing the module-specific requirements. **It then merges the requirements of all found modules into the consolidated composer.json file.** This results in a single vendor/ directory shared across all modules which prevents code duplication and version mismatches. \[My emphasis.\]

The Drupal site where I use for testing is a fresh install of Drupal 7, organized as Drupal 7 is normally organized when you install it using drush (`drush si standard`).

The **Composer Manager** package contains a `composer.json` with the following requirement:

```
"require": {
    "php": ">=5.3.0",
    "nikic/php-parser": "^4.2"
}

```

I have the Drupal variable `composer_manager_vendor_dir` set to `sites/all/vendor` and the composer directory for the consolidated `composer.json` is set to `/sites/default/files/composer`.

The consolidated `composer.json` currently contains:

```
{
  "require": {
    "symfony/yaml": ">=3.1",
    "php": ">=5.3.0"
  },
  "config": {
    "autoloader-suffix": "ComposerManager",
    "vendor-dir": "../../../all/vendor"
  },
  "prefer-stable": true
}

```

I.e., it does *not* include a requirement for `nikic/php-parser`. The note from the project cited above seems to imply that it would somehow be merged in automatically. This is yet to happen on my test site.

Following up another hint by *Clive*, I ran:

```
drush composer-manager install

```

This resulted in:

```
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
  - Installing symfony/yaml (v3.1.0)
    Downloading: 100%
Generating autoload files

```

I.e. it did the updates that was required per the consolidated `composer.json`. But it did not pay attention to the `composer.json` in the module's directory.

Trying:

```
drush composer-manager update

```

... did not resolve the issue.

There must be something fairly obvious I am missing.

How do I get the requirements in a module's composer.json merged into the consolidated composer.json (apart from splicing it in "by hand")?

# Answer
> 0 votes
I think I've figured it out.

This is supposed to happen automatically. If the module is enabled with *drush* under Drupal 7, it does. If you use *other* means to enable, the module, this might not happen.

In case the root `composer.json` for some reason is missing the requirements for a specific module, using *drush* to disable and then again *re-enable* the module fixes the problem. E.g.:

```
drush dis composer_manager -y
drush en composer_manager -y

```

This seems to be all that is required.

It should be emphasised that this is only valid for Drupal 7. Drupal 8 is a completely different beast.

---
Tags: 7, composer
---


title: Uploaded files don't appear on the page

text:
# Question
Title: Uploaded files don't appear on the page
**My research**
I have browsed some of the other similar questions asked regarding this but the fixes do not work for me so I figured I'd ask a new question in the hopes that I can help myself and hopefully others that have the same issue. I have also checked the drupal help forums which again does not fix my issue.

**What I want to happen**
This is using Drupal 7. I want to make it so that when creating a news article, I can upload files that can be downloaded when people view the page.

**What happens when I try to do this**
I have added the field successfully and when creating the page, I can upload the file and it shows in the preview. However, when I save the page, although the file shows as uploaded in the 'edit' side, it does not show on the public page.

**What I've tried**
Additionally, when checking in the files through FTP, the files gets uploaded to the sites/default/files/ directory. I have checked, double checked and tripled checked the permissions which I even set to 777 briefly so permissions doesn't seem to be the issue here.

I have tried commenting out some lines in the sites/default/files/.htaccess file which is one fix I found but unfortunately didn't work for me.

I have checked user permissions which, again, isn't the issue as I'm an admin with every permission checked.

I have also copied the exact settings from another website where this feature is working in case I missed something very simple but this didn't work either unfortunately. The file upload field is set to display and I believe that it's set up appropriately although it is possible I'm missing something extremely simple.

I'm more than happy to update my question with further information if anyone needs any more to help me out. I'm completely baffled on this one so any help would be greatly appreciated.

# Answer
So after a lot of digging, I realised that this issue was due to the Panels module.

I had only added the field the usual way you would; through the content type when it turns out you need to configure it through the Panels view (which I was completely unaware of until today).

You would think that configuring it though the content type would be enough but evidently not.

Nonetheless, hopefully my question and answer will come in useful to someone one day who encounters a similar issue to mine.
> 0 votes

---
Tags: files
---


title: How to use tokens in webforms?

text:
# Question
Title: How to use tokens in webforms?
I'm trying to use the \[current-page:url\] token in a webform hidden field (as the default value) but the submission shows "\[current-page:url\]" literally. Am I missing something?

# Answer
> 1 votes
token is a contributed module and not part of Drupal 8 or webform installation. You have to install and enable before you can use it.

```
composer require drupal/token
drush en token

```

**NOTE:** Webform is not aware of token directly and does not complain because it thinks are you just inputting text

---
Tags: webforms, tokens
---


# Question
Title: Get out of maintenance mode using database query (without using drush or admin area)
I understand there are very many stackoverflow questions on this very topic.

How can get my site out of maintenance mode? for example.

However I've never seen one that explains how to turn off maintenance mode using only a database query. I run a complex site that does not allow you to login directly using /user since it's using a special sso. So there are times when I do not have access to the admin area and I do not have access to the user login either. I don't always have ssh access to run drush, but I do usually have direct access to the mysql database.

I did find an entry in the config table that seems related.

The name is system.maintenance and the data is

```
a:3:{s:7:"message";s:93:"@site is currently under maintenance. We should be back shortly. Thank you for your patience.";s:8:"langcode";s:2:"en";s:5:"_core";a:1:{s:19:"default_config_hash";s:43:"Z5MXifrF77GEAgx0GQ6iWT8wStjFuY8BD9OruofWTJ8";}}

```

I see where it shows the message, langcode and hash settings but I do not see where it defines whether it's on or off.

Is there a location in the database that would allow me to turn maintenance mode on and off directly?

# Answer
> 3 votes
It's never the best idea to manipulate the database directly (for the usual reasons), but if you're out of other options, it's not that unsafe:

```
UPDATE key_value
SET value = '<value>'
WHERE collection = 'state'
AND name = 'system.maintenance_mode'

```

Where `<value>` is replaced with a serialised PHP string representing the integer value `1` for enabled, or `0` for disabled, e.g.

```
$value = serialize(1);

```

You'll probably want to invoke a cache rebuild after manually updating the variable, it's probably cached somewhere.

---
Tags: 8, configuration, maintenance-mode
---


# Question
Title: Adding core Javascript libraries in my_module.libraries.yml
I've read Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module and I can see where you can add assets that are part of your module or from a CDN or external source. What about if that library you want to add is already a core asset?

I'm trying to add `jquery.ui.accordion` to my modules so in my `*.libraries.yml` I have:

```
my_module:
  js:
    /core/assets/vendor/jquery.ui/ui/widgets/accordion-min.js: { minified: true }
  dependencies:
    - core/jquery.ui
    - core/jquery.ui.widget

```

That library is never loaded. What am I missing? Is there a better way to add core assets to my module?

**EDIT:** I've also tried different paths like:

```
core/assets/vendor/jquery.ui/ui/widgets/accordion-min.js: { minified: true }
../../../core/assets/vendor/jquery.ui/ui/widgets/accordion-min.js: { minified: true }

```

# Answer
> 0 votes
I just scraped the `MY_MODULE.libraries.yml` and utilized one of the other methods of adding assets, by:

```
function MY_MODULE_page_attachments(array &$attachments) {
  $attachments['#attached']['library'][] = "core/jquery.ui.accordion";
  //new addition below
  $attachments['#attached']['library'][] = "MY_MODULE/MY_MODULE.accordion";
}

```

This works for me. Perhaps you don't need a `MY_MODULE.libraries.yml` if you are trying to add libraries that already exist in core.

Edit: So I still have a `MY_MODULE.libraries.yml` file however it now just adds my module's javascript (with a dependency to jQuery). It's just some Javascript that initializes jQuery UI accordions. I still use the code above to add jQuery s UI accordion javascript and my own.

---
Tags: 8, javascript
---


title: MailManager override "from" email

text:
# Question
Title: MailManager override "from" email
I use MailManager to send emails to end users for notifications. I would like to override the email address shown to the end user, using a "fake" address shown and not the real mail account used to send the email. I use the following code, however, in my gmail receiving account I don't see the `noreply@mymailserver.com` but the real email account used.

```
$params['message'] = $message;
$params['subject'] = $title;
$key = 'send_email';
$langcode = \Drupal::currentUser()->getPreferredLangcode();
$send = true;
$result = $mailManager->mail($module, $key, $targetEmail, $langcode,
                    $params, 'noreply@mymailserver.com', $send);

```

Is there a way to define a custom address to be shown to the end user? Am I missing something?

# Answer
> 1 votes
You can use hook\_mail\_alter to customize the From:

```
MODULE_NAME_mail_alter($key, &$message, $params) {

  switch ($key) {
    case 'my_email_key':
      $message['headers']['From'] = 'My Email Name <my_email@address.com>';
      break;
  }
}

```

---
Tags: 8, emails
---


# Question
Title: How do I recreate the system.site configuration element?
For some reason `system.site`, `system.performance` and `system.date` config values have been deleted from our site.

I have the original configuration files, but when attempting to import those using drush cim, Drush complains about the site UUID mismatch.

```
The import failed due to the following reasons:
Site UUID in source storage does not match the target storage.

```

I assume this is because UUID is missing entirely. If I run `drush cget system.site`, I get the following error:

```
[error]  Config system.site does not exist

```

Attempting to set the UUID with `drush config-set "system.site" uuid "my site id"` also fails with:

```
[error]  Config system.site does not exist

```

So now I'm in a bit of conundrum.

Any suggestions on how to restore the `system.site` configuration?

# Answer
> 2 votes
I solved it with Drush.

To get around the UUID mismatch I uncommented the UUID field in `system.site.yml` and ran `drush cim`. After that I specifically set the UUID by running `drush cset "system.site" uuid "my site id"`.

---
Tags: configuration
---


# Question
Title: How do I test a paragraph bundle entity reference with Behat?
I am learning Behat with Drupal 8 and I'm stuck on trying to test a paragraph bundle (`field_related_content`) which has a title and description field, the title is an entity reference field to content type `marine_notices`. Currently I have the below, but the results are 'No link to Post Title', am I missing something?

```
  @api
  Scenario: Reference site pages from within a "marine_notices" node
  Given "marine_notices" content:
    | title      |
    | Post title  |
  When I am viewing a "marine_notices" content:
    | title                | Post title         |
    | field_related_content | Post title - <front> |
  Then I should see the link "Post title"

```

# Answer
I needed something similar so I implemented a context for paragraph support.

Install using `composer require miiimooo/behat-tools`

The follow the installation and usage here: https://github.com/miiimooo/behat-tools

In your feature you can then write:

```
Feature: Content
  @api
  Scenario: Paragraph creation through Drupal 8 API

    Given a "my_paragraph_type" paragraph named "my_arbitrary_name":
      | title             | Lorem ipsum |

    Given I am viewing a "page" content:
      | title            | Dolor sed         |
      | field_paragraphs | my_arbitrary_name |

```
> 2 votes

---
Tags: 8, testing
---


title: Contextual filter by taxonomy terms

text:
# Question
Title: Contextual filter by taxonomy terms
I have a two taxonomy vocabulary labeled as "Region and Category". Also made this as entity reference to a custom content type.

Now, I created a view of contents of "Business Page" and I want to create a contextual filter by taxonomy term, both Region and Category.

Temporarily, what I did is just focus on one taxonomy, by Region, to test if it works.

Please see images below for my configuration:

And this is the result:

My problem it is only working on term ID and not term Name.

I want to input the term Name and result would display on the page.

PS: I have a Pathauto enabled and added URL aliases to each terms.

# Answer
I found this simple answer: How to use use Term:Name as a contextual filter
> 2 votes

# Answer
I'll try to explain better Johnn's answer and relative link.

1. add a relation to your View. Something like **Taxonomy term referenced by field\_my\_taxonomy** (you may want to make this required)
2. add a Contextual Filter to **Name** (Taxonomy term). Check Relationship is set to your taxonomy reference field (field\_my\_taxonomy in my example)
3. the key setting is: When the filter is NOT in the URL: **Raw values extracted from URL**, select position by your pattern and check "Use path alias"

You may want to specify the **evalutation method Taxonomy term NAME** (not ID), selecting the vocabulary.

If term names can contain spaces you should check the option to transform them in "-" and for pretty looking titles you can use the "Uppercase/Lowercase" thing.
> 1 votes

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


# Question
Title: Delete a node after X weeks it was created
How can I delete a node after, for example, 2 weeks it has been created?

# Answer
If you're looking for a developer-centric solution, you can invoke `hook_cron()` in a custom module to clean up old nodes:

```
function MYMODULE_cron() {

  // Other conditions can be altered/added as neeed
  $query = \Drupal::entityQuery('node')
    ->condition('created', strtotime('-2 week'), '<=');
  $nids = $query->execute();
  foreach ($nids as $nid) {
    $node = node_load($nid);
    $node->delete();
  }
}

```
> 18 votes

# Answer
Based off Shawn Conn's answer, here is the full solution for novices:

1. Go to your root file directory and create folder "delete\_old\_nodes"
2. Create a file in the folder you just created called: "delete\_old\_nodes.info.yml" and paste this code in it:

```
name: Delete old nodes
description: Deletes nodes older than 30 days.
package: Custom
type: module
version: 1.0
core: 8.x

```
3. Create a file called "delete\_old\_nodes.module" and put this code into it:

```
<?php

function delete_old_nodes_cron() {

  $query = \Drupal::entityQuery('node')
    ->condition('created', strtotime('-2 week'), '<='); // Can change -2 week to -2 year or -3 day
  $nids = $query->execute();
  foreach ($nids as $nid) {
    $node = node_load($nid);
    $node->delete();
  }
}

```
4. Flush cache, then navigate to modules page — (yoursite.com/admin/modules) — and enable your module, (by searching for "delete old nodes", click the checkbox by the modules name and click save).
5. Done! Whenever you run cron, the nodes/pages that were published -2 weeks, or whatever you have it at, from now will be deleted.
6. Note: To schedule when cron runs, go to yoursite.com/admin/config/system/cron

Testing:

Create a node and change the published date, normally in the right sidebar, to -2 weeks or whatever you have it at. Manually run cron at yoursite.com/admin/config/system/cron and you should not be able to find your node.
> 4 votes

# Answer
I would use a `hook_cron()` implementation too, but using the following code.

```
function mymodule_cron() {
  $storage_handler = \Drupal::entityTypeManager()->getStorage('node');
  $query = \Drupal::entityQuery('node')->accessCheck(FALSE)
    ->condition('created', strtotime('-2 week'), '<=');
  $result = $query->execute();
  if (!empty($result)) {
    $nids = array_keys($result);
    $nodes = $storage_handler->loadMultiple($nids);
    $storage_handler->delete($nodes);
  }
}

```

The code I used to delete the nodes is the one that the deprecation message for `entity_delete_multiple()` suggests to use.
I also used a call to `accessCheck(FALSE)` to avoid the entity query returns only the nodes to which the anonymous user has access. (Cron tasks run as anonymous user.)

If then there is the possibility the nodes to delete are too much, I would limit the number of nodes deleted each time cron tasks run.

```
function mymodule_cron() {
  $storage_handler = \Drupal::entityTypeManager()->getStorage('node');
  $query = \Drupal::entityQuery('node')->accessCheck(FALSE)
    ->condition('created', strtotime('-2 week'), '<=')
    ->range(0,30);
  $result = $query->execute();
  if (!empty($result)) {
    $nids = array_keys($result);
    $nodes = $storage_handler->loadMultiple($nids);
    $storage_handler->delete($nodes);
  }
}

```
> 3 votes

# Answer
I would do try to do it as such:

1. Create a View of all nodes that are 2+ weeks old
2. Create a system Rule to run on Cron maintenance
3. In the rule configuration, create a loop to iterate over those view results
4. Delete each node

I'll try to test it when I get a chance, because I'm not entirely sure how easy/possible it'll be to utilize the view like that in 3., but that's definitely where I'd start. Of course, this comes with the caveat that it won't delete nodes when the become EXACTLY 2 weeks old, but will be dependent on when Cron runs on your system; but, I assume within 3 hours or so is still sufficient.

(I only just noticed this was for D8; I think the process is still sound though.)
> 0 votes

---
Tags: nodes, 8
---


title: Select any entity created today

text:
# Question
Title: Select any entity created today
One of an entity properties is a timestamp, set when it was created.

I want to use the `EntityFieldQuery` class to load entities that were created today.

Normally, I would write a query using `DATE_FORMAT(FROM_UNIXTIME(created_timestamp), "%Y-%m-%d") = "2014-03-17"`.

I'm not aware of any method to use any MySQL functions in `EntityFieldQuery`. I have tried with the following code.

```
$day_start = strtotime(date('Y-m-d 00:00:00', $created_ts));
$day_end = strtotime(date('Y-m-d 23:59:59', $created_ts));
$query->propertyCondition('created', $day_start, '>')
  ->propertyCondition('created', $day_end, '<');

```

Whilst this works, it doesn't seem as efficient and certainly less succinct. Is there a function that I can use with `EntityFieldQuery` similar to `SelectQuery::where()` that would allow to write code similar to the following one?

```
$query->propertyWhere('DATE_FORMAT(FROM_UNIXTIME(created), "%Y-%m-%d")', "2014-03-17");

```

# Answer
> 4 votes
You can use below code , PropertyCondition accepts range values using BETWEEN operator.. Since timestamp is stored as int in database node table created column with data and time together below code works to fetch records of a particular date..

```
<?php
$day_start = strtotime(date('Y-m-d 00:00:00', $created_ts));
$day_end = strtotime(date('Y-m-d 23:59:59', $created_ts));
$query
    ->propertyCondition('created', array($day_start, $day_end), 'BETWEEN');
?>

```

Find more about propertyCondition in D.O

# Answer
> 2 votes
No there's no such method in `EntityFieldQuery`. If you take your code here:

```
$query
  ->propertyWhere('DATE_FORMAT(FROM_UNIXTIME(created), "%Y-%m-%d")', "2014-03-17");

```

Just imagine what Drupal would have to do to determine *which* property (column) you're referring to here. It would have to parse the SQL string and pull out the `created` string before it can get the field meta data - arguably an expensive and unnecessary step.

Since an `EntityFieldQuery` is only supposed to be used for query entities by property/field, the methods provided are (necessarily) limited. I think your less-succinct method is the best you'll get without subclassing and extending.

# Answer
> 1 votes
> I want to use the `EntityFieldQuery` class to load entities that were created today.

In that case, you don't need the equivalent of `SelectQuery::where()`.

If the creation date cannot be set to any date in the future, you can simply use the following code.

```
$query->propertyCondition('created', strtotime('today'), '>=');

```

Otherwise, I would use the following code.

```
$query->propertyCondition('created', array(strtotime('today'), strtotime('today 23:59:59')), 'BETWEEN');

```

---
Tags: 7, database, datetime
---


# Question
Title: Infinite scroll is firing multiple times
I have looked for other answers on the same topic but still cannot find a solution why the event is firing more times in my code:

```
  (function($, Drupal, drupalSettings) {
    Drupal.behaviors.news = {
        'attach': function(context) {

            $(".loader").hide();
            var loadIndex = 0;
            var isLoading = false;

            $(window).scroll(function(){
                if (!isLoading) {
                    var footerHight = $(document).height() - $(window).height() - $("#myFooter").height();
                    if($(window).scrollTop() > footerHight){

                        isLoading = true;
                        loadIndex = loadIndex + 1;

                        $(".loader").show();
                        $.ajax({
                            method: "GET",
                            url: '/load-news?startIndex=' + loadIndex,
                            success: function (result) {
                                console.log("More loaded");
                                setTimeout(function(){
                                    $(".loader").hide();
                                    onSuccess(result);
                                    isLoading = false;
                                }, 1000);

                            }
                        });
                    }
                }
            })
        }
    };

    var onSuccess = function(data) {
        console.log('SUCCESS');
        $(".news-list-wrapper").append(data);
    };

})(jQuery, Drupal, drupalSettings);

```

# Answer
> 3 votes
When using `Drupal.behaviors` you need to use `.once('behaviorName')`

```
$(window).scroll(function(){

```

needs to be:

```
$(window, context).once('news').scroll(function(){

```

---
Tags: javascript, ajax
---


# Question
Title: How do I display all terms of nodes created by user in a user view field
I have a User view where I list user information with contextual filter UID. I want to display all the terms from the nodes that the user added. I added the Author relationship so that way I can display the terms field to the view.

The issue is that the field only displays the terms of the first node added by the user. The aim is to display all the terms of all the nodes added by the user. Preferably with no repetition.

So if user U added node A with term X and Y and also added node B with term X and Z, the views filed should display term X, Y and Z.

What am I doing wrong that only the user's first node's terms display?

# Answer
> 3 votes
It's not likely you have it working the way you describe it, even for one node.

You need to first connect the users to the nodes, before you can make further connection to terms on those nodes.

The easiest to create such views is through Taxonomy term type, not User type, since it's the terms you want to list in the end:

1. Create Taxonomy term Views with 0 Pager (to show all items)
2. Under Fields add Taxonomy term: Name if you don't have it already
3. add Relationship **Content using field\_\[name\]**, require it
4. Add another Relationship **Content author**, require it (it will automatically use the first Relationship)
5. Add a Contextual filter **User ID**, it will automatically use the `author` Relationship, and configure it:
`When the filter value is NOT available`
**Provide default value**
**User ID from route context**
`When the filter value IS available or a default is provided`
**Specify validation criteria**
**User ID**
**Single ID**
**Hide view**
6. Turn **Aggregation** on.

To test the views enter a user ID into the Preview field, it should show a list of terms associated with the user's node's field you added the Relationship for.

Aggregation takes care that there are no duplicates in the results.

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


# Question
Title: Page template suggestion based on content types but not for node/edit or node/delete
I have a template for a page content type that works perfect. But when I try to edit or delete the node of that content type it blocks the standard template.

So `node/130/edit?` or `node/130/delete?` are not working because I don't get the right page.

I tried `strpos($_SERVER['REQUEST_URI'])` versions but it doesn't work or like the one below only gives me the "original" Drupal template when the path is `node/130/edit?` so the second variable gets through.

```
function mytheme_theme_suggestions_page_alter(array &$suggestions, array $variables) {
      // Add content type suggestions.
      if (($node = \Drupal::request()->attributes->get('node')) &&
      (strpos($_SERVER['REQUEST_URI'], "delete") || strpos($_SERVER['REQUEST_URI'], "edit") === false)
      ) {
        array_splice($suggestions, 1, 0, 'page__node__' . $node->getType());
      }
    }

```

The array\_splice hint comes from
https://www.drupal.org/forum/support/theme-development/2015-07-02/how-to-add-in-drupal-8-a-custom-suggestion-page-template#comment-10684366

Any help?

# Answer
> 1 votes
A slightly different approach: Add a custom theme suggestion for the canonical route of your node type(s).

This way, you neither have to meddle with path arguments whose position might change, e.g. when using subpath aliases in a later stage of your site's development cycle, nor have to extend your checks for additional routes added by third party modules, as e.g. `node/{nid}/translate`, `node/{nid}/revisions`, `node/{nid}/devel`, and so on.

I didn't test it though, but you could do something like this:

```
/**
 * Implements hook_theme_suggestions_HOOK_alter() for page.html.twig.
 */
function mytheme_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  if (
    $route_name = \Drupal::routeMatch()->getRouteName()
    && $route_name == 'entity.node.canonical'
    && $node = \Drupal::request()->attributes->get('node')
  ) {
    $suggestions[] = 'page__node__' . $node->getType() . '__canonical';
  }
}

```

Then you could rename your page template to `page--node--my-type--canonical.html.twig` and it should be picked up only for your node type `my_type` at its canonical (view) route.

# Answer
> 0 votes
You can work with path\_args instead of `$_SERVER['REQUEST_URI']`.
Something like:

```
function mythem_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  // Add content type suggestions.
  // Get current path.
  $current_path = \Drupal::service('path.current')->getPath();
  // explode args.
  $path_args = explode('/', $current_path);
  if (($node = \Drupal::request()->attributes->get('node')) && isset($path_args[3]) && ($path_args[3] == 'edit' || $path_args[3] == 'delete')) {
    array_splice($suggestions, 1, 0, 'page__node__' . $node->getType());
  }
}

```

For more infos about how to get url args take a look at https://www.drupal.org/node/2274705

---
Tags: 8, theming
---


title: How to get taxonomy term field values

text:
# Question
Title: How to get taxonomy term field values
I have created vocabulary "Hospital" and created text and image fields like:

* Hospital Image: (machine name: field\_hospital\_image) // image field
* Hospital Contact: (machine name: field\_hospital\_contact\_no\_) // text field

My code is:

```
$vid = 'hospitals';
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
foreach ($terms as $term) {
  $term_data[] = [
    'tid' => $term->tid,
    'tname' => $term->name,
    'image' => ...???..,    // image field
    'contact' => ...???..,  // text field
  ];
}

```

Please suggest namespace also.

I alsready tried :

```
'contact' => $term->get('field_hospital_contact_no_')->getValue(),

```

and

```
'contact' => $term->get('field_hospital_contact_no_')->value,

```

Errors:

> Error: Call to undefined method stdClass::get()

# Answer
Term object is not loaded with `loadTree` by default a basic php object is loaded instead.

You have to load the term object for each term using `$term_obj = Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($term->tid);`

Your code should look like this

```
$vid = 'hospital';
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
foreach ($terms as $term) {
  $term_obj = Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($term->tid);
  $url = "";
  if(isset($term_obj->get('field_hospital_image')->entity)){
    $url = file_create_url($term_obj->get('field_hospital_image')->entity->getFileUri());
  }

  $term_data[] = [
    'tid' => $term->tid,
    'tname' => $term->name,
    'contact' => $term_obj->get('field_hospital_contact_no_')->value,
    'image_url' => $url,
  ];
}

```

**NOTE:** Alternatively you can also use `loadTree($vid, 0, NULL, TRUE)` to load the entities directly on the `$terms` array but perhaps it should be avoided on very large vocabularies. More info on the loadTree method
> 10 votes

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


# Question
Title: User login through JSON request returning HTML instead of JSON
I am using Drupal 8.6.4

```
http://example.org/user/login?_format=json

```

When I try to submit a post request, it returns HTML page instead of JSON response.

I am sending headers:

```
  Content-Type: application/json

```

and data as:

```
 { "name": "admin" , "pass": "admin" }

```

What am I missing?

# Answer
It turned out that the Redirect after login module was redirecting to the given URL, which resulted in HTML being output. I have disabled that and now I am getting the proper JSON response.
> 2 votes

---
Tags: 8, authentication-authorization
---


# Question
Title: Can I post a job from freelance website into issue queue at drupal.org issue queue list?
I heard it's kind of illegal to post a paid job request in Drupal.org issue queue. Is it true?

I've emailed the maintainer, but they are busy to do a paid job.

# Answer
I assume that, since you are asking about posting a request for a paid job in a project issue queue, the paid job is relative to the project. For example, you are willing to pay for adding a feature to the project.

In that case, if the maintainer doesn't have the contact tab accessible to every user, or you don't have any other way to contact him privately, you could open a support request in the project issue queue asking for the availability to do paid jobs, without adding too much details. If the maintainer is available for a paid job, you will get a way to contact the maintainer and provide more details about the paid job you are asking for.

If the request for the paid job is not relative to a project, or the maintainer of the project already answered not to be available for any paid job, you can post on the Paid Drupal services forum. Before posting, please see READ THIS FIRST: Recommendations for hiring a Drupal site developer and \*** RULES FOR THIS FORUM \*** read this so your posts don't get deleted, which contain useful information on how to post a request for paid work.
> 0 votes

---
Tags: community-official-site
---


# Question
Title: Migrating files from local source are not found
I am migrating from Drupal 7 to Drupal 8 (8.6.9). Both the Drupal 7 and the Drupal 8 site currently run on my local machine. The migration of the public files goes well using:

```
source:
  plugin: d7_file
  scheme: public
  constants:
    source_base_path: 'http://www.oldsite.com/'
process:
  fid:
    -
      plugin: get
      source: fid
  filename:
    -
      plugin: get
      source: filename
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - filepath
    -
      plugin: urlencode
  uri:
    -
      plugin: file_copy
      source:
        - '@source_full_path'
        - uri
...
destination:
  plugin: 'entity:file'
migration_dependencies:
  required: {  }
  optional: {  }

```

The private files are not found using the site URL as `source_base_path` so I switched it to `/absolute/path/to/private`. However, the files are still not found.

When I check the migration messages it says `File '/absolute/path/to/private/filename.png' not found` for each private file. However, if I copy the path and search for the file in the terminal, it's there so the path is correct.

At first I thought it was due to spaces in the filename but it also happens with files without spaces. For completeness: there are no spaces in the path to the private directory.

Note: not all files are images, many are PDFs.

When searching for this problem I find configurations like above, so I'm out of options.

# Answer
Turns out the problem was not in the Drupal code but simply a path issue. I run the Drupal 8 site inside a DrupalVM server and the migration is done relative to THAT root. So `'/absolute/path/to/private/filename.png'` is not with respect to the root of my computer, but with respect to the root of the DrupalVM.

The problem is solved by adding an extra synced folder to the DrupalVM that points to the Drupal 7 root:

```
vagrant_synced_folders:
  - local_path: /path/to/drupal8/root
    destination: /var/www/drupalvm
    type: nfs
    create: true
  - local_path: /path/to/drupal7/root
    destination: /var/www/drupal7
    type: nfs
    create: true

```

Then restart the server:

```
vagrant halt
vagrant up

```

In the migration file the source path becomes:

```
constants:
    source_base_path: '/var/www/drupal7'

```

Now the files are found.
> 0 votes

---
Tags: 8, files, migrations
---


title: Page title from the exposed filter term

text:
# Question
Title: Page title from the exposed filter term
I have a view that shows all the contents of my site, with an exposed filter, that allows to filter these contents according to different taxonomy terms.

I would like the taxonomy term chosen via the exposed filter to appear as a page title.

Example:

1. I type in my search form: drupal,
2. I arrive on a page with the title "drupal" and presenting all the contents having for term "drupal".

I tried different options, especially with the contextual filter, but without success.

For example, i tried this solution (1) or this solution (2), but either I do not get any title (1), or I get many errors that make the site crash (2), of type

> Warning : Illegal string offset 'value' dans Drupal\views\Plugin\views\area\Text-\>preQuery() ((...)/core/modules/views/src/Plugin/views/area/Text.php ligne 50)

Help would be much appreciated

**Edit:**

My views configuration (maybe views can't find the id in the url? The url of my page: : mysite/myviews?tid=term+taxonomy+(ID) )

# Answer
To use term names in a Contextual filter in Content views you need to add the Relationship to the taxonomy reference field you have in your content. Then you'll be able to add Taxonomy term: Name Contextual filter that will take names as arguments, and not term ID numbers.

You will be able to override the title for the Name contextual the same way, only use the corresponding token for the taxonomy name. You can look it up under `Replacement patterns`.

You can find more details about how to set up the Name contextual here in a section of this answer: Create view with path relative to taxonomy term
> 0 votes

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


# Question
Title: How can I insert many field values under one term?
I'm working on a module, of which one function is grab list names and stock codes from a custom table and create corresponding terms. Now, my current code creates a new term and corresponding stock code, however this is not very efficient. How can I create one term for each unique list name and create corresponding many field values? Below is my current code:

```
function liste() {
    $src = ['Ý', 'Þ', 'ý', 'þ', 'ð'];
    $tar = ['İ', 'Ş', 'ı', 'ş', 'ğ'];
    $query = \Drupal::database()->select("excel","m")->fields("m",["stokkodu","grupadi"])->condition("grupadi", "","!=")->execute()->fetchAll();
    foreach ($query as $q) {
        $term = Term::create([
            'vid' => 'liste_adi',
            'name' => str_replace($src, $tar, $q->grupadi),
            'field_stok_kodu' => $q->stokkodu,
        ]);
        $term->enforceIsNew();
        $term->save();
    }
}

```

I thought about selecting only grupadi and grouping by it and inserting to a temporary table and then inserting corresponding stock codes in another column delimited with comma or something; but if there is another more efficient way, please let me know. EDIT: I'm looking to do something like the following:

Current:

```
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2299001      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2299002      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2299003      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2299004      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2299005      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303001      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303002      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303003      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303004      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303017      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303022      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2303046      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2601044      |
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2608020      |
+-------------------------------------------------------------------------------------+-----------------+

```

Desired:

```
| Manyetik Matkaplar?n Yedek Par�alar?                                                | YMD2299001,YMD2299002,YMD2299003

```

I hope you get the idea.

# Answer
I ended up doing the below. It might be overkill but does the job.

```
function liste() {
    $src = ['Ý', 'Þ', 'ý', 'þ', 'ð'];
    $tar = ['İ', 'Ş', 'ı', 'ş', 'ğ'];
    $grupadi = \Drupal::database()->select("excel","e")->fields("e",["grupadi"])->condition("grupadi", "","!=")->groupBy("grupadi")->execute()->fetchAll();
    foreach ($grupadi as $g) {
        $term = Term::create([
            'vid' => 'liste_adi',
            'name' => str_replace($src, $tar, $g->grupadi),
        ]);
        $term->enforceIsNew();
        $term->save();
    }
    $terms = \Drupal::entityTypeManager()->getStorage("taxonomy_term")->loadTree("liste_adi");
    foreach($terms as $term) {
        $stokkodu = \Drupal::database()->select("excel", "e")->fields("e", ["stokkodu"])->condition("grupadi", $term->name)->execute()->fetchAll();
        foreach($stokkodu as $s) {
            $t = Term::load($term->tid);
            $t->field_stok_kodu[] = $s->stokkodu;
            $t->save();
        }
    }
}

```
> 0 votes

# Answer
You needn't have to do aggregation via temporary tables, it can be done in your query via a `GROUP_CONCAT` expression & `GROUP` clause:

```
$query = \Drupal::database()->select("excel","m")->fields("m",["stokkodu","grupadi"])->condition("grupadi", "","!=");
$query->addExpression('GROUP_CONCAT(m.stokkodu)', 'stokkodus');
$query->groupBy('m.grupadi');
$results = $query->execute()->fetchAll();
foreach ($results as $result) {
  $result->stokkodus contains a comma-delimited list of values that you can split with explode()
  $stokkodus = explode(',');
  // @TODO: add transform logic
}

```

In the example above, you can transform the exploded array then create an array of values for your multivalue `field_stok_kodu` field:

```
  // @TODO: add transform logic
  'field_stok_kodu' => [
    ['value' => $stokkodus[0]],
    ['value' => $stokkodus[1]]
  ];

```
> 0 votes

---
Tags: 8, database
---


title: Any callback method for migration

text:
# Question
Title: Any callback method for migration
I have written a migration script that is working but After migrate data I need a method/way to store recent inserted id with some other relevant data in another custom database table.

Can I do with help of any hook or use any plugin. This is my yml file.

```
id: order_billing_address
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags: null
migration_group: default
label: 'User profile for billing information'
source:
  plugin: csv
  path: pathtocsv/order_billing_address.csv
  header_row_count: 1
  keys:
    - profile_id
process:
  type:
    plugin: default_value
    default_value: 'customer'
  uid: uid
  profile_id: profile_id
  address/country_code: country
  address/administrative_area: state
  address/locality: locality
  address/dependent_locality: locality
  address/postal_code: postal_code
  address/sorting_code: ''
  address/address_line1: street
  address/address_line2: street2
  address/organization: company_name
  address/given_name: first_name
  address/family_name: last_name
destination:
  plugin: 'entity:profile'
migration_dependencies: {  }

```

# Answer
In order to do this, I will create a custom module, an event, dispatch it in a hook\_ENTITY\_TYPE\_insert implementation and subscribe to it so that we can insert the data into different custom table.

https://x-team.com/blog/creating-and-subscribing-to-events/
> 0 votes

---
Tags: migrations
---


# Question
Title: How can I remove the checkbox from tableselect form header only?
How can I remove the checkbox from tableselect form header (Drupal 7) only? I am looking for any configuration if available that can be applied in the below sample code:

```
$form['listings'] = array(
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $options,
    '#empty' => t('No Listing available.'),
);

```

# Answer
The checkbox on the header is the *Check all* one. As the documentation about the tableselect form element says, just set the *#js\_select* property to `FALSE`. In your case, the code would become the following one.

```
$form['listings'] = array(
  '#type' => 'tableselect',
  '#js_select' => FALSE,
  '#header' => $header,
  '#options' => $options,
  '#empty' => t('No Listing available.'),
);

```

See also the code of `theme_tableselect()`, the theme function responsible of rendering *tableselect* elements.

```
// Add an empty header or a "Select all" checkbox to provide room for the
// checkboxes/radios in the first table column.
if ($element['#js_select']) {

  // Add a "Select all" checkbox.
  drupal_add_js('misc/tableselect.js');
  array_unshift($header, array(
    'class' => array(
      'select-all',
    ),
  ));
}
else {

  // Add an empty header when radio buttons are displayed or a "Select all"
  // checkbox is not desired.
  array_unshift($header, '');
}

```
> 2 votes

# Answer
Better to use drupal table theme instead of tableselect.

```
  $header = array('Cell 1', 'Cell 2');
  $data = array(
            array('A', 'B'),
            array('C', 'D')
  );
  $output = theme('table',
           array('header' => $header,
                  'rows' => $data ));
  return $output;

```

https://alvinalexander.com/drupal/drupal-theme-table-example-theme\_table-function
> 0 votes

---
Tags: forms
---


# Question
Title: How do I add an autocomplete to a form element that is not an entity reference?
I need to add a auto complete text field in my custom form module. The auto complete values should be retrieved from the database table. Can anybody tell me how to do that?

# Answer
> 1 votes
To add an autocomplete to a form element that is not an entity reference element, you need to use two properties:

* *#autocomplete\_route\_name*, the name of the route returning the autocomplete array as JSON
* (optional) *#autocomplete\_route\_parameters*, an array of parameters to pass to the autocomplete route, in the format `[<parameter> => <value>]`

For example, the autocomplete controller could be implemented from a class similar to the following one.

```
/**
 * Defines a route controller for autocomplete form elements.
 */
class AutocompleteController extends ControllerBase {

  /**
   * Handler for the autocomplete request.
   */
  public function autocomplete(Request $request) {
    $results = [];

    // Get the typed string from the URL, if it exists.
    if ($input = $request->query->get('q')) {
      $typed_string = Tags::explode($input);
      $typed_string = Unicode::strtolower(array_pop($typed_string));

      // Use $typed_string to load data from the database.

      $results[] = [
        'value' => $value,
        'label' => $label,
      ];
    }

    return new JsonResponse($results);
  }

}

```

Notice that:

* The value entered in the form element is available in `$request->query->get('q')`
* The autocomplete returns an array containing entries with *value* (the value to use) and *label* (the value to show), converted in JSON

---
Tags: 8, forms
---