# Question
Title: How to alter view query after exposed filter is changed?
We have a custom view, `myview`, that has two exposed filters: `country` and `category`. For the `country` value we have a value that we want to be applied regardless of what is selected as the exposed filter that is not `All Countries`.

How would we alter the query after a value is selected so that we always append an `or country = United States of America` to whatever value is selected for the view's query?

**Goal:**

After the exposed filter has been applied, alter the query such that it will return whatever the user selected AND all other nodes where `country = 'United States'`.

Country value:

1. All Countries
2. Worldwide
3. United States of America
4. United Kingdom
5. France
6. Germany

What we were thinking of using hook\_views\_query\_alter, but not sure how we can alter the query after a value has been selected.

**mymodule.module**

```
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implements hook_views_query_alter().
 */
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {

  if ($view->id() == 'myview') {
    $or_statement = new Condition('OR');
    $or_statement->condition('field_country', '12', '=');
    $query->addWhere(0, $or_statement);
  }

}

```

Current filters:

1. published = yes
2. content type = article
3. country (exposed filter, display all, single select)
4. category (exposed filter, display all, single select)

When using `ksm()` to print the `$condition_group`, this is the results. It is not even showing the two exposed filters.

**Current Where Clause**

`10` is the value selected by the user from the exposed filter and `12` is the one we want to add.

```
WHERE (((node__field_country.field_country_target_id = '10')) AND (node__field_country.field_country_target_id = '12'))

```

**Desired where clause**

```
WHERE (((node__field_country.field_country_target_id = '10')) OR (node__field_country.field_country_target_id = '12'))

```

# Answer
Using d70rr3s suggestion and this patch (required), I came across this solution that worked.

```
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implements hook_views_query_alter().
 */
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
   if ($view->id() == 'myview'  && !empty($view->exposed_raw_input['field_country']) && $view->exposed_raw_input['field_country'] !== 'all') {
    // Traverse through the 'where' part of the query.
    foreach ($query->where as &$condition_group) {
      foreach ($condition_group['conditions'] as &$condition) {
        if ($condition['field'] == 'your_entity.field_country') {
          $field = 'node__field_country.field_country_target_id';
          $value = 'somevalue';
          $operator = '=';
          $query->addWhere(2, $field, $value, $operator);
        }
      }
    }
  }
}

```

Results:

```
WHERE (((node__field_country.field_country_target_id = '10')) OR (node__field_country.field_country_target_id = 'someValue')) AND (node_field_data.status=1) AND (node_field_data.type='article')

```

Filter Criteria where #1 and #2 from screenshot had to be applied:
> 4 votes

# Answer
Taken from the hook example. Assuming your filter name is *field-country* a possible solution could be:

```
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
 * Implements hook_views_query_alter().
 */
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
   if ($view->id() == 'myview'  && !empty($view->exposed_raw_input['field_country']) && $view->exposed_raw_input['field_country'] != 'all') {
    // Traverse through the 'where' part of the query.
    foreach ($query->where as &$condition_group) {
      foreach ($condition_group['conditions'] as &$condition) {
        if ($condition['field'] == 'your_entity.field_country') {
           $filter_value = $view->exposed_raw_input['field_country'];
           if (!is_array($filter_value)) {
             $filter_value = [$filter_value];
           }

           $condition = [
             'field' => 'your_entity.field_country',
             'value' => array_merge($filter_value, ['United States Of America']),
             'operator' => 'IN',
           ];
        }
      }
    }
  }
}

```

I haven't fully test it but should work.

Also you can always implement your own ad-hoc filter plugin.

**Update**: Add a condition to check if the filter is multivalue.

**Update**: Remove strict comparison for filter input value as it may cause side-effects.
> 2 votes

---
Tags: views, 8, hooks
---


# Question
Title: How do I translate hard coded words in twig file
Is there a way to translate hard coded words in twig when selecting a language from the language dropdown? I have used the `|t` `({{ myword|t }})` function but it doesn't seem to be work when selecting another language.

Is there a way to do this?

# Answer
> 2 votes
`{{ myword }}` is a variable, not a string. You need to use `{{ 'myword'|t }}` (with quotes)

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


# Question
Title: Features 8.x-3.7 not writable on Window's Ubuntu
8x-3.7 features, most stable version, but I am having trouble writing to custom module on the UI. My structure is as follow:

```
 -modules/
    contrib/
       features/
    custom/
       news_blogs/
          config/
             install/
                [code]

```

when i edit my view, i go to `/admin/config/development/features` I see that the feature state is edit. I click the checkbox and click `write`.

I get error: `Package News/Blogs not written to modules/custom/news_blogs. Error: Failed to create directory /mnt/c/mywebsite/modules/custom/news_blogs/config/install..` and then inside `install` code is deleted and empty.

I check my logs: `Warning: chmod(): Operation not permitted in Drupal\Core\File\FileSystem->mkdir() (line 226 of /mnt/c/mywebsite/core/lib/Drupal/Core/File/FileSystem.php) #0...`

I checked my permissons and it is 777 and my usr is the owner for the directory. I am unsure what else to check or test to figure out what can be going wrong. Any help is thanked!

# Answer
It looks like you are using something like a virtual machine (Vagrant?) with a shared windows file system. The problem is that Windows permissions don't map well to Linux ones. That is why the chmod error is happening.

You may need to get your webserver running under the same user you share the file system under, e.g. the vagrant user.

Personally, I have never gotten a stable way to have Features write to a windows share. There always seemed to be a gotcha in the ones that worked. I've just excepted that I had to download the feature archive, unpack it, and copy it to the site on the Windows side.

But your situation may be different.
> 1 votes

---
Tags: features, files
---


title: How do I display taxonomy child terms?

text:
# Question
Title: How do I display taxonomy child terms?
I used the *Taxonomy View Depth* module to create a taxonomy vocabulary like this.

### Animal

* Cats
    + Brown
    + white
* Dogs
    + Brown
    + White

What I did was enabling the default taxonomy view, and changing the depth in *Content: Has taxonomy term ID* (with depth) to 1 instead of 0 (also tried 2,3, etc.)

The children items will never show on the page. It does remove the **There is currently no content classified with this term.** from the page.

**What I want?** With Taxonomy menu I want to be able to click Cats and show the second level children.

# Answer
I used View tree Module to achieve this same kind of functionality but i used it for Node Reference. As per their module page, this module is also compatible for taxonomy.

**Here are the steps to set Views Tree to display hierarchical taxonomy.**

Create a new term view using the fields row style

1. add relationship for taxonomy term: parent term
2. add field term id (do not use relationship) and exclude it from display
3. add field term id with relationship, exclude from display
4. add any fields you want to display, like term name, term description, etc...
5. Change style plugin to Tree (Adjacency model)
6. Set Main field to Term ID
7. Set Parent field to Term ID with parent relationship
> 1 votes

# Answer
If using Drupal 7, views I has changed a lot from the year the question was asked.

In the view,

**Filter criteria:** Add

`Content: Has taxonomy terms (with depth) (exposed)` **exposed** is used when you are using `BEF settings` and want the **visitor** be able to modify the exposed filter.

Select the taxonomy **vocabulary:** like `Animal` from question.

Important step **Selection type:** `Dropdown` if autocomplete is selected show hierarchy wont show as a option. Drop down gives a option to choose the checkbox for `show hierarchy`

**Depth:** This option depends on the maximum child items you want to choose for a term as asked in question `cats` and `dogs` has child terms with depth `1`, means if you want to see the content tagged to `brown` when you select `cats` term `depth: 1` is prefered. If the child terms also have child terms then we need to increase the depth. For example if

`Animals
-cats
--brown
---lightbrown
--black`

As Child term `brown` has `lightbrown` as child term, and if you prefer to show the content tagged to `lightbrown` if `cats` were selected then `depth: 2` is recommended.
> 0 votes

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


# Question
Title: Adding a class to the <li> tag of a menu
I need to put a class/ID on the actual li element as each link in the menu has a color-coded background when active meaning, I can't just style ".active-trail" as that will be the same color for every link.

Creating a menu and using the CSS ID or class puts the ID/class on the a element, not on the `<li>` tag.

I could write something in jQuery, but I thought there might be a way in Drupal.

The output I want would be like the following.

```
<li class="leaf myCustomClass active-trail"><a href="/trash-this" class="active" title="">Test links</a></li>
<li class="leaf myCustomClass"><a href="http://#" class="specialMenuItem first" title="">first</a></li>
<li class="leaf myCustomClass"><a href="http://#" class="specialMenuItem" title="">second</a></li>

```

# Answer
> 0 votes
You can use menu attribute module which provide functionality to set id or class for the menu item.

> This simple module allows you to specify some additional attributes for menu items such as id, name, class, style, and rel.

# Answer
> 1 votes
You need to use theme\_menu\_item\_link()

The following is an example that I pulled from an old site:

```
function THEME_menu_item_link($link)
{
    if (empty($link['localized_options']))
    {
        $link['localized_options'] = array();
    }

    //Give this menu item a unique id
    $link['localized_options']['attributes']['id'] = 'menu-item-' . $link['mlid'];

    //Not sure if this is the cleanest method, but it should allow us to follow
    //the active-trail across menu items, based on path.

    //Get the start of the current path (e.g. admin/build/modules would be admin)
    $base_path = preg_replace('/^([A-Za-z0-9_-]+)\/(.*)/', '${1}', drupal_get_path_alias($_GET['q']));

    //Get the current link we're looking at
    $this_link = drupal_get_path_alias($link['href']);

    //If the
   if($base_path == $this_link)
   {
       $link['localized_options']['attributes']['id'] = 'menu-active-trail-' . $link['mlid'];
   }

   return l($link['title'], $link['href'], $link['localized_options']);
}

```

# Answer
> 0 votes
You can add the below code to your template.php. Reference article: http://scriptcult.com/subcategory\_197/article\_978-add-class-to-menu-item.htm

```
/**
 * Theme a menu link.
 */
function THEMENAME_menu_link(array $variables) {
  // Add class for li.
  $variables['element']['#attributes']['class'][] = 'menu-' . $variables['element']['#original_link']['mlid'];
  // Add class for a.
  $variables['element']['#localized_options']['attributes']['class'][] = 'menu-' . $variables['element']['#original_link']['mlid'];
  return theme_menu_link($variables);
}

```

# Answer
> 0 votes
For Drupal 8 you can use the menu\_link\_attributes module.

---
Tags: 6, routes
---


title: Table doesn't render on ajax command

text:
# Question
Title: Table doesn't render on ajax command
I have a function that returns a render array for a table;

```
  private function _files_table($job_id){
    $files = $this->_query("
      select *
      from JC_Documents_Recent_Revisions
      where Job_ID=".$this->sqs($job_id).";
    ");

    $rows = array_map(function($row){
      return [
        (string)$row['Job_ID'],
        $row['Document_Name'],
        $row['Document_Type'],
        $row['File_Name'],
        ($row['Uploaded_Date'] != NULL ? $row['Uploaded_Date']->format("Y-m-d H:i") : 'Unknown Date'),
        $row['Uploaded_By'],
        new FormattableMarkup('<a href=":link">show</a>', [':link' => (Url::fromRoute('JobFileUpload.Serve', ['file_id' => (int)$row['FileID']]))->toString()]),
        new FormattableMarkup('<a href=":link">revise</a>', [':link' => (Url::fromRoute('JobFileUpload.Revise', ['file_id' => (int)$row['FileID']]))->toString()]),
        new FormattableMarkup('<a href=":link">delete</a>', [':link' => (Url::fromRoute('JobFileUpload.Delete', ['document_id' => (int)$row['DocumentID']]))->toString()])
      ];
    }, $files);

    $header = [
      t('Job ID'),
      t('Document Name'),
      t('Document Type'),
      t('File Name'),
      t('Uploaded Date'),
      t('Uploaded By'),
      t('Download'),
      t('Revise'),
      t('Delete')
    ];

    return [
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $rows
    ];
  }

```

and two occasions where I wish to render the table. The first is in `buildForm`:

```
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $job_id=NULL) {
    $jobs = $this->_query("
      select *
      from Active_Job_List;
    ");

    $formatted_jobs = [];
    $len = count($jobs);
    for($i=0; $i<$len; $i++){
      $formatted_jobs[$jobs[$i]['Job_ID']] = $jobs[$i]['Job_Name'];
    }
    natsort($formatted_jobs);

    $form['job_id'] = [
      '#weight' => 1,
      '#title' => t('Job'),
      '#type' => 'select',
      '#options' => $formatted_jobs,
      '#ajax' => [
        'callback' => '::showFiles',
        'wrapper' => 'ajax-wrapper'
      ],
      '#required' => TRUE,
      '#default_value' => $job_id
    ];

    $form['jobfiles'] = $this->_files_table($job_id);
    $form['jobfiles']['#weight'] = 2;

    if($job_id != null){
      $form['newfile'] =  [
        '#weight' => 3,
        '#title' => t('Upload new file'),
        '#type' => 'link',
        '#url' => Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id])
      ];
    }

    return $form;
  }

```

The second is in showFiles:

```
  public function showFiles(array &$form, FormStateInterface $form_state) {
    $job_id = $form_state->getValue('job_id');

    $output = $this->_files_table((int)$job_id);
    // $output['link'] = new FormattableMarkup('<a href=":link">Upload a new file...</a>', [':link' => (Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]))->toString()]);

    $renderer = \Drupal::service('renderer');

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#ajax-wrapper', $renderer->render($output)));

    return $response;
  }

```

The buildForm method works just fine, and I get a table with the files in it. But when I call the same render array function on an output for the AjaxResponse (in `::showFiles`), I don't even get an error, and the table does not show up. Anyone got an idea of what I'm doing wrong here?

# Answer
I think the problem was not specifying an id attribute for my table when I first render it, so there was nothing to replace.

This seems to work:

```
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $job_id=NULL) {
    $jobs = $this->_query("
      select *
      from Active_Job_List;
    ");

    $formatted_jobs = [];
    $len = count($jobs);
    for($i=0; $i<$len; $i++){
      $formatted_jobs[$jobs[$i]['Job_ID']] = $jobs[$i]['Job_Name'];
    }
    natsort($formatted_jobs);

    $form['job_id'] = [
      '#weight' => 1,
      '#title' => t('Job'),
      '#type' => 'select',
      '#options' => $formatted_jobs,
      '#ajax' => [
        'callback' => '::showFiles',
        'wrapper' => 'ajax-wrapper'
      ],
      '#required' => TRUE,
      '#default_value' => $job_id
    ];

    $form['jobfiles'] = $this->_files_table($job_id);
    $form['jobfiles']['#weight'] = 2;

    if($job_id != null){
      $form['newfile'] =  [
        '#weight' => 3,
        '#title' => t('Upload new file'),
        '#type' => 'link',
        '#url' => Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]),
        '#attributes' => [
          'id' => ['new-file']
        ]
      ];
    }

    return $form;
  }

  public function showFiles(array &$form, FormStateInterface $form_state) {
    $job_id = $form_state->getValue('job_id');
    // $form_state->setRedirectUrl(Url::fromRoute('JobFileUpload.OverviewWithJobId', ['job_id' => $job_id]));

    $table = $this->_files_table((int)$job_id);
    $link = [
      '#type' => 'markup',
      '#markup' => new FormattableMarkup('<a href=":link">Upload a new file...</a>', [':link' => (Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]))->toString()
      ])
    ];
    $renderer = \Drupal::service('renderer');

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#ajax-wrapper', $renderer->render($table)));
    $response->addCommand(new HtmlCommand('#new-file', $renderer->render($link)));

    return $response;
  }

```
> 0 votes

---
Tags: theming, forms, ajax
---


# Question
Title: What can I use as default value for a datetime form element?
I need to create a custom contact form in Drupal 8. I wrote all the code to build the form. I just need to set the default value for a *datetime* form element.

The code I am using to add that form element is the following one.

```
$form['start_date'] = [
  '#type' => 'datetime',
  '#title' => t('Start date'),
  '#default_value' => time(),
];

```

The value I am using for the default value doesn't show the expected value. What should I use instead of `time()`?

# Answer
use Drupal\Core\Datetime\DrupalDateTime;

and in form

```
$form['start_date'] = array(
  '#type' => 'datetime',
  '#title' => t('Start Date'),
  '#default_value' => DrupalDateTime::createFromTimestamp(time()),
);

```
> 26 votes

# Answer
The `#default_value` datetime field element expects a `DrupalDateTime` object, not a date string.

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

$form['start_date'] = [
       '#type' => 'datetime',
       '#title' => t('Start Date'),
       '#description' => date($date_format, time()),
       '#default_value' => new DrupalDateTime('1978-11-01 10:30:00', 'Europe/Berlin'),
     ];

```

For more information see `Datetime::processDatetime()` & `Datetime` in the API docs.
> 5 votes

# Answer
Also using Drupal 8. This discussion raises an important point - ensure that your date format matches.

I wanted to display the date as d/m/Y but that is not the default format used by the date field:

```
$today = date("Y-m-d");
$form['general']['endDate'] = ['#type' => 'date','#date_format' => 'd/m/Y','#title' => t('End date'),'#default_value' => $today,];

```

The clue was in the generated HTML:

```
data-drupal-date-format="Y-m-d"

```

The discussion states that the default could be changed but I did not validate that proposition.
> 2 votes

# Answer
For Drupal 8, the following piece of code works:

// Form element inside buildForm().

```
$form['start_date'] = [
      '#type' => 'datetime',
      '#title' => t('Start Date'),
      '#default_value' => DrupalDateTime::createFromTimestamp(strtotime($config->get('start_date')))
    ];

```

// Inside submitForm().

```
->set('start_date', (string) $form_state->getValue('start_date'))

```
> 0 votes

---
Tags: 8, forms, datetime
---


# Question
Title: "Filename cannot be empty in file_unmanaged_save_data()"
We're using Drupal 7.20 and this error message started appearing after trying to add a new context. I removed the context condition, and even restored `drush arr` from a dump from Friday. All files belong to apache (`chown -R apache:apache`) and group/owner can do everything (`chmod -R 775 * #temporarily`).

The message still persists.

> Warning: file\_put\_contents(): Filename cannot be empty in file\_unmanaged\_save\_data() (line 1903 of /var/www/html/includes/file.inc).
> The file could not be created.
> Warning: file\_put\_contents(): Filename cannot be empty in file\_unmanaged\_save\_data() (line 1903 of /var/www/html/includes/file.inc).
> The file could not be created.
> Warning: file\_put\_contents(): Filename cannot be empty in file\_unmanaged\_save\_data() (line 1903 of /var/www/html/includes/file.inc).
> The file could not be created.
> Warning: file\_put\_contents(): Filename cannot be empty in file\_unmanaged\_save\_data() (line 1903 of /var/www/html/includes/file.inc).
> The file could not be created.
> Warning: file\_put\_contents(): Filename cannot be empty in file\_unmanaged\_save\_data() (line 1903 of /var/www/html/includes/file.inc).
> The file could not be created.
> Warning: file\_put\_contents(): Filename cannot be empty in file\_unmanaged\_save\_data() (line 1903 of /var/www/html/includes/file.inc).
> The file could not be created.

# Answer
> 1 votes
Oy! My temp folder had bad permissions.

Of course I only thought of this after I restored a back up from last Friday -- thus, overwriting all the work from this morning and Friday evening. Arg. Okay, Thanks for letting me vent here.

# Answer
> 1 votes
Same symptom (error message), but it was due to exceeded disk quota.

---
Tags: files
---


title: Event is not responding properly

text:
# Question
Title: Event is not responding properly
I created 2 rules with the same action, which sends Drupal logs to the site. One is *Content is created* with the *After saving new content (rules\_entity\_insert:node)* event; the other one is *Content is updated* with the *After updating content (rules\_entity\_update:node)* event. Also, they use the same *Condition: Node is of type* condition.

I am using a REST request to create/edit a node. However, when I do a POST, I am getting 2 logs in the site, which means that both rules are being triggered. PATCHing a node is working fine: A single log is created.

Am I missing something?

I am using the Rules module 8.x-3.0-alpha3. The action is programatically created.

# Answer
Problem solved by https://www.drupal.org/project/rules/issues/2990211#comment-12716081

> I have another rule that modify the title of my node with event **After updating content (rules\_entity\_update:node)**. But since that rule is necessary, then it should not be deleted but still I dont want to get a duplicate result when a node is created. So what I did, is I change the other rule that modifies the title into event **Before saving content (rules\_entity\_presave:node)** so it wont be called on node creation, and this works!
> 0 votes

---
Tags: 8, rules
---


title: How to use GreatSchools API module?

text:
# Question
Title: How to use GreatSchools API module?
I enabled the GreatSchools module and entered the API KEY from greatschools in the configuration but there is no documentation on how to see the schools as content.

Can you point me to the right direction?

# Answer
This is an Drupal API module making it easier to use The GreatSchools API / get data from GreatSchools. You have to write your own module (or enable the PHP module and write PHP directly in your nodes - not recommended) to use the functionality provided by the module. Currently it provides the following functions:

* great\_schools\_nearby\_schools
* great\_schools\_browse\_schools
* great\_schools\_browse\_districts
* great\_schools\_city\_overview
* great\_schools\_nearby\_cities
* great\_schools\_school\_census\_data
* great\_schools\_school\_profile
* great\_schools\_school\_search
* great\_schools\_school\_test\_scores
* great\_schools\_school\_reviews

Good luck!

PS! I have never used this module myself.
> 0 votes

---
Tags: 7
---


# Question
Title: Max File Upload Size set to big, but Ajax Error with old file size
I have changed the upload\_max\_filesize and the max body size in my `php.ini` to 15 MB. It used to be 2 MB. Drupal displays the max file size correctly, but when I try to upload files bigger than 2 MB - the old limit - I get an Ajax Error, telling me the entity is too large. Any idea where this comes from?

# Answer
Just for documentation I'd like to add my findings here. I had this issue in Drupal 8, but I guess the Drupal version can be neglected to answer this question.

---

### Suhosin

As @Clive already mentioned it in the comments to the question it's definitely worth a look under `/admin/reports/status/php` if the Suhosin PHP extension is enabled.

In https://www.drupal.org/node/725056 people suggest to disable this extension completely, but it's maybe better as @Clive suggested to simply override one of its parameters by editing your `php.ini`. Or by setting this in `settings.php` – if that is possible at all – via `ini_set('suhosin.post.max_value_length', '-1');` or something like that. Maybe it's a different parameter you have to override.

---

### Or Apache

If there's no Suhosin extension enabled, you may find this forum post valuable: https://www.drupal.org/forum/support/post-installation/2015-04-07/ajax-error-when-uploading-large-files where it's suggested to disable or reconfigure Apache's `mod_security` security mod.

---

### Or JS

Last but not least you could simply try to circumvent Ajax completely by unbinding the event handler for the submit button, or by removing it completely.

**Drupal 7**

```
// Disable ajax upload for file field
drupal_add_js("jQuery(function() { jQuery('#edit-field-image :submit').unbind(); });", 'inline');

```

Source: How do I disable ajax on file fields?

**Drupal 8**

```
(function ($, Drupal) {
  Drupal.behaviors.autokill = {
    attach: function (context, settings) {
      // $('.form-managed-file > input.form-submit').remove();
      $submit_button = $('.form-managed-file > input.form-submit');
      $submit_button.unbind();
      $submit_button.removeClass('js-hide');
    }
  };
})(jQuery, Drupal);

```
> 1 votes

---
Tags: ajax, files
---


# Question
Title: How do I get the current language in custom user edit Twig file?
I have a custom user profile edit twig file.How can i check current language code in user twig file in drupal8?

# Answer
> 0 votes
You can check language in twig as below:

```
{% if (language.getId() == 'en') %}
    Do something
{% endif %}

```

---
Tags: 8, users
---


# Question
Title: Drupal8 Oaut2 add a grant type “password” to client
I work on **Drupal8** project and created **Rest API**, everything works fine until I want to add **Oauth2** when I try to get a token I got an invalid grant type error.

This is the error code:

```
{
    "error": "invalid_grant",
    "message": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.",
    "hint": "Check the configuration to see if the grant is enabled."
}

```

This is the url that i called:

http://myserver/oauth/token?grant\_type=password&client\_id=6db9da8d-b831-4381-b279-381bc5a57e90&scope&username=webmasterrest&password=webmasterrest&client\_secret=$S$EamACyfemGWic74kmkwUvphMmr9FL132KC297mI1GEkTKhyBJyAo

I added a client, but I can't add a grant type "password" to this client, any help please?

# Answer
## To add Oauth 2 authentification

Install the module using Composer: composer config repositories.drupal composer https://packages.drupal.org/8 && composer require drupal/simple\_oauth:^2. You can use any other installation method, as long as you install the OAuth2 Server composer package.

Generate a pair of keys to encrypt the tokens. And store them outside of your document root for security reasons.

```
openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout > public.key

```

Save the path to your keys in: /admin/config/people/simple\_oauth.

Go to REST UI and enable the oauth2 authentication in your resource.

Create a Client Application by going to: /admin/config/services/consumer/add.

Create a token with your credentials by making a POST request to /oauth/token. See the documentation about what fields your request should contain

(Not shown) Permissions are set to only allow to view nodes via REST with the authenticated user.

Request a node via REST without authentication and watch it fail.

Request a node via REST with the header Authorization: Bearer {YOUR\_TOKEN} and watch it succeed.

# From this

---

*NOTE: I user drupal/simple\_oauth version 2.x because i got an exception n version 3.x*
> -1 votes

---
Tags: users, authentication-authorization
---


title: Remove "index.php" from upgraded paths

text:
# Question
Title: Remove "index.php" from upgraded paths
I've managed to upgrade a D7 site to D8 on localhost but I don't seem to be able to get rid of a superfluous 'index.php/' string appearing in all paths, both old and newly generated, eg:

* /localhost/drupal/index.php/admin
* /localhost/drupal/index.php/node/201

Thanks for any suggestions!

Here's the `.htaccess` file:

```
#
# Apache/PHP/Drupal settings:
#

# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
  </IfModule>
</FilesMatch>

# Don't show directory listings for URLs which map to a directory.
Options -Indexes

# Set the default handler.
DirectoryIndex index.php index.html index.htm

# Add correct encoding for SVGZ.
AddType image/svg+xml svg svgz
AddEncoding gzip svgz

# Most of the following PHP settings cannot be changed at runtime. See
# sites/default/default.settings.php and
# Drupal\Core\DrupalKernel::bootEnvironment() for settings that can be
# changed at runtime.

# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
  php_value assert.active                   0
  php_flag session.auto_start               off
  php_value mbstring.http_input             pass
  php_value mbstring.http_output            pass
  php_flag mbstring.encoding_translation    off
  # PHP 5.6 has deprecated $HTTP_RAW_POST_DATA and produces warnings if this is
  # not set.
  php_value always_populate_raw_post_data   -1
</IfModule>

# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
  # Enable expirations.
  ExpiresActive On

  # Cache all files for 2 weeks after access (A).
  ExpiresDefault A1209600

  <FilesMatch \.php$>
    # Do not allow PHP scripts to be cached unless they explicitly send cache
    # headers themselves. Otherwise all scripts would have to overwrite the
    # headers set by mod_expires if they want another caching behavior. This may
    # fail if an error occurs early in the bootstrap process, and it may cause
    # problems if a non-Drupal PHP file is installed in a subdirectory.
    ExpiresActive Off
  </FilesMatch>
</IfModule>

# Set a fallback resource if mod_rewrite is not enabled. This allows Drupal to
# work without clean URLs. This requires Apache version >= 2.2.16. If Drupal is
# not accessed by the top level URL (i.e.: http://example.com/drupal/ instead of
# http://example.com/), the path to index.php will need to be adjusted.
<IfModule !mod_rewrite.c>
  FallbackResource /index.php
</IfModule>

# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on

  # Set "protossl" to "s" if we were accessed via https://.  This is used later
  # if you enable "www." stripping or enforcement, in order to ensure that
  # you don't bounce between http and https.
  RewriteRule ^ - [E=protossl]
  RewriteCond %{HTTPS} on
  RewriteRule ^ - [E=protossl:s]

  # Make sure Authorization HTTP header is available to PHP
  # even when running as CGI or FastCGI.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # Block access to "hidden" directories whose names begin with a period. This
  # includes directories used by version control systems such as Subversion or
  # Git to store control files. Files whose names begin with a period, as well
  # as the control files used by CVS, are protected by the FilesMatch directive
  # above.
  #
  # NOTE: This only works when mod_rewrite is loaded. Without mod_rewrite, it is
  # not possible to block access to entire directories from .htaccess because
  # <DirectoryMatch> is not allowed here.
  #
  # If you do not have mod_rewrite installed, you should remove these
  # directories from your webroot or otherwise protect them from being
  # downloaded.
  RewriteRule "(^|/)\.(?!well-known)" - [F]

  # If your site can be accessed both with and without the 'www.' prefix, you
  # can use one of the following settings to redirect users to your preferred
  # URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
  #
  # To redirect all users to access the site WITH the 'www.' prefix,
  # (http://example.com/foo will be redirected to http://www.example.com/foo)
  # uncomment the following:
  # RewriteCond %{HTTP_HOST} .
  # RewriteCond %{HTTP_HOST} !^www\. [NC]
  # RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  #
  # To redirect all users to access the site WITHOUT the 'www.' prefix,
  # (http://www.example.com/foo will be redirected to http://example.com/foo)
  # uncomment the following:
  # RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  # RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]

  # Modify the RewriteBase if you are using Drupal in a subdirectory or in a
  # VirtualDocumentRoot and the rewrite rules are not working properly.
  # For example if your site is at http://example.com/drupal uncomment and
  # modify the following line:
   RewriteBase /drupal
  #
  # If your site is running in a VirtualDocumentRoot at http://example.com/,
  # uncomment the following line:
   RewriteBase /

  # Redirect common PHP files to their new locations.
  RewriteCond %{REQUEST_URI} ^(.*)?/(install.php) [OR]
  RewriteCond %{REQUEST_URI} ^(.*)?/(rebuild.php)
  RewriteCond %{REQUEST_URI} !core
  RewriteRule ^ %1/core/%2 [L,QSA,R=301]

  # Rewrite install.php during installation to see if mod_rewrite is working
  RewriteRule ^core/install.php core/install.php?rewrite=ok [QSA,L]

  # Pass all requests not referring directly to files in the filesystem to
  # index.php.
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.php [L]

  # For security reasons, deny access to other PHP files on public sites.
  # Note: The following URI conditions are not anchored at the start (^),
  # because Drupal may be located in a subdirectory. To further improve
  # security, you can replace '!/' with '!^/'.
  # Allow access to PHP files in /core (like authorize.php or install.php):
  RewriteCond %{REQUEST_URI} !/core/[^/]*\.php$
  # Allow access to test-specific PHP files:
  RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?.php
  # Allow access to Statistics module's custom front controller.
  # Copy and adapt this rule to directly execute PHP files in contributed or
  # custom modules or to run another PHP application in the same directory.
  RewriteCond %{REQUEST_URI} !/core/modules/statistics/statistics.php$
  # Deny access to any other PHP files that do not match the rules above.
  # Specifically, disallow autoload.php from being served directly.
  RewriteRule "^(.+/.*|autoload)\.php($|/)" - [F]

  # Rules to correctly serve gzip compressed CSS and JS files.
  # Requires both mod_rewrite and mod_headers to be enabled.
  <IfModule mod_headers.c>
    # Serve gzip compressed CSS files if they exist and the client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.css $1\.css\.gz [QSA]

    # Serve gzip compressed JS files if they exist and the client accepts gzip.
    RewriteCond %{HTTP:Accept-encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.*)\.js $1\.js\.gz [QSA]

    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
    RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]

    <FilesMatch "(\.js\.gz|\.css\.gz)$">
      # Serve correct encoding type.
      Header set Content-Encoding gzip
      # Force proxies to cache gzipped & non-gzipped css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
  </IfModule>
</IfModule>

# Various header fixes.
<IfModule mod_headers.c>
  # Disable content sniffing, since it's an attack vector.
  Header always set X-Content-Type-Options nosniff
  # Disable Proxy header, since it's an attack vector.
  RequestHeader unset Proxy
</IfModule>

```

# Answer
This works for me:

No edit .htaccess ! Need only apache2.conf

```
<Directory "/var/www">
 AllowOverride None
</Directory>

```

to

```
<Directory "/var/www">
 AllowOverride All
</Directory>

```

and all of sites works as we expect.
> 1 votes

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


title: Different node form id for add/edit

text:
# Question
Title: Different node form id for add/edit
I recently found that unlike Drupal 7, D8 has a different form id for addition and edit of nodes. Is there a specific reason for that? Because this makes the `hook_form_FORM_ID_alter()` less granular as we now have to alter like `mymodule_form_node_form_alter()` and put the specific node type in there.

Sorry, could not find a discussion on this. Must be something very basic that I missed.

Thanks

# Answer
> 7 votes
I'd rather say, added granularity is exactly what has been achieved by introducing entity form ID's specific to their entity type, bundle and operation.

You can now target the form for a specific entity type and bundle with a specific operation when using hook\_form\_FORM\_ID\_alter(). Before this you had to check the bundle yourself and also figure out whether the node already had an ID or not.

The form ID will be composed of entity type identifier, bundle, operation and the `_form` suffix. (Compare EntityForm::getFormID().)

If you require a more generic form alter for ALL node forms, you can use hook\_form\_BASE\_FORM\_ID\_alter() which will be invoked with the base form ID that is `ENTITYTYPE_form` for entities, so `node_form` for content entities.

The invocation order along with a description of all three hooks is actually well documented in the description of hook\_form\_alter().

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


title: One product in multiple categories

text:
# Question
Title: One product in multiple categories
using drupal7 commerce and trying to figure out how to have a product assigned to multiple categories(old ubercart user here). The only way I have found so far is to create a new product view for each category(seems kind of cumbersome).

# Answer
> 1 votes
There is no enforcement in Drupal Commerce of any product catalog data model. The solution will depend on how you've configured your taxonomy vocabularies, really. If you have a single catalog vocabulary, simply add a multi-value taxonomy term reference field to the node type you're using to display products. This will let you assign as many categories as you want per product page.

When it comes to actually creating a View of the products, it isn't clear what you're attempting or why. A single View should be able to filter a group of nodes to any selection of or combination of taxonomy terms. You may need to export the View or paste a screenshot of your configuration to this question to get more specific help.

---
Tags: commerce, taxonomy-terms
---


title: Clone Commerce Product Option Sets

text:
# Question
Title: Clone Commerce Product Option Sets
This issue hints it's possible to clone Option sets https://www.drupal.org/project/commerce\_option/issues/1319618

> To reproduce:
>
> On page admin/commerce/products/option-sets Click 'clone' on any product option set. New option set appears as \[original option set name\] (cloned) Selecting 'Manage Fields' shows no fields and selecting 'Manage Display' shows no fields added.

But there is no Clone button anywhere to be found under `admin/commerce/products/option-sets` following that instruction.

Does it require any additional module?

# Answer
> 1 votes
Commerce Product Option is an unsupported module. You should not be using it. If you want similar functionality with core support (e.g. options on an Add to Cart form that aren't required to correspond to unique SKUs), use custom line item types with line item fields instead.

---
Tags: 7, entities, commerce
---


# Question
Title: How do I check if a user may access a given route?
I am trying to render a link from a `Url` object and verify the user actually has access to that URL, like when viewing a node.

For some reason, this always returns `FALSE`, although the node is accessible when `$language` is the set language.

```
$_url = Url::fromRoute('<current>', [], ['language' => $language]);
if ($_url->access()) {
  // The code inside here is never executed.
}

```

How do I verify a user may access the given path, without actually loading the entity behind that path?

---

edit: current state:

```
$currentPath = \Drupal::service('path.current')->getPath();
$urlObject = Url::fromUserInput($currentPath);
$routeName = $urlObject->getRouteName();

$linkUrl = Url::fromRoute($routeName, [], ['language' => $dataLangId]);

debug($languageData['languageName']);
debug($linkUrl->toString());

if ($linkUrl->access()) {
  debug('access');
}
else {
  debug('denied');

}

```

results in:

> Some mandatory parameters are missing ("node") to generate a URL for route "entity.node.canonical

# Answer
I don't know why

```
$_url = Url::fromRoute('', [], ['language' => $language]);

```

Doesn't work with route name `<current>` but it works with other route names. For example with route with name `some_module.some_route_name` the following will work.

```

  $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $_url = Url::fromRoute('some_module.some_route_name', [], ['language' => $language]);
  $userCurrent = \Drupal::currentUser();
  if ($_url->access($userCurrent)) {
    //- Do Stuff
  }

```

In your case for the current route. Try this out.

```
use Drupal\Core\Url;

  $request = \Drupal::request();
  $_url = Url::createFromRequest($request);
  $userCurrent = \Drupal::currentUser();
   if ($_url->access($userCurrent)) {
     //- Do Stuff
  }

```
> 5 votes

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


# Question
Title: Check if a node field has changed upon save
I am parsing pdf's in a field for a custom content type in a cron job. I have a boolean on each node that determines whether their pdf has already been parsed. I grab the ones I need like so:

```
$query = \Drupal::entityQuery('node')
    ->condition('status',1)
    ->condition('type', 'issue')
    ->exists('field_pdf')
    ->condition('field_indexed',false)
    ->sort('created','ASC');
if($range > 0){
    $query->range(0,$range);
}

$issue_nids = $query->execute();
$issue_nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($issue_nids);

foreach ($issue_nodes as $issue_node){
    //do my pdf parsing magic on field_pdf
    $node->field_indexed->value = true;
    $node->save();
}

```

This works fine but if the user replaces field\_pdf and uploads a new one I want to make field\_indexed false again so I know to reindex it. The problem is I don't really have a way of knowing whether the field changed.

I considered using a presave hook but I didn't see a way to compare the form state to what was currently on the node.

Is there a way I can detect when a field has changed when a node has saved?

# Answer
> 7 votes
Clive is correct. $node-\>original does give access to the original node values. I was able to accomplish what I needed like so

```
function my_module_node_presave($node) {
    $type = $node->getType();
    if($type == 'issue'){
            if(isset($node->field_pdf->entity) && !isset($node->original->field_pdf->entity) || empty($node->original->field_pdf->entity) || $node->field_pdf->entity->id() != $node->original->field_pdf->entity->id()){
                $node->field_indexed->value = false;
            } else {
                $node->field_indexed->value = true;
            }
    }

```

---
Tags: 8, nodes
---


# Question
Title: Gray overlay and no dialog when clicking Image button in CKEditor
Attempting to get CKEditor and Media to work together on a Drupal7 site. Things are mostly working great, but when I click the regular Image button (or double-click an image, or use the context menu to access image properties), I get only a gray overlay and no dialog window.

I'm using CKEditor 7.x-1.18 with the 4.10.0 FULL library locally installed (in libraries), as well as CKFinder 3.4.4 (also in libraries), all with Media 7.x-2.19 and the Media CKEditor 7.x-2.5 bridge module.

When I click the Image button, I get this error in console:

```
TypeError: Drupal.settings.picture is undefined[Learn More] plugin.js:152:15
init/<
http://example.com/sites/all/modules/picture/ckeditor/plugins/plugin.js:152:15
n
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:10:222
CKEDITOR.event.prototype</<.fire</<
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:12:42
CKEDITOR.dialog
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:594:500
openDialog
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:642:134
openDialog/<
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:642:492
e
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:258:175
y
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:258:332
v
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:258:412
A/e.$.onload/<
http://example.com/sites/all/libraries/ckeditor/ckeditor.js:259:327

```

I'm not Drupal-technical enough to understand this error entirely. But my intuition is that I don't have something configured correctly. (Installation instructions I have found are so ancient, I'm not even sure the module supports this version of CKEditor.)

# Answer
After discovering that the Image button works fine in the default "Advanced" text format, which I did not modify, and which doesn't have the Media button added, I started investigating differences.

Turns out that if I disable the Picture module in Editor Appearance \> Plugins, things work.

I just don't know what I'm giving up by disabling this. I would like images to be responsive. :-(
> 0 votes

---
Tags: wysiwyg, media
---


title: How to check if the page is front page?

text:
# Question
Title: How to check if the page is front page?
The following method not returning any value (true or false). `\Drupal::service('path.matcher')->isFrontPage();`

How to check if the page is front or not?

# Answer
> 25 votes
This is indeed a way to check if it is the front page and should return a value if you check the method code.

I am using it in a few preprocess hooks:

```
$variables['is_front'] = \Drupal::service('path.matcher')->isFrontPage();

```

# Answer
> 11 votes
* Twig : You can use `{% if is_front %}`. here is an example page.html.twig
* PHP: `\Drupal::service('path.matcher')->isFrontPage();`

---
Tags: 8
---


title: Show blocks at a specific URL

text:
# Question
Title: Show blocks at a specific URL
I'm trying to move some Blocks to a different Page. None of the Blocks are defined in a region. They are specified to display on every Page.

In reality, they show up on only one Page. I tried deleting that Page, and when I navigate to the URL of that page, the Blocks still show up, along with the message that this page does not exist. I made a new Page, and I can't figure out how to get those Blocks to display on the new Page. I've been looking into this for weeks, and I just can't figure it out.

Any suggestions in this matter?

# Answer
Well, I figured it out. There is a module called Context installed on the website, and, as I originally suspected, this module looks at the path and modifies (or "reacts") to the path when the user navigates to it.

I also had problems adding and modifying blocks to the regions available in the Context editor. You have to select the item on the right side first, and then click on the +Add button on the left side in the region you want to add the block to.

After so many weeks, this is such a relief to be able to find out. I sincerely hope that I do not have such issues again. Thank you again, so much, for your help in all of this. I know it doesn't seem like you helped much, but I think by just talking it out a little bit more, I was able to pinpoint the issue.
> 0 votes

# Answer
If you are in **Drupal 7** you will need to check the block visibility settings for that block

1. `structure > block`
2. in the list find the block in question and click configure
3. change the visibility settings

On a default installation there are visility settings per URL / per content type / per role / per user but many more can be added by contributed modules.

On **Drupal 8** something similar can be found on `structure > block layout`
> 0 votes

---
Tags: 7, blocks
---


# Question
Title: How to add specific field to article node twig template?
I want to customize the article type node pages. I created a twig file :

```
node--article--full.html.twig

```

What code should I put in this file to display the "Description" field ?

```
/admin/structure/types/manage/article/fields

```

# Answer
> 1 votes
Rendered output of this field

```
{{ content.field_article_description }}

```

# Answer
> 1 votes
Also note that if you need to exclude a specific field from the general content area even if it is set to display (which is what you have to do to get it into the render array) then this works:

```
   {#We hide the comments and links now so that we can render them later.#}
  <div{{ content_attributes }}>
    {{ content|without('comment', 'links', 'field_tags', 'field_machinename') }}
  </div>

```

and then where you need it to appear:

```
      {{ content.field_machinename }}

```

# Answer
> 0 votes
GiorgosK's answer should work, unless you have a layout set in the Manage Display tab, in which case you may need to use something like {{ content.\_field\_layout.content.field\_article\_description }}

---
Tags: 8, theming, nodes, entities
---


# Question
Title: Parameter upcasting in Forms: buildForm works, submitForm doesn't
Route:

```
mymodule.applications.payment_form:
  path: '/payment/{submission}'
  defaults:
    _form: '\Drupal\mymodule\Form\PaymentForm'
    _title: 'Pay Fee'
  requirements:
    _role: 'applicant'
  options:
    parameters:
      submission:
        type: entity:webform_submission

```

This works:

```
public function buildForm( array $form, FormStateInterface $form_state, WebformSubmission $submission = NULL) {
    $submission_data = $submission->getData();

```

This doesn't (null):

```
public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmission $submission = NULL) {
    $submission_data = $submission->getData();

```

Is it intentional that upcasting is only available to buildForm?
Is there a workaround?

(My logic being: the form, when submitted, still POSTs to /payment/123, so it's still convenient to load the object.)

# Answer
Yes, this is intentational. submit and validate callbacks aren't tied to the request, they only receive exactly those two arguments.

As mentioned in the comments, you can store the information either on the object, with $form\_state-\>get()/set() or a form elemnt of #type value, doesn't make a big difference which you chose.

You could also store only the ID instead of the whole object but actually, I believe it is stored anyway in form\_state somewhere when you pass it as an argument to the form (pretty well hidden though, so better to store & access it in a more explicit place)
> 1 votes

---
Tags: 8, forms, routes
---


# Question
Title: In views formatted as table, columns with taxonomy term fields are sorted according to term ID, not label
In Drupal 8 I have View formatted as table, where user can click to any column header to sort displayed records according to the given field. This works well for numbers (ascending/descending), as well as for plain text (ascending/descending for title or any other text values), records are then sorted correctly alphabetically. But this does not work for taxonomy terms - they are sorted according to taxonomy term ID and not alphabetically according to label.

I.e. I wish to display in the table column with a taxonomy term (only one value is allowed per node) and be able to sort the table alphabetically.

In my use case I have records about plant specimens containing plenty of fields, including e.g. species or life form. These are taxonomy terms. I'm displaying the specimen records in table filterable according to various criteria, e.g. various traits. The table is also sortable according to any column, e.g. species, but in this particular case, it is sorted according to taxonomy term ID and not naturally by label.

I found several answers to similar problems, but nothing exactly fitting my problem. Views Natural Sort module might also help, but its development status is not very promising.

# Answer
That's because the stored value of the field is the term ID, the label of it is just how it is displayed.

To sort on the name, you need to instead add a relationship using that field to terms, and then add the name field of that relationship. Then you should be able to sort it as well based on that.
> 3 votes

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


# Question
Title: How to load library only on one twig template?
We have a custom theme, `mytheme` where we have the following library for the `header-fix`. I have also added `{{ attach_library('mytheme/header-fix') }}` to only one twig template `block--myblock.html.twig` that is for my custom block `myblock`.

The goal is to only add the library to `myblock` when `myblock` is rendered on the page.

The problem we are having is that the library is being added to all pages even ones where the block is not present (loaded on the page). How can we load a single library only on one block and not all the twig templates?

**myblock configuration:**

1. restricted to only `Article` content type (so do not load on `basic` content type)

**block--myblock.html.twig**

```
{{ attach_library('mytheme/header-fix') }}
<div>
  <p>Continually fashion turnkey sources without web-enabled alignments. Some more content.</p>
</div>

```

**mytheme.libraries.yml**

```
...
header-fix:
  version: 1.x
  js:
    /path/to/header-fix.js: { preproces: false, attributes: { defer: true } }
...

```

**mytheme.info.yml**

```
...
libraries:
  - mytheme/header-fix
...

```

# Answer
> 3 votes
Just remove the reference from mytheme.info.yml.

That's adding it any time the theme is loaded (every page), whereas `attach_library` will add it only when that specific template is used.

You'll need to rebuild cache for the change to take effect.

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


# Question
Title: Cannot log in to drupal admin in a new installation (access denied)
I've just made a Drupal 7 installation on localhost with XAMPP. I created an SQL database and did the installation without any error.

However, when I try to login on Drupal admin from `localhost/mytest?q=user`, I get an error like `"Access denied. You are not authorized to access this page"`.

I tried to change the password on PhpMyAdmin manually, but I still have this error. I don't have any other drupal installation on my laptop.

These are the latest lines on logs.txt in logs file:

```
[Thu Mar 05 17:43:11.022491 2015] [mpm_prefork:notice] [pid 4801] AH00169: caught SIGTERM, shutting down
[Thu Mar 05 17:43:15.000852 2015] [ssl:warn] [pid 5867] AH01906: www.example.com:443:0 server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)
[Thu Mar 05 17:43:15.001021 2015] [ssl:warn] [pid 5867] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Thu Mar 05 17:43:15.001398 2015] [suexec:notice] [pid 5867] AH01232: suEXEC mechanism enabled (wrapper: /opt/lampp/bin/suexec)
[Thu Mar 05 17:43:15.052113 2015] [auth_digest:notice] [pid 5868] AH01757: generating secret for digest authentication ...
[Thu Mar 05 17:43:16.002626 2015] [ssl:warn] [pid 5868] AH01906: www.example.com:443:0 server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)
[Thu Mar 05 17:43:16.002750 2015] [ssl:warn] [pid 5868] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Thu Mar 05 17:43:16.003085 2015] [lbmethod_heartbeat:notice] [pid 5868] AH02282: No slotmem from mod_heartmonitor
[Thu Mar 05 17:43:16.015087 2015] [mpm_prefork:notice] [pid 5868] AH00163: Apache/2.4.10 (Unix) OpenSSL/1.0.1j PHP/5.6.3 mod_perl/2.0.8-dev Perl/v5.16.3 configured -- resuming normal operations
[Thu Mar 05 17:43:16.015126 2015] [core:notice] [pid 5868] AH00094: Command line: '/opt/lampp/bin/httpd -E /opt/lampp/logs/error_log -D SSL -D PHP'
sh: 1: -t: not found

```

# Answer
> 1 votes
It may also be a cookie problem. To check if that is what causing it, just try to use another web browser to verify if you get the same problem.

**If** using that other browser the problem disappaears, **then** DELETE the cookie in the browser where you experience this problem and try again. Pretty sure your issue will be solved then.

Curious to hear if this helps (sometimes it does ...).

# Answer
> 1 votes
I think the issue can be:

1. You are not an Administrator of the site. - Check for the Username with Administrator as the role. Then use `drush upwd username --password="any_password"` from the terminal. And the try logging in with this user name.
2. Some caching issue - Try clearing the caching from the terminal using `drush cc all`.
3. Try clearing all the cookies thats there for your site.

# Answer
> 1 votes
I had similar issue.

I tried everything possible to resolve issue

* checked rewrite enabled
* AllowOverride All
* cookie domain in settings.php
* clear browser cache
* Truncate Drupal cache\*, sessions tables
* used drush uli user to auto login
* Changed Drupal Password using drush

Additional Details :

* Fresh install without any changes.
* Site was loading without any issue.
* For incorrect password, Drupal was showing correct message.
* For Correct username and password no message other than access denied screen.

Problem was related to cookies Then i started search cookies setting in apache conf files.

*This was the one setting causing issue for Drupal login, after removing 'Secure' word, i am able to login to Drupal.(Restart apache)*

Security: cookies

> Header edit Set-Cookie ^(.\*)$ $1;HttpOnly;Secure

TO

> Header edit Set-Cookie ^(.\*)$ $1;HttpOnly

Look at the Response headers of your site, and check 'secure' is present, it may cause php session issue (on non https)

> Set-Cookie: secure; httponly

* Note : i was using subdomain without https, it was our additional setting for all our server /etc/httpd/conf.d/additional\_settings.conf
* OS : Amazon OS (EC2), Apache : Apache/2.4.33, PHP : 5.6.36

# Answer
> 0 votes
Are you sure the site is not installed in a subfolder mytest? Then the login would be localhost/mytest/?q=user (noticed the extra / after mytest)

# Answer
> 0 votes
Check if you have .htaccess file in web-root folder ('/opt/lampp/htdocs/mytest')

Check it your site is in correct folder. 1. Open "/opt/lampp/htdocs/mytest" and create file 'info.php' with content:

```
<?php echo phpinfo(); ?>

```

2. Open it in browser: http://localhost/mytest/info.php

Expected result: you should see all php settings. If you don't see them: check path to site's folder.

Enable showing all errors in browser using this doc: https://www.drupal.org/node/1056468

If problem still not solved please provide more information.

# Answer
> 0 votes
Apache module mod\_rewrite must be on. Otherwise login form wont work...

# Answer
> 0 votes
clear your browser cache and then try again with right login credentials.

---
Tags: users, installation
---


title: Access denied for the user #1

text:
# Question
Title: Access denied for the user #1
I'm getting a 403 error everytime I try to log in with the user #1.

What can I do to get access again?

I have already tried to:

* clear all cashes (via Drush)
* set the time in both the server and Drupal's timezone, to be sure it isn't a cookie expiration problem

# Answer
> 7 votes
The problem began after I uncommented and defined a wrong `$cookie_domain`, in settings.php. (I needed this set up for FCKeditor/CKFinder.) Once I have corrected this, I've managed to log in again.

# Answer
> 2 votes
Check that cookie domain, and site URL are the same, in the settings.php file.

Look for these lines:

```
$base_url = 'http://yourdomain.com';
$cookie_domain = 'yourdomain.com'

```

within the `settings.php` file.

Usually at: yourdomain.com/sites/default/settings.php

Remember to delete cookies from your browser and empty your browser cache before you try again.

# Answer
> 1 votes
Ok, you've solved your problem. I'm just trying to explain "how".

When you was logging in (with uid 1 or any user), the cookie was set on the wrong domain, but Drupal didn't know it. It thought you was logged in and redirect you to user/1. In this second request, browser sent an empty cookie and Drupal saw you as anonymous, which probably didn't have `access user profiles` permission and you got a 403.

# Answer
> 1 votes
This might be useful for you, if its not related to Drupal domain\_cookies setting. https://drupal.stackexchange.com/a/266928/39462

---
Tags: 7, users
---


title: How to delete block on hook_uninstall?

text:
# Question
Title: How to delete block on hook_uninstall?
I have a custom module, mymodule, that will create custom blocks, `block_test` and `block_test2` on `mymodule_install()`.

When the module is uninstalled, I want to remove any blocks created by `mymodule`. How would I delete the block generated by a module being uninstalled?

drush command (local dev):

```
drush pmu mymodule -yv

```

**mymodule.uninstall()**

```
function mymodule_uninstall() {
  // Delete Blocks generated by module.

  /** @var \Drupal\Core\Entity\EntityStorageInterface $block_storage */
  $block_storage = \Drupal::service('entity_type.manager')->getStorage('block');
  /** @var \Drupal\block\Entity\Block[] $blocks */
  $blocks = $block_storage->loadMultiple();
  foreach ($blocks as $block) {
    // I am stuck here.
  }
}

```

# Answer
Yes, then the best thing would be to follow the enforced config dependencies part above, if you create the content blocks with a fixed uuid then you can just put the block config entities in your config/install folder, with the config dependencies as explained there and it should be uninstalled automatically.

At least the config entities, if you want to delete the block\_content entities too then load them by UUID with `$block_content = \Drupal::service('entity.repository')->loadEntityByUuid('block_content', 'YOUR_UUID'); $block_content->delete()`
> 2 votes

---
Tags: 8, blocks, hooks
---


title: Bulk user creation

text:
# Question
Title: Bulk user creation
We manually create users via the Acquia Cloud Sites Factory. I want to create a script that bulk creates users at one time using a .csv file with just username, email, and password.

I know I can use a command like `drush ucrt username —password password1 —mail test@example.com`, but I need to create multiple users at the same time.

How can I achieve this?

# Answer
1. Use a shell-script to stick the `drush ucrt`-command in a loop reading from the `.csv`-file.
2. If you're on Drupal 7, use contributed module **User Import**.
> 1 votes

# Answer
If you working with drupal 7 you can use User Import module. Import users into Drupal, or update existing users, with data from a CSV file (comma separated file). Provides a wide range of features out of the box, and a comprehensive API to customise imports.

**Features**

Create an account for each user

Update existing users option (data can be added or replaced)

**Upload Options**

Upload CSV files through browser

Use file uploaded through SFTP, FTP,...

Drop an import file into a directory to trigger an automatic import
> 0 votes

---
Tags: users, drush
---


# Question
Title: Webform tokens - token to return the 'option value' not 'option text'
I am trying to pass the value of fields from one wizard page to another page . I can use the \[Webform\_submission:values:element\_key\] to pass most values. However on the select list I want the 'option value' not the 'option text'. Example using the twig Example: '#options': 10: Ten 20: Twenty 30: Thirty 40: Forty 50: Fifty

**if the second item is selected I want the value "20" not "Twenty"**

Is there a token that will give me the other value?

# Answer
You need to suffix your token with `:raw`.

@see https://www.drupal.org/project/webform/issues/2990260
> 1 votes

---
Tags: webforms
---


title: webform 5 access other webform tokens

text:
# Question
Title: webform 5 access other webform tokens
Is there a way to access tokens of another webform ? I have users of one role who need to evaluate in a webform files uploaded by users with another webform

# Answer
This is not supported and could be a security issue because it would allow people to use tokens to pry into information available in other entities.
> 0 votes

---
Tags: webforms, tokens
---


# Question
Title: Autoload next page while scrolling to the bottom
I am looking for a way to automatically load the next article once a reader has scrolled to the bottom of the page. Something similar to what this wordpress plugin is doing. So I understand that the functionality need to do three things:

1. Detect that the user has scrolled to the bottom of the page, and then load the next page underneath it, without breaking the theme's structure.
2. When the user has scrolled on to the next article, the URL and title on the browser should change to reflect that the user is now reading a new article.
3. The new page view should be trackable by google analytics. This should also create a separate history entry on the user's browser. Any social media share after the scroll should reflect the second article and not the first.

I understand there may be a way to achieve this using views infinite scroll. But that won't be able to achieve conditions two and three.

# Answer
> 0 votes
After a lit bit more looking around, I found that this functionality can be achieved by the Infinite Scroll js plugin. There is no out of box integration with Drupal yet, however, it shouldn't be too hard to build one. This plugin takes care of conditions 2 and 3 mentioned in the question quite nicely. It has the added advantage over the "views infinite scroll module" in that the content can be rendered without using views, and hence is a more flexible option.

---
Tags: 8, theming, nodes, javascript
---


# Question
Title: Multilingual Paragraphs fields are not present in node content
Following these Instructions I set up a paragraph field in custom node type. The field is called `field_content_sections` and it holds the paragraph elements. Next to it I created another field, the plain old list field called `field_content_rating_level`.

But when i create a node of that type with filled out parapgraph elements, the paragraph field doesn't appear in the nodes content, but the plain old list field does:

What I've done wrong?

I tried it with Drupal 8.5.6 and 8.6.0 and the most recent versions of the paragraphs module itself.

# Answer
> 0 votes
Turned out, that there was a conflict with the `field_layout` module. Just uninstalled it and voilá!

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


# Question
Title: How to get drupal to remove /drupal/ from all the links on the website
I first ran the install.php when drupal was reachable as example.org/drupal/, then later I changed the Apache configuration to make it into a virtual host. Now that I can reach the site at example.org, the problem is, all links available on that page still have /drupal/ in them, and result in 404.

I have tried uncommenting "RewriteBase /" in the .htaccess file, and restarting Apache. Nothing changed. There is nothing of use in the settings.php file for the site.

There are a lot of web pages that seem to solve this, but they are either for older versions of Drupal or just don't work.

I can force the correct URL's down Drupal's throat with an additional rule in the Apache configuration to rewrite the URL without the /drupal/ link, but come on, there must be a less hackish way to fix this.

Also of note, I'm trying this out on Arch Linux, so some file paths might be different. But this is a configuration issue, not a file path issue.

EDIT: for clarity, what I want is all links to show as example.org/blah *without* the /drupal/ being automatically inserted.

# Answer
The entry in the `.htaccess` file you should uncomment is the `/drupal` one:

```
  # Modify the RewriteBase if you are using Drupal in a subdirectory or in a
  # VirtualDocumentRoot and the rewrite rules are not working properly.
  # For example if your site is at http://example.com/drupal uncomment and
  # modify the following line:
  RewriteBase /drupal

```
> 3 votes

---
Tags: uri
---


# Question
Title: Image upload in content type, no previous image is present
Oddly worded title, I know. I'm not sure how to phrase it or what to ask exactly.

In previous versions of Drupal if I added an image field to a content type, once an image was uploaded it was saved in a library of images and it was available without being uploaded again.

Currently in Drupal 8.5.4 that's no longer the case.

I'm given the option to either upload or embed but not to select from an already existing list of uploaded images.

This is more of a nuisance since I have to reupload images even if I want to use them on a separate content type.

I'm not sure if this is a bug or it has completely changed in this version.

Drupal 8 bug tracker doesn't offer anything relevant.

Any help is appreciated.

# Answer
A little more configuration is necessary to add the feature of browsing existing media, you can do it with Entity browser and Core Media module in Drupal 8.5 and upwards.

Here's a great tutorial on how to do that, you need the **Part 4: How to Browse Media Assets**: Managing Media Assets using Core Media in Drupal 8
> 0 votes

---
Tags: 8
---


title: Help with database query

text:
# Question
Title: Help with database query
**How can I convert this sql query into a Drupal 8 query?**

I need all nodes of type 'page' that has not been referenced by nodes of type 'article'. Article content type contains an entity reference field, from where nodes of type 'page' can be referenced.

```
SELECT *
FROM node_field_data
WHERE type = 'page' AND
node_field_data.nid NOT IN (
   SELECT 1
   FROM node_field_data
   LEFT JOIN node__field_ref
   ON node_field_data.nid = node__field_ref.entity_id
   WHERE type = 'article'
);

```

I tried with this approach, but it doesn't work:

```
$sub_result = $this->database->query("
   SELECT 1 FROM {node_field_data} n
   LEFT JOIN {node__field_ref} r
   ON n.nid = r.entity_id
   WHERE n.type = :type",
   ['type' => 'article']
);

$result = $this->database->query("
   SELECT * FROM {node_field_data} n
   WHERE n.type = :type AND n.nid NOT IN :query", [
      'type' => 'page',
      'query' => $sub_result
   ]
);

```

I get this error:

```
The website encountered an unexpected error. Please try again later.
Recoverable fatal error: Object of class Drupal\Core\Database\Statement could not be converted to string in Drupal\Core\Database\Statement->execute() (line 59 of core/lib/Drupal/Core/Database/Statement.php).
Drupal\Core\Database\Statement->execute(Array, Array) (Line: 625)
Drupal\Core\Database\Connection->query('
      SELECT * FROM {node_field_data} n
      WHERE n.type = :type AND n.nid NOT IN :sub_result', Array, Array) (Line: 87)
Drupal\Core\Database\Driver\mysql\Connection->query('
      SELECT * FROM {node_field_data} n
      WHERE n.type = :type AND n.nid NOT IN :sub_result', Array) (Line: 141)
...
...
...

```

# Answer
Try this out. `get_all_nodes_not_referenced_by_article('page');`

```

use Drupal\Core\Database\Database;
/**
 * @param $type
 *
 * @return mixed
 */
function get_all_nodes_not_referenced_by_article($type){

  $connection = Database::getConnection();

  //- Step one get all referenced nids
  $query = $connection->select('node_field_data', 'nfd')
                      ->condition('nfd.type', 'article')
                      ->fields('nfd', ['nid']);
  $query->leftJoin('node__field_ref', 'nfr', 'nfd.nid = nfr.entity_id');
  $result = $query->execute()->fetchAll(PDO::FETCH_ASSOC);

  $referenced_nids = [];
  foreach ($result as $key => $value) {
    $referenced_nids[] = $value['nid'];
  }

  /**
   * Check if $referenced_nids to avoid
   * Drupal\Core\Database\InvalidQueryException: Query condition 'nfd.nid NOT IN ()' cannot be empty.
   * */
  if (!empty($referenced_nids)) {
    return $connection->select('node_field_data', 'nfd')
                      ->condition('nfd.type', $type)
                      ->condition('nfd.nid', $referenced_nids, 'NOT IN')
                      ->fields('nfd', ['nid', 'title'])
                      ->execute()
                      ->fetchAll(PDO::FETCH_ASSOC);
  }
  else {
    return $connection->select('node_field_data', 'nfd')
                      ->condition('nfd.type', $type)
                      ->fields('nfd', ['nid', 'title'])
                      ->execute()
                      ->fetchAll(PDO::FETCH_ASSOC);
  }
}
?>

```
> 2 votes

# Answer
Thank you so much for your help, berramou.

I just needed to modify it a little bit to make it work:

```
$query = $this->database->select('node_field_data', 'nfd')
  ->condition('nfd.type', 'article')
  ->fields('nfd', ['nid']);
$query->leftJoin('node__field_ref', 'nfr', 'nfd.nid = nfr.entity_id');
$query->fields('nfr', ['field_ref_target_id'])
  ->isNotNull('nfr.entity_id')
  ->condition('nfr.bundle', 'article');
$result = $query->execute()->fetchAll(PDO::FETCH_ASSOC);

$referenced_nids = [];
foreach ($result as $key => $value) {
  $referenced_nids[] = $value['field_ref_target_id'];
}

if (!empty($referenced_nids)) {
  return $this->database->select('node_field_data', 'nfd')
    ->condition('nfd.type', 'page')
    ->condition('nfd.nid', $referenced_nids, 'NOT IN')
    ->fields('nfd', ['nid', 'title'])
    ->execute()
    ->fetchAll(PDO::FETCH_ASSOC);
}
else {
  return $this->database->select('node_field_data', 'nfd')
    ->condition('nfd.type', 'page')
    ->fields('nfd', ['nid', 'title'])
    ->execute()
    ->fetchAll(PDO::FETCH_ASSOC);
}

```

I needed to check against field field\_ref\_target\_id (the page nid) and also field entity\_id shouldn't be null - otherwise I got all nodes of type page, instead of only nodes that havn't been referenced.

I appreciate you help.
> 0 votes

---
Tags: 8, database
---


# Question
Title: Return a 404 when a view pane in a page manager page has no result?
When you have a view page that takes a contextual filter, you can easily set the no result behavior to a 404. But I am trying to do this when I have a view pane, in a page manager page like in the screenshot attached

If the view has no result (contextual fitter does not validate) I would like the page to return a 404.

# Answer
You can implement hook\_views\_pre\_render in your module to do this task

```
/**
 * Implements hook_views_pre_render().
 */
 function mymodule_views_pre_render(&$view) {
   if ($view->name == 'myview' && $view->current_display == 'mypane') {
     if (empty($view->result)) {
       drupal_not_found();
     }
  }
}

```
> 2 votes

# Answer
@Andrew's answer adopted to Drupal 8:

```
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Implements hook_views_pre_render().
 */
function mymodule_views_pre_render(&$view) {
    if (
            array_key_exists('title', $view->build_info)
            && $view->build_info['title'] == 'My View'
            && $view->current_display == 'mypane'
    ) {
        if (empty($view->result)) {
            throw new NotFoundHttpException();
        }
    }
}

```
> 0 votes

---
Tags: views, panels
---


title: Layouts versus theme templates

text:
# Question
Title: Layouts versus theme templates
When I add a layout to my theme using *.layouts.yml, it will show up in the display settings for various entities (for example, paragraphs and blocks).<br>I can then set the display to be of a certain layout, but doing so gives me template suggestions. When I try to implement one of the template suggestions, it doesn't even use the template in themes/custom/*/templates/.

So I am a little confused. Which should I use? It's easy enough to use a layout, but I feel like I should use templates more often than layouts.

I do remember reading that layouts were added in Drupal 8.3 as experimental module, so it sounds like templates existed before layouts. It sounds like it's up in the air as to which one is better to use, but I just wanted some more opinions.

# Answer
> 2 votes
Before Field Layout was added to core this functionality was provided in contrib by Display Suite. With these modules you can configure layouts in UI instead of theming them in node/block/paragraph templates. This is not about one versus the other, this is more about the skill level needed to change the layout. You can use both methods at the same time. However, when you install one of these modules they add a new layer to theming, so you need to adjust any existing node/block/paragraph templates which changed the field layout.

---
Tags: 8, theming
---


title: use a custom textgroup from t()

text:
# Question
Title: use a custom textgroup from t()
I've defined my own textgroup using:

```
function foo_locale($op = 'groups') {
  switch ($op) {
    case 'groups':
      return array('foo' => t('foo strings'));
  }
}

```

The problem is that when I use `t('bar')` in a template, the entry generated in the database (e.g when viewing the template in `/fr`) is associated with the `default` textgroup. This doesn't allow me to use the `foo` textgroup I've previously defined, thus all my custom strings are mixed with the other "Built-in interface" ones.

How can I solve this?

# Answer
t('String') *always* belongs to the "Built-in interface". If you have t() texts, then you don't need to create textgroups.

They are meant for strings that are not translated with that function, usually content/configuration. The I18n modules define lots of these groups for things like variables, menus, taxonomy terms and so on.
> 3 votes

# Answer
Since the t() only for UI and you can not select which exactly the grouptext that you prefer. You can use this:

```
$context = $field_name . ':' . $entity_type . ':label';
$label = i18n_string_translate('field:' . $context, $field_info['label']);

```

Example:

```
$context = 'field_custom:article:label';
$label = i18n_string_translate('field:' . $context, 'Custom title');

```

You have to prefix the context with "field:"
> 1 votes

# Answer
As others have mentioned use i18n module, the specific function is

```
i18n_string_translate($name, $string, $options)

```

This is part of i18n\_string module. Here pass $textgroup . $context as $name, the string to be translated as $string. You can also pass $options\['langcode'\] if translation in a specific language is desired.
> 0 votes

# Answer
You can add strings to a custom text-group by first extracting them to a POT file. Then when you import them at `/admin/config/regional/translate/import` you can assign the strings to your text-group.

Or for user-defined strings you could use the i18n module.

NOTE: Text-groups will be removed in Drupal 8. See http://drupal.org/node/1188430
> -1 votes

---
Tags: 7, i18n-l10n
---


# Question
Title: Redirect user from a custom access callback
In my module routing I have a custom access callback for a payment page.

```
_custom_access: 'Drupal\mymodule\Form\PaymentForm::access'

```

It checks if the user:

* is allowed to make the payment (it's their own)
* actually needs to (has it already been paid)

It works fine, but in the latter case, whilst I can give them an explanatory warning:

```
\Drupal::messenger()->addWarning('Fee already paid or no fee to pay.');
return AccessResult::forbidden();

```

it'd be nicer to redirect them to a page that's friendlier than:

> Access Denied - you are not authorised to access the page.

Drupal / Symfony insists on returning something that implements *AccessResult* \- so I can't return a *RedirectResponse*. Any suggestions? Moving the checks to *buildForm()* seems a bad idea.

# Answer
For the second condition an access denied doesn't seem to be the right answer because permissions are not the reason. It is to control the business logic and for this I think it is a good idea to use buildForm(), which acts in a form route as a controller from which you can return a redirect response:

```
  public function buildForm(array $form, FormStateInterface $form_state) {
    if (...) {
      $this->messenger()->addMessage('Fee already paid or no fee to pay.');
      return $this->redirect('<front>');
    }

    // build form if fee is not paid already

  }

```
> 2 votes

---
Tags: 8, routes
---


title: How to create links from term to node

text:
# Question
Title: How to create links from term to node
On the node display I would like to create a list of services but for some of the services, I would like the list element to be displayed as a link to a certain node, and some will not have links.

I tried creating a vocabulary called Services with an additional Link field, but with no luck.

Ideally it would be good to reference the NID, incase the path changes in the future, and display the link URL without the NID as its final path. But if there is a simpler way using final paths, then I am happy with this.

Below is the desired outcome.

Services:
\- Website Design \<--Linked to node/2
\- SEO \<-- no link
\- Hosting \<-- linked to node/4

# Answer
The module Special menu items lets you create menu items that aren't links.

Using Taxonomy doesn't seem like it would do anything to solve this, unless you want a different list of links to show depending on what node it's being displayed on.

So basically you just create a new Menu and add menu items you want in the list. A Block showing the list is automatically created for each new Menu, so you just have to go to Block configuration and place it in a region of your theme to make it appear. On Block configuration you'll also be able to restrict which pages to display the links on, maybe just the one node.

The thing you asked about using NID is concerning Path aliases. You can use the module Global redirect to make the system always output the alias instead of the NID link. With Pathauto you can configure patterns to automatically create path aliases when creating new content.
> 0 votes

# Answer
I have achieved the results using a view, following the instructions in the below answer: Get list of taxonomy terms for current node through Views

Then placing this Views block on the node.
> 0 votes

---
Tags: 7, taxonomy-terms
---


title: Switch theme by http status code

text:
# Question
Title: Switch theme by http status code
We have a page that uses several themes, but the 404 pages should all look the same.

So, for all themes except one we need a rule that switches to another theme when the URL does not match any content.

There are ways to choose the theme by the current URL, like using the context module, or implementing a `ThemeNegotiatorInterface`, and we use them to assign our themes to certain parts of the website.

It seems that the `ThemeNegotiatorInterface` is not used when delivering a 404 error page.

So, how can we switch the theme according to the http status code?

# Answer
I've done something similar by implementing the `ThemeNegotiatorInterface`. In the function that determines which theme should be used, the following code snippet checks for a 404 Page Not Found exception:

```
$status = \Drupal::requestStack()->getCurrentRequest()->attributes->get('exception');
if ($status && $status->getStatusCode() == 404) {
  return 'name_of_the_theme_that_should_handle_404_responses';
}

```
> 3 votes

---
Tags: theme-negotiation
---


# Question
Title: How to consume a web service using username?
I have set up a very simple web service in another server, using plain PHP, which receives data as GET, does a database search, and retrieves a JSON string. From the server where Drupal is installed, I could get the data using CURL.

Now I need to do the same in Drupal, using username as parameter. How can I achieve this?

All I can find relates to creating web services in Drupal rather than consuming them.

# Answer
> 0 votes
OK, after a lot of research and guessing I think I've solved it, this is my solution in case anyone needs it

```
<?php

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use GuzzleHttp\Client;

class MyModuleController extends ControllerBase {
  protected $httpClient;

public function __construct(Client $http_client) {
  $this->httpClient = $http_client;
}

public static function create(ContainerInterface $container) {
  return new static(
    $container->get('http_client')
  );
}

public function content() {
  $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
  $name = $user->get('name')->value;
  $myurl = 'http://(remote url)?doc='.$name;

  $request = $this->httpClient->request('GET',$myurl);

  if ($request->getStatusCode() == 200) {
     $datos = $request->getBody()->getContents();
     return ['#markup' => $datos,];
  }
}
}
?>

```

This only shows the answer as a string, now I'll have to parse it, etc, and add some security and validation. Opinions are welcome.

---
Tags: 8
---


# Question
Title: How to show users who have not flagged a node with any flag?
Drupal 7. I have a content type that can be flagged with 3 different flags. I need to display a view of users who have not flagged any of them.

The users that are allowed to flag are listed in an entity reference field on the node. My view is a content view that has the relationship to the entity reference list to get the users, then I have a relationship to Flags: User's flaggings for each of the different flags. There is also a Contextual Filter for the current node.

When I add a filter for Flags: Flagged (False) related by the User's Flagging, it seems to check if the user has flagged any content with that flag, not just the current node.

Looking at the flagging table, it seems like I need to do some kind of combined column check. I need to know if the uid has any entries in the table with the same entity\_id (node id in this case).

Will I have to alter the query in code? Any hints on that would be great too. Otherwise, if it can be done in the UI, that would be nice.

# Answer
It's always tricky when trying to display "things that aren't" because Views rely on things that are, even when querying out empty fields.

I haven't tried to recreate your example, but here are some comments that might help start you up:

## Do it for one flag first

Once you have a working example related to only one flag it's easy to repeat the steps adding conditions for other flags. This is difficult enough to figure out for one flag alone.

## List NOT flagged

To display content that isn't flagged, you must **untick** the option **Include only flagged content** in the `Flags: flagname` Relationship, and then use the Filter `Flags: Flagged` set to `Not flagged`:

How to list content that is not flagged.

## Users who aren't here please identify yourselves!

It's impossible to list users who "aren't". You can only list all of them and then filter out the ones who "are".

If you start with Content Views, you can list content that hasn't been flagged, and you can show which users flagged it, but you can't list which users haven't flagged it, because there is no relationship between nodes and users who haven't flagged it!

A better option might be to go with User View. You can add Relationhip to the relevant flag, don't limit only to users who flagged, and adjust to Any user. Add Contextual filter `Flags: Entity ID` and set the default value to `Content ID from URL`, but don't forget to **Exlude** under More. Add a Filter `Flags:Flagged` and set to `Not Flagged`, but this way you only get users that haven't done any flags on any nodes.

You need some additional module to combine and help with showing things that aren't. With Content Views you can't list usernames of people who haven't flagged, while with User views you can only show people who haven't used the flag at all, you can't show a user who hasn't flagged a node if that user flagged another node with that same flag.

## Views Reference Filter module

This module has a cryptic explanation on its project page, but could be useful in your case to pass one views results to the main views display to combine the results so you get something meaningful.

Views Reference filter module can be used to filter a View with the results of another (Entity Reference) Views Display. It can pass arguments to the embedded view:

You can probably create one View listing all Users who are allowed to flag Content, create another view that shows the users that have flagged it, then filter the first view with the negative second one. Just remember that the Field type of the Views Reference Filter must match the type of ER Views Display type (uid-user).

## Introduce Flags Relationship

You need to add a Relationship that contains information about the node flag status. I doubt you can do that with `User's flaggings` without another Relationship before it that connects to the user who flagged, which is a roundabout way.

Just use the `Flags: flagname`, don't limit to Include only flagged content, and do set it to `Any user`.

Later you can add more Relationships to display users names etc, first you need to focus on making the filtering work.
> 2 votes

---
Tags: 7, views, flags
---


# Question
Title: 500 error on one page in entire site only showing error "You are here" instead of administration content
this error seems to only affect one page in on the website, and nowhere else. Here is what it looks like:

The watchdog reports do not show the issue, and I believe it to be a permission error or caching error with Apache2, but unsure. I have tried: clearing cache, searching for a relevant php file with unreadable permissions, and looking over .htaccess files for anything out of the ordinary. I may have missed a few php files but I am looking for confirmation that I am heading in the right direction.

I will probably end up asking the web platform IT people for help if I can't find an answer, but anything at all will be greatly helpful. Thank you.

# Answer
> 0 votes
If you have shell access to your server, you could check the actual php error logs on the server- which should indicate the exact culprit.

If you recently updated Drupal core or some contrib modules, you may want to make sure the update process completed successfully.

Also, if you were editing/adding a custom feature module, content types, field collections, paragraph bundles, or other entities referenced by the specific "People" content type, you may have accidentally removed a required field that could cause the page to break- in which case, restoring a backup database could fix the issue.

---
Tags: 7, http-request
---


# Question
Title: "Uncaught TypeError: Cannot read property 'getAttribute' of undefined"
There are some posts about this error for Drupal 7, but I'm using Drupal 8.1 and those solutions don't work for D8.

I tried this patch (coded for D7) and doesn't work.

The effect of the error is that QuickEdit doesn't work: sometimes the quick edit link doesn't appears, sometimes it appears but when edit some fields I get error.

Can anybody help?

**UPDATE for neograph**: I haven't changed anything about the loading of the javascript. The only thing I did is edit the `my_theme.libraries.yml` for adding JS plugins:

```
global-css:
  css:
    theme:
      #css/style.css: { }
      dist/css/style.css: { }

global-js:
  js:
    #js/script.js: { }
    bower_components/slick-carousel/slick/slick.min.js: { }
    bower_components/slicknav/dist/jquery.slicknav.min.js: { }
    bower_components/superfish/dist/js/superfish.min.js: { }
    dist/js/script.js: { }
  dependencies:
    - core/jquery

```

# Answer
The problem is in panels module, upgrade to latest version to fix the issue. For more details see https://www.drupal.org/node/2713123
> 0 votes

# Answer
add `defer` to js files. When present, it specifies that the script is executed when the page has finished parsing.

```
global-css:
 css:
 theme:
   #css/style.css: { }
   dist/css/style.css: { }

global-js:
 js:
   #js/script.js: { }
   bower_components/slick-carousel/slick/slick.min.js: { attributes: { defer: true } }
   bower_components/slicknav/dist/jquery.slicknav.min.js: { attributes: { defer: true } }
   bower_components/superfish/dist/js/superfish.min.js: { attributes: { defer: true } }
   dist/js/script.js: { attributes: { defer: true } }
dependencies:
 - core/jquery

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Making custom database text fields available for search
I have a custom module that stores text records in a table, however this table records are not mapped to nor an entity neither a node, so as far as I know, I can't expose them to the search module or the search API.

So my question is how do I expose my data (custom table fields) to Drupal so I can use some sort of search module (preferably search API or the core search) ?.

# Answer
> 0 votes
You can use

To define your own search type and add the required data to the index.

# Answer
> 0 votes
I really think it is good practice to store the data as entities making you able to use views, search, editing, permissions, ... Take a look at the following snippet on how to store your data as entities. Use the Entity Construction Kit (ECK) module to create the entity bundle, type and fields and store your data like this:

```
$new_ent = entity_create('TYPENAME_YOU_DEFINE_IN_ECK', array(
  'uid' => 1, // the uid that created this record
  'type' => 'BUNDLENAME_YOU_DEFINE_IN_ECK',
  'field_FIELDNAME_YOU_DEFINE_IN_ECK' => 'TEXT_RECORD_VALUE'
 ),
))->save()

```

You'll even get an admin interface from ECK for free. After the creation, you can index the data also.

---
Tags: 7, search
---


title: Moving a change to other servers

text:
# Question
Title: Moving a change to other servers
Is there a way a person can ensure that if he makes a change to a drupal 8 website via the UI (*e.g. Adding/modifying a field to a content type, creating/editing a view*) that this can be automatically applied to another developers localhost on the git pull or on a staging/production server?

Currently (*I have moved from Drupal 7*) I am doing this manually which is a pain. I've been told that Features is the way to go from Drupal 8 (*and Drupal 7 apparently*).

# Answer
In D8, this is done by configuration synchronization (the config\_sync module).

The entirety of the configuration (fields, views, formats, block layout, etc) can be exported to YAML files, and imported on another installation (which should be using a copy of the original database).

There are several ways to do this, but since you already mention git, one of the cleaner ways to do it is to run `drupal config:export` in Drupal Console, and add the resulting directory (which should be in `sites/default/config` by default, but this path can be changed) to your git repository, and import it with `drupal config:import` on the other installation after pulling.

(Content, even taxonomy and content blocks, isn't exported unfortunately, which may break your block layout and taxonomy filters in views.)
> 2 votes

# Answer
Features in D8 is the way to sync features across multiple sites. And was the default in D7 to import and export database changes. Which in D8 is solved by Configuration management.

Please read the docs (thoroughly): Managing your site's configuration.

You routinely have to `drush cex` after you've made changes via the UI. This will export database values into multiple (hundreds/thousands) `*.yml` files. Then your colleagues will have to `drush cim` after they pulled the latest `*.yml` files to get the changes imported into their DB.

---

For a general overview please see Web development structure on multiple devices.
> 2 votes

---
Tags: 8
---