title: Using node values in a custom token

text:
# Question
Title: Using node values in a custom token
I'm trying to create a custom token using the Custom Tokens module. The token should use (and modify) a node field value, but it not returning any value.

I set the token to need node data and I am using the following code.

```
print ($variables['my_custom_field_name']);

```

How do I access field values within a custom token?

# Answer
Creating custom tokens for nodes is fairly straightforward, Drupal provides core hooks to define your own. Here is an example from a project I just completed in a small custom module:

```
/**
 * Implements hook_token_info().
 */
function MYMODULE_token_info() {
  $info['tokens']['node']['custom_year'] = array(
    'name' => t('Year Field Value'),
    'description' => t('Value from the year field.')
  );

  return $info;
}

/**
 * Implements hook_tokens().
 */
function MYMODULE_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = [];

  if ($type == 'node' && !empty($data['node']) && array_key_exists('custom_year', $tokens)) {
    $replacements['[node:custom_year]'] = $data['node']->field_custom_year[LANGUAGE_NONE][0]['value'];
  }

  return $replacements;
}

```

Where `field_custom_year` is the machine name of your field. This token provides the field value for me and is used in a Pathauto alias token chain. *Most* fields store their data in a `value` column, but not all of them do (like a Date field, or custom fields using country codes, or postal address, or years etc). `[LANGUAGE_NONE][0]['value']` won't work in that case, you would need to replace `'value'` with the right name of the column.

Since you are using the Countries module and it stores the field value in a column called `iso2`, then your replacement line would have to be:

`$replacements['[node:custom_token]'] = $data['node']-> field_prgm_country[LANGUAGE_NONE][0]['iso2'];`

See:

**Edit**

I assumed you were using this token somewhere where replacement would be otherwise automatic (like a Pathauto alias).

If you are using it in a field, like a Body field (WYSIWYG or plain text), you will need to do the replacing yourself. Drupal does not know you have tokens needing to be replaced, it just assumes its a regular string.

Here is an example of replacing a longtext (body) field tokens with what their values should be:

```
/**
 * Implements template_preprocess_node().
 * @param $variables
 */
function mytheme_preprocess_node(&$variables) {
  if (!empty($variables['node']->field_myfield_name)) {
    $variables['replaced_text'] = token_replace($variables['node']->field_myfield_name[LANGUAGE_NONE][0]['value'], ['node' => $variables['node']]);
  }
}

```

Note that I am not entire sure this example above is 100% accurate in your case, but calling `token_replace(...)` will cause any valid token string found in that fields value to be replaced, which you could then use a debugger within `hook_tokens` above to see whats going on. You'd then have to use that new variable in your node template, or overwrite the fields original value (don't know the full syntax off the top of my head here, sorry).

Alternatively, you could look at Token Insert or Token Filter to aid you here, but both seem to have reported issues of it not working correctly (hence the code first approach here, plus teaches you a little bit about common hooks, extensions, and adding functionality in Drupal).
> 3 votes

# Answer
You can access to node in this manner into custom token UI:

```
<?php
    //Accessing to node.
    $node = $data['node'];

    //Retrieving your field.
    $token = '[node:your_custom_field_name]';
    $your_field_value = token_replace($token, array('node' => $node));

    // DOing something
    $new_value = ...;

    print $new_value;
?>

```

I hope this help you.
> 0 votes

---
Tags: tokens
---


# Question
Title: Theme CSS libraries always loaded after module libraries
My custom theme uses Bootstrap, which I'd obviously like to load before any module CSS libraries, but Drupal ignores any kind of ordering for themes, and Bootstrap CSS styles appear as `@import` in a `<style>` tag that *always* comes last, even if it's set to base. Modules however, respect SMAACS groupings and will move CSS @imports into different style tags.

How can I get the theme CSS files to load before module CSS files? Why is bootstrap ALWAYS at the bottom?

I've cleared the cache, disabled devel, tried aggregation on and off. Nothing makes a difference.

This is the code I am using.

### /themes/custom/trent/trent.info.yml

```
core: 8.x
type: theme

name: "Trent"
description: "Test theme"
package: "Trent"

libraries:
  - trent/bootstrap

```

### /themes/custom/trent/trent.libraries.yml

```
bootstrap:
  css:
    base:
      libraries/bootstrap/bootstrap.min.css: {}

```

### /modules/custom/trent\_news/trent\_news.info.yml

```
name: Trent News
type: module
description: Displays news
core: 8.x
package: Trent
libraries:
  - trent_news/trent-news

```

### /modules/custom/trent\_news/trent\_news.libraries.yml

```
trent-news:
  version: 1.x
  css:
    theme:
      css/trent_news.css: {}
      css/print.css: {}

```

I want bootstrap to move up higher but Drupal isn't respecting any setting; it just keeps it in that last `<style>` tag no matter what. However, it does respect SMAACS ordering *within* that style tag, oddly enough. As I mentioned, I can change the module ordering (e.g. theme -\> component) and the CSS imports will move into different `<style>` tags accordingly.

**UPDATE:**

`core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php:165` overrides and ignores any SMACCS setting (or group setting in \*.libraries.yml) for theme CSS. It actually doesn't appear possible to move the import higher up before any module includes:

```
$options['group'] = $extension_type == 'theme' ? CSS_AGGREGATE_THEME : CSS_AGGREGATE_DEFAULT;

```

# Answer
> 2 votes
The proper way to modify the loading order is *weight property* as described here. The lower the weight the further up your library should go.

Try something like the following in your *trent/trent.libraries.yml*

```
bootstrap:
  css:
    base:
      libraries/bootstrap/bootstrap.min.css: {weight: -50}

```

You might have to adjust the number to get it to desired position.

NOTE: weight is in the process of being replaced by dependencies. Work done can be seen in this issue and when ready this sort of problem will be easier to tackle.

# Answer
> 2 votes
# Solution

Implement a `hook_css_alter()` in your theme and make sure the CSS group for your stylesheet is the right one. Replace `THEME` with your theme's machine name.

```
/**
 * Implements hook_css_alter().
 */
function THEME_css_alter(&$css, AttachedAssetsInterface $assets) {
  if (isset($css['libraries/bootstrap/bootstrap.min.css'])) {
    $css['libraries/bootstrap/bootstrap.min.css']['group'] = CSS_BASE;
  }
}

```

## Cause

I think there's a probable bug in core. According to the CSS file organization documentation, `CSS_BASE` is supposed to be loaded before other things. However, for some reason, Drupal assigns the weight of `100` to the theme's `base` stylesheets, which is not correct. So, I simply wrote the hook to restore the stylesheet weight to the correct one, i.e. `CSS_BASE`.

---
Tags: theming
---


title: Facet - default value with search api

text:
# Question
Title: Facet - default value with search api
I am using content type in Facet. The search result will be having an option to choose the content type to filter the result.

I want the search should show the result with particular content-type filtered by default. Is it possible? If so, how to do that?

To be little more clear instead of

https://example.com/searchpage?search\_terms=xxxx

I want to search as following by default.

https://example.com/searchpage?search\_terms=xxxx&f\[0\]=content\_type:content\_page&f\[1\]=content\_type:cotent\_page

# Answer
> 0 votes
Not sure you can do this with facets. Facets by definition show only options that exist in the current query results. There is no guarantee that a content\_page type will be among the search results for a term.

You may want to consider using an exposed view filter (the views\_block\_filter\_block module lets you turn this into a place-able block). This would show all content types and can have a default type selected if the filter has none.

---
Tags: views, 8, search
---


# Question
Title: How do I send a variable value from my form to another page using the POST method?
In the first page I have the following code:

```
$form['message1'] = array(
  '#markup' => $this->t('Check Your Details once again !!'),
);

$form['candidate_name'] = array(
  '#type' => 'textfield',
  '#title' => t('Candidate Name:'),
  '#required' => TRUE,
);

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

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

return $form;

function submitForm(array &$form, FormStateInterface $form_state){
  drupal_set_message($this->t('@candidate_name! Wow! Nice choice! Thanks for telling us!', array('@candidate_name' => $form_state->getValue('candidate_name'))));
  $form_state->setRedirect('second_page');
}

```

In the second page I have the following code:

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

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Candidate Name:'),
    '#required' => TRUE,
  );

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

  return $form;
}

```

How can I get the first page candidate name into the second page candidate textfield?

# Answer
Quite a pickle! Here are some suggestions:

**Solution 1: Session to the rescue!**

* After the first form is submitted, validated and processed, store the relevant values (the ones you want to pass to the second form) in the session.
* While building the second form, use the values stored in session as default values to pre-populate it.

**Solution 2: Multi-step form**

* Merge the 2 forms into one giant form. Put the elements of the first form in one *container* and the elements of the second form in another *container*. Set `#access` to `FALSE` for the second container to hide the second container.
* After the user submits the info in the first part of the form, hide the first container and show the second one!

**Reference:** See the form examples provided in the examples module.

**Solution 3: Form states?**

Depending on situation, you can also consider using form states. If you use form states, the hiding and showing can be done in the client-side. So the form will make one request to the server once it has all the data.

**Solution 4: Change form action!**

Depending on situation, you may even consider changing the `action` attribute of the form so that the values are submitted to the URL you specify in the form's `action` attribute.
> 2 votes

# Answer
This is how I send information from one form to another.

In the first page:

```
use \Drupal\Core\Url;

function submitForm(array &$form, FormStateInterface $form_state){
  drupal_set_message($this->t('@candidate_name! Wow! Nice choice! Thanks for telling us!', array('@candidate_name' => $form_state->getValue('candidate_name'))));

  $params['query'] = [
    'candidate_name' => $form_state->getValue('candidate_name'),
  ];

  $form_state->setRedirectUrl(Url::fromUri('internal:' . 'second_page', $params));
}

```

In the second page:

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $candidate_name = \Drupal::request()->query->get('candidate_name');

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Candidate Name:'),
    '#required' => TRUE,
    '#value' => $candidate_name,
  );

  return $form;
}

```

**EDIT:** For POST method I never see it before, but you can create in the first page a session var and use this var in the second var after the redirection. Take a look in Storing Session Data with Drupal 8.

**SECOND EDIT**: It seems that the correct way todo this is with PrivateTempStore, if you go to see the CommentAdminOverview in Core you will see this:

```
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
      ...
      $info = [];
      /** @var \Drupal\comment\CommentInterface $comment */
      foreach ($comments as $comment) {
        $langcode = $comment->language()->getId();
        $info[$comment->id()][$langcode] = $langcode;
      }
      $this->tempStoreFactory
        ->get('comment_multiple_delete_confirm')
        ->set($this->currentUser()->id(), $info);
      $form_state->setRedirect('comment.multiple_delete_confirm');
    }
  }

```

In this page you collect the comment id that you want to delete and made a redirect, and the comment deletion happens in `comment.multiple_delete_confirm` (ConfirmDeleteMultiple) that have the following code:

```
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $this->commentInfo = $this->tempStoreFactory->get('comment_multiple_delete_confirm')->get($this->currentUser()->id());
    if (empty($this->commentInfo)) {
      return $this->redirect('comment.admin');
    }
    /** @var \Drupal\comment\CommentInterface[] $comments */
    $comments = $this->commentStorage->loadMultiple(array_keys($this->commentInfo));
  ...
  }

```

So, we don't have a POST method from one form to another in Drupal 8 but this can be solved in this way.
> 3 votes

# Answer
One way you can do this is to add a query string with the value on it with setRedirect.

```
$form_state->setRedirect('second_page', ['name' => $form_state->getValue('name')]);

```

Then, read it in the next form:

```
// top of file
use Drupal\Core\Component\Utility\Xss;

$name = Xss::filter(\Drupal::request()->get('name'));

$form['name'] = array(
  '#type' => 'textfield',
  '#title' => t('Candidate Name:'),
  '#default_value' => isset($name) ? $name : '',
  '#required' => TRUE,
);

```

Note, I wouldn't do this for more sensitive information like credit card numbers or anything like that.
> 2 votes

# Answer
From 8.2 you can use `hook_ENTITY_TYPE_prepare_form()`

E.G.

```
function hook_ENTITY_TYPE_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
  if ($operation == 'edit') {
    $entity->label->value = 'Altered label';
  }
}

```

So assuming your second form is a node, you could do:

```
function submitForm(array &$form, FormStateInterface $form_state){
  drupal_set_message($this->t('@candidate_name! Wow! Nice choice! Thanks for telling us!', array('@candidate_name' => $form_state->getValue('candidate_name'))));

  $params['query'] = [
'candidate_name' => $form_state->getValue('candidate_name'),
  ];

  $form_state->setRedirectUrl(Url::fromUri('internal:' . 'second_page', $params));
}

function my_modules_node_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
  $candidate_name = \Drupal::request()->query()->get('candidate_name');
  if($candidate_name) {
    $entity->set('name', $candidate_name);
  }
}

```
> 0 votes

# Answer
You can set the information in session if it is related to single user. Hope it helps.
> -1 votes

---
Tags: 8, forms
---


# Question
Title: Programmically add multiple empty fields on a multiple value field/form
In Drupal 7, When you set a field "Number of values" to unlimited, it will show you 1 field on the creation page with an add more button. How would one go about so it shows 5 empty fields on the creation page?

# Answer
> 0 votes
Have tested this in Drupal 8 but I think it is the same for drupal 7.

```
if($form_id == 'node_MYCONTENTTYPE_form') {
  $item = $form['FIELD_MY_FIELD_NAME']['widget'][0];
  for ($n=1; $n<5; $n++) {
    if(!isset($form['FIELD_MY_FIELD_NAME']['widget'][$n])) {
      $form['FIELD_MY_FIELD_NAME']['widget'][$n] = $item;
    }
  }
}

```

# Answer
> 0 votes
With Stef help, I figured it out for D7

```
/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id)
  if ($form_id == 'MYNODE_node_form') {
    $item = $form['field_NAME'][LANGUAGE_NONE][0];
    // Add a minimum of 5 fields.
    for ($n=1; $n<5; $n++) {
    if(!isset($form['field_NAME'][LANGUAGE_NONE][$n])) {
      $form['field_NAME'][LANGUAGE_NONE][$n] = $item;
    }
  }
}

```

Now the only problem is it'll grab field 1, so if field 1 has a value in it, it'll get copied, to the 2nd, then 3rd, etc. If I figure that out I will update my answer. For now, I hope this helps others.

---
Tags: 7
---


title: comments module with infinite scroll

text:
# Question
Title: comments module with infinite scroll
I've added a comment field to my content type. Now I'd like to add infinite scroll to the comments messages, so it shows by default some number of comments and when I click on the load more button, it shows more.

The problem is that the list of comments is coming from the comment module, not a view, so I can't add infinite scroll plugin to the pager. If I create a custom view that shows the comments, it gets complicated because some comments have nested comments and so on. Is there any solution?

# Answer
One option is to create a "views block" that shows comments, set it to use views infinite scroll, then add it to the bottom of the page (and disable the page from showing comments the normal way).
> 0 votes

---
Tags: 8, comments
---


# Question
Title: Creating a view with multiple latest content types
I am looking to create a view for my home page that displays the 3 last added items for 2 different content types (articles and news). Like 2 lists next to each other that also has the option to show more.

I already tried by creating a view with one of the 2 content types but I couldn't seem to manage to show both content types in the same view.

# Answer
> 2 votes
You can create two views, one for each content type, the configuration is the same, Filter Criteria should be Content Type (select in one articles and in the other news) you should sort by Authored on in DESC order, in the pager select Display a specified number of items (3) and More link (Yes).

Then you can add the two blocks to the page and add the styles with css.

# Answer
> 0 votes
If you want two lists, then I'll double Adrian's answer, and say you're going to want two different views. If you select both content types in the same feed, then they'll be interspersed, an order like this: article1 news1 article2

You can add the links by modifying the twig template in your theme.

---
Tags: views, 8
---


# Question
Title: How can I tell if I'm on a taxonomy page in preprocess_page?
If I'm on a node, inside preprocess\_page(&$variables), I can check

`if (isset($variables['node']) && $variables['node']->bundle() == 'my-type')`

to see if I'm on a node, and a node of a certain type.

Then I can get field information with

```
$variables['node']->field_icon->entity->getFileUri()

```

How can I do the same thing for a taxonomy term page to know that I'm on a taxonomy term page and get the field values?

# Answer
Unfortunately I don't think there is anything that the hook gives you directly that you can use in this instance. However you can always check the route name to determine if you are on a taxonomy term page.

```
// Will be "true" if you are currently on a taxonomy term page.
if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical') {

  // Since this is a taxonomy term page, you may wish to get the term ID.
  $term_id = \Drupal::routeMatch()->getRawParameter('taxonomy_term');
}

```
> 6 votes

# Answer
To check term data in theme\_preprocess\_page for drupal 7. you can use below code.

```
if (arg(0) == 'taxonomy' && arg(1) == 'term') {
if (isset($variables['page']['content']['system_main']['term_heading']['term']['#term'])) {
  $term_data = $variables['page']['content']['system_main']['term_heading']['term']['#term'];
}

```

}

Hope this helps.
> 1 votes

# Answer
There is two ways to get the term in `preprocess_page`.

1. Get the tid from parameter and then load the term.
2. Get the Term directly from ParameterBag.
Her is code snippet

```

use Drupal\taxonomy\Entity\Term;
/**
 * Implements hook_preprocess_HOOK().
 */
function myModule_preprocess_page(&$variables) {
  // Get the tid.
  $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term');
  // Load the term.
  $term = Term::load($tid);

   // Get possible params.
   /** @var \Symfony\Component\HttpFoundation\ParameterBag $possible_parameters */
   $possible_parameters = \Drupal::routeMatch()->getParameters();
    // Get term
    $term = $possible_parameters->get('taxonomy_term');
}

```
> 1 votes

---
Tags: taxonomy-terms
---


# Question
Title: Is there a "best practice" for overriding a contributed module's controller?
I'm still relatively new to Drupal 8 and recently I came across an occasion to override the WebFormSubmissionListBuilder Controller.

I eventually found another project which had exactly the same need and they did it as below:

```
<?php
/**
 * Implements hook_entity_type_alter().
 *
 * @todo This alters all webform_submission entites but should alter only the ones in configured workflows.
 */
function academic_applications_entity_type_alter(array &$entity_types) {
  /* @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
  $entity_types['webform_submission']->setListBuilderClass('Drupal\academic_applications\WebFormSubmissionListBuilderOverride');
}

```

While this works I can see it being a real problem if more than one module tried to override another module's controller this way. However, I couldn't find a better way so I ended up using their method for now.

Is there a known or "best practices" for doing this? I don't see any obvious plugin points in the WebFormSubmissionListBuilder controller's code so taking it over seems to be the only way to extend it as far as I can tell.

# Answer
> 10 votes
To avoid conflicts with other modules you could alter the controller content in a kernel VIEW event similar to a form alter hook:

*src/EventSubscriber/ControllerAlterSubscriber.php:* \<?php

```
namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Class ControllerAlterSubscriber.
 */
class ControllerAlterSubscriber implements EventSubscriberInterface {

  /**
   * Alters the controller output.
   */
  public function onView(ViewEvent $event) {
    $request = $event->getRequest();
    $route = $request->attributes->get('_route');

    if ($route == 'entity.webform_submission.collection') {
      $build = $event->getControllerResult();
      if (is_array($build)) {
        // alter controller build array
        $build['added_content'] = ['#markup' => '<p>Added by ControllerAlterSubscriber.</p>'];

        $event->setControllerResult($build);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    // priority > 0 so that it runs before the controller output
    // is rendered by \Drupal\Core\EventSubscriber\MainContentViewSubscriber
    $events[KernelEvents::VIEW][] = ['onView', 50];
    return $events;
  }

}

```

*mymodule.services.yml:*

```
services:
  mymodule.controller_alter:
    class: Drupal\mymodule\EventSubscriber\ControllerAlterSubscriber
    arguments: []
    tags:
      - { name: event_subscriber }

```

---
Tags: webforms, page-controller
---


title: 'Order of importance' type field

text:
# Question
Title: 'Order of importance' type field
I'm using an Entityform to create a survey for a client, however one of the types of question they have is to rank a number of options in terms of importance to the user.

Similar to how the draggableviews module work would be the ideal, but I know that draggableviews changes the global setting for that list, rather than a per-user response.

Is there any way to achieve something like this?

# Answer
> 0 votes
Could you use "tabledrag", the code draggableviews uses to do dragging? It is basically javascript acting on an html table, with a weights column to remember the order.

Have a look at how the block module uses it (but bear in mind block is more complex because it has multiple regions to manage).

For tabledrag to work you need your questions in the form of a html table, which you then extend using the render array "#type" = "tabledrag". It is possible to configure tabledrag in Javascript, too.

---
Tags: 7
---


# Question
Title: Form fields still treated as required even after setting #required to false
I'm using `hook_form_alter` to remove the "required" setting for a couple of fields, specifically the *First name* and *Last Name* fields on the Address form.

Here's my code, where I provide a callback function for `#after_build` to remove the required setting:

```
function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id === 'listing_edit_form') {
    $form['address']['widget'][0]['address']['#after_build'][] = '_mymodule_customize_address';
  }
}

function _mymodule_customize_address($element, $form_state) {
  $element['given_name']['#required'] = false;
  $element['family_name']['#required'] = false;
  return $element;
}

```

The problem is that after I submit the form, the fields are still treated as required, which means that if I don't enter any data for them the submit fails with an error message telling me that those fields are required.

Note that even if I hide the fields by setting `#access` to `false`, the form submit will still complain that they are required. So it seems to be a backend issue with the Address module.

I have:

```
Drupal                  8.7.1
drupal/address          1.6.0
commerceguys/addressing 1.0.3
commerceguys/enum       1.0
commerceguys/intl       1.0.4

```

I'd appreciate any help with this. Thanks!

# Answer
> 0 votes
Have you tried unset() on the #required element, rather than making it false?

---
Tags: 8
---


# Question
Title: Submitting a form causes 'secure connection failed' error that persists
I've got a SSL certified server running drupal 7.37. Everything was working fine until I started adding form submission to a module I'm working on. As soon as I submit the form, I get 'Secure Connection Failed' in all browsers. I can get to other pages ok, but not the homepage which then also throws the same error. This persists until I restart my internet connection.

I did the following test to try and find the problem:

I submit the form on my desktop pc - secure connection failed.

I try to go to the domain root - secure connection failed.

I check on my laptop which is connected to the same router - secure connection failed.

I check on my phone using 4g - works fine.

So I seem to be causing a local network wide issue somehow, but I don't know how to fix it.

This is the form, it just uploads an xml file to the temp directory:

```
$form['file'] = array(
    '#type' => 'file',
    '#title' => t('XML file'),
    );
$form['submit_button'] = array(
    '#type' => 'submit',
    '#value' => t('Import'),
    );
return $form;

```

This is the validate function:

```
$file = file_save_upload('file', array(
    'file_validate_extensions' => array('xml'),
));

if ($file = file_move($file, 'public://'))
{
    $form_state['storage']['file'] = $file;
}
else
{
    form_set_error('file', t("No file was uploaded. Check extension is .xml"));
}

```

This is the submit function:

```
$file = $form_state['storage']['file'];
unset($form_state['storage']['file']);
dsm($file);
$file->status = FILE_STATUS_PERMANENT;
file_save($file);

$filepath = file_create_url($file->uri);
dsm($filepath);

```

Any help would be appreciated, it's driving me mental.

UPDATE: This problem disappeared for a few hours, then returned for no apparent reason. I'm thinking it might be a problem with my internet provider.

# Answer
For those who end up in this situation, the reason for this to happen is an error somewhere in your PHP code that is not caught by the PHP interpreter or Drupal itself and the server disconnects to your browser immediately before sending any information (including for example the web server certificate). It is not a network-related error as suggested above here.

To solve the problem, install the xdebug PHP module, configure it and run your scripts again. You will now get far better insight in the cause of the error(s) and it is actually caught before a disconnect.

In my case, the disconnect was caused by a recursion limit hit in my code, which was not caught by the PHP interpreter. Took me a few hours, mostly looking in the wrong direction (network issues, certificate issues).
> 0 votes

---
Tags: forms, ssl
---


# Question
Title: Commerce Address Book – need to reuse customer profile without address
In addition to the default shipping and billing addresses I have added a customer profile in Drupal Commerce, where the customer can add additional info, like email for invoices, special marking on shipped goods, comments and so forth.

This info is often the same on each order and we have recieved feedback that customers dont want to fill in these fields again and again when placing orders.

I have tried out the Address Book module and it seems to work for billing and shipping addresses, but how can I reuse info from previous customer profile that does not include an address? Maybe just skip the dropdown address field and use a previous customer profile and still have the possibility to edit the info?

Anyone that can point me in the right direction?

EDIT 1: as i am trialling and testing the address book module, I realize that the dropdown menu is empty in my added customer profile (because there is no address field). I need to be able to choose which field in the added profile that should be saved as "options" in the dropdown menu. Is this possible to accomplish in code? I am not asking for complete solutions here. Mereley is it possible? If yes, are there hooks I can use?

EDIT 2: I discovered that the dropdown menu is not empty after all... it's just the human readable value that is missing. There are several empty options values that can be selected after which the field values are populated from the corresponding saved customer profile. So my question changes again (sorry about that). How can I add human readable values from one of the fields in my customer profile?

# Answer
It turns out that the Commerce Addressbook Extra module takes care of this. In case anyone else is searching after a smooth solution. Link to module
> 0 votes

---
Tags: 7, commerce
---


# Question
Title: Can I use Moment.js to fix a client side date format issue?
Different Browser and OS show a different date format on client side. Given the following markup:

```
<input data-drupal-selector="edit-field-date-end-value-date" title="Date (e.g. 2019-05-15)" type="date" min="1969-05-15" max="2069-05-15" data-drupal-date-format="Y-m-d" id="edit-field-date-end-value-date" name="field_date[end_value][date]" value="2019-05-11" size="12" class="form-date hasDatepicker">

```
* In Chrome: dd/mm/yyyy
* In Safari: yyyy-mm-dd

I think it's an issue with input type date, because it is showing as per browsers HTML5 or HTML4.

How can I solve this issue? So while load or if select from datepicker then it also solves? Do I maybe need to use Moment.js?

http://jsfiddle.net/g7mvaosL/

# Answer
Actually the thing is `type="date"` is not supported by the Safari browser and moreover best practice is to use server time rather using JavaScript. Maybe the following code helps

```
var dateSTR = "2019-05-15";

var date = new Date(dateSTR.replace(/-/g,"/"));

console.log("0:" + new Date("2019-05-15"))
console.log("1:" + date)
date.setUTCHours(date.getHours());
console.log("2:" + date)
date.setUTCMinutes(date.getMinutes());
console.log("3:" + date);
console.log("4:" + date.toLocaleDateString());

```
> -2 votes

---
Tags: 8, datetime
---


title: Content Admin Search Tool Drupal 8

text:
# Question
Title: Content Admin Search Tool Drupal 8
As a content admin, are there any feasible ways in Drupal 8 to search the source HTML of certain Text fields across multiple content types. For example, I want to find all nodes that contain `<div class='special-list'>` in one or more Text fields.

For Drupal 7, it seems that Views Bulk Operations would suffice. Has anyone encountered a similar need in D8?

# Answer
> 0 votes
VBO doesn't search, it only gives you the interface to select items in the Views results and perform actions on them.

To construct the search you want you can use ordinary Views with the `Combine fields filter` filter, here's one video tutorial: Search across Fields in Views using Combine Fields Filter in Drupal 8, or use Search API for something more advanced.

Once you have the search working you can add the VBO field if you need to do some actions on the found items.

---
Tags: 8, search
---


# Question
Title: How to change DateTime field value on form submit
I am trying to update a DateTime field in an altered form submit. Something like:

```
function my_module_form_submit($form, FormStateInterface $form_state) {
  if (!$profile->field_someother_field->isEmpty()) {
    $date = new DrupalDateTime();
    $date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
    $string = $date->format(DATETIME_DATETIME_STORAGE_FORMAT);
    $form_state->setValue('field_date_updated_details', [$string]);
  }
}

```

But this fails with various messages (depending on whether I set the value as an array or directly as string).

Any advice?

# Answer
The form value need to be an call DrupalDateTime, so you can directly pass **$date** as value.
> 0 votes

# Answer
I've been working on a similar problem, and the following kind of thing works for me:

```
$form_state->setValue('field_date_updated_details', [['value' => $date]]);

```

As another respondent noted, I'm not using a string, but the actual DrupalDateTime object, and setting the **'value'** inside that nested array.
> 0 votes

---
Tags: 8, datetime
---


# Question
Title: "No query was run" when Contextual Filter is added. Was working before
I have a bunch of nodes with terms in a certain vocabulary. The vocabulary consists of doctors' specialties, like "Gynecology / Obstetrics". Terms in this vocabulary have a few extra fields:

* Singular noun form ("Gynecologist / Obstetrician")
* Plural noun form ("Gynecologists / Obstetricians")
* URL string ("obgyn")

I have a view that displays all the nodes associated with the term. The view's path is "doctors/specialties/%", and it has a Contextual Filter for the URL String field of the taxonomy term, via a taxonomy Relationship. So when you go to /doctors/specialties/obgyn, you get a page with a heading "Gynecologists / Obstetricians" and then all the content with that term.

This view previously worked perfectly, but at some point something changed, and now it returns 404. The preview in the Views UI just says "No query was run". When I delete the Contextual Filter, it shows all the normal SQL, but when I re-add it, it goes back to "No query was run".

Here's a dump of the view. Can anyone tell me what I'm doing wrong?

# Answer
I had already flushed caches and reloaded the page twice (yes, I'm positive, and yes, I swear) when I originally asked this question, but at some point my view magically started working again. So I guess I should have just flushed caches and reloaded the page *harder*.
> 1 votes

# Answer
Seemed to be a hidden flag. Choosing `Display > Advanced > Contextual Filters > Specify validation criteria`

I still had a node type selected. Unchecked node types, then unchecked Specify validation criteria, then save.

Results as expected when previewing with filters.
> 2 votes

# Answer
When you add a contextual filter to a view, the preview should default to 'No query was run.' This is because you have to actually enter a value into the '*preview with contextual filters:*' box before hitting preview. Doing this will refresh the preview and consequently show the SQL.
> 1 votes

# Answer
For me this happened because of particular values in the Contextual Filter configuration itself. I had two filters in that section. Both were set 'When the filter value was not present' to 'query'. The query parameter was named, but I couldn't get rid of this message until both filters had the "fallback value" set to all (without a capital A, FWIW).
> 0 votes

# Answer
In my case the preview of block with contextual filters worked on a localhost site, then I exported the view into configuration, refreshed my local DB from live, updated to core 8.7.1 from 8.6, re-imported the configuration and the view is fine but the preview no longer works. I have to save and refresh a page where the block appears to preview my changes, which while inconvenient is not a dealbreaker.
> 0 votes

---
Tags: views
---


title: How to use t() function in controller?

text:
# Question
Title: How to use t() function in controller?
I understand Drupal 8 ControllerBase implements StringTranslationTrait so we can use $this-\>t() in Controller class. But I found in Drupal 8 examples code, they setStringTranslation to use t() function. Here is the code.

```
public static function create(ContainerInterface $container) {
    $controller = new static(
      $container->get('database')
    );
    $controller->setStringTranslation($container->get('string_translation'));
    return $controller;
  }

```

The link for their module. https://git.drupalcode.org/project/examples/blob/8.x-1.x/tablesort\_example/src/Controller/TableSortExampleController.php

My question is why setStringTranslation when you can just use t() function in the controller.

# Answer
> 0 votes
`$this->t()` assumes object context. `$this` isn't available in the static context of the create method above.

The ControllerBase provides access to `t()` via a protected function (see below from docs) to it is also not available from the public context. `setStringTranslation` however is a publicly available method.

```
StringTranslationTrait::t   protected   function    Translates a string to the current language or to a given language.
...
StringTranslationTrait::setStringTranslation    public  function    Sets the string translation service to use.

```

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Controller%21ControllerBase.php/class/ControllerBase/8.2.x

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


# Question
Title: How to push values from views attachment to Javascript?
I have a table view with both filters and exposed filters, and attached to it there is another view that uses views\_aggregator\_plus to display a summary of months and different value counts.

I want to have the attachment visualized so I attached ChartJs script to the page view and had another function loop through the attachment html table rows to fetch the data while separating each column into its own array.

This works though I am not sure. It doesn't feel right. Wouldn't it be better if I pushed the values from the view directly to the script rather than have it done by the browser?

I am not sure about how to do it, but I found the values needed in hook\_view\_post\_render under $view-\>style\_plugin-\>rendered\_fields..

How to proceed from there? Or maybe there is an entirely different and better way to achieve the same?

Thanks,

# Answer
It really depends on what you want and what data structure you have.
Normally I would say if you want only chart on the page/views, than create a new views type (Like block, page, etc) and then you can do whatever you want, and you can still attach it to another views. (I think this is it: https://www.drupal.org/docs/8/creating-custom-modules/building-a-views-display-style-plugin-for-drupal-8)
If you just want to show a chart side-by-side with some other data, maybe you need to create a new field (for views), than you can put there the stuff. (https://www.webomelette.com/creating-custom-views-field-drupal-8)
You can also hook in any time to a view, but it will make a mess after a while, however, every time you need to use the `drupalSettings` (Pass variable to drupalSettings) if you want to pass php data to javascript and some custom JS code to glue the ChartJS to the `drupalSettings`.
> 1 votes

---
Tags: views, 8, charts
---


# Question
Title: How do I pass a value to a content type field with a custom submit please
and thank you for your patience in helping me learn

I have created a content type called response (Through Drupal, not in a custom module)

In the content type I have a field called field\_response\_number which is a text field.

When I create new content for the response content type and press submit I want to first submit the form, then run a custom submit afterwards that populates my field\_response\_number based on the result of a custom function.

I can submit and call my custom form submit function fine, but how do I get the total returned from my custom function to populate the field\_response\_number please

So my work flow is

* Create new response content
* Submit results in form and then call custom submit handler
* Get count from DB
* Populate the field\_response\_number with the result
* Display result

Can anyone assist please, as I think I'm almost there

My code is as follows

```
function testmodule_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  foreach (array_keys($form['actions']) as $action) {
    if ( $form_id == 'node_response_form'){
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions'][$action]['#submit'][] = 'testmodule_form_submit';
      }
    }
  }
}

function testmodule_form_submit(array $form, FormStateInterface $form_state){
  // This works
  //$result = testmodule_get_node_count('response');
  //drupal_set_message($result);

  How do I populate my field_response_number here please
}

//This handles incrementing by one I want to use to populate the field_response_number with
function testmodule_get_node_count($content_type) {
  $query = "SELECT COUNT(*) FROM {node} n ".
           "WHERE n.type = :type";
  $total = db_query($query, array(':type' => $content_type))->fetchField();
  return $total;
}

```

Many Thanks for your assistance

# Answer
> 1 votes
I guess you have multiple options.

1. You set the field value in the alter as a #value, this is not editable by the user, not like #default\_value. Then drupal will save it automatically on successful save.
2. You set the field value in the validate callback into the $form\_state variable. Not too elegant, but the drupal will save the value automatically (normally) on successful submit.
3. You create a custom submit (as you did) and then you load your node (D7: `node_load($nid)` D8: `\Drupal::entityTypeManager()->getStorage('node')->load($id);`), set the field value (D7: `$node->field_name[LANGUAGE_NONE][0]['value'] = 'something';` D8: `$node->set('field', 'field_value');`), and then save the node (D7: `node_save($node);`, D8: `$node->save();`).
4. You can use `hook_ENTITY_TYPE_insert()` to update your field and save the entity again. (https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook\_ENTITY\_TYPE\_insert/8.2.x)
5. You can use `hook_ENTITY_TYPE_presave()` you just set the field value here, you don't need to save it. Drupal's next step will the save. (https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook\_ENTITY\_TYPE\_presave/8.2.x)

For D8 a bit more detailed: https://www.heididev.com/how-programmatically-update-fields-value-drupal-8
And also, maybe the entity is already loaded, check this: https://www.drupaleasy.com/quicktips/drupal-8-getting-entity-id-formstate

# Answer
> 0 votes
You just need the following

```
       function testmodule_form_submit(array $form, FormStateInterface $form_state){

              $nid = $form_state->getformObject()->getEntity()->id();

              $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
              $node->set('field_response_number', 'field_value');
              $node->save();
        }

```

---
Tags: 8, nodes
---


# Question
Title: How to use the YML structure of routes to control access to Group Content
I am using the Group module and would like to leverage each Group's permissions in my module's yml files.

I have a `module.permissions.yml` with something like

```
tam_api.group_gid_members_uid:
  path: 'group/{group}/members/{member}'
  defaults: { _controller: '\Drupal\tam_api\Controller\TamApi::getGroupMember' }
  methods: [GET, HEAD]
  requirements:
    _permission: 'access user profiles'
  options:
    _format : ['json']
    _auth: ['oauth2', 'cookie']
    parameters:
      group:
        type: entity:group
      member:
        type: entity:group_content

```

I would like to change `access user profiles` to the `View individual group members` for the given Group?

Can this be done within the Structure of Routes?

# Answer
in `group.services.yml` you'll find access\_check entries like:

```
  access_check.group.permission:
    class: 'Drupal\group\Access\GroupPermissionAccessCheck'
    tags:
      - { name: 'access_check', applies_to: '_group_permission' }
  access_check.group.member:
    class: 'Drupal\group\Access\GroupMemberAccessCheck'
    tags:
      - { name: 'access_check', applies_to: '_group_member' }

```

you can use these in your routes like:

```
tam_api.group_gid_members_uid:
  path: 'group/{group}/members/{member}'
  defaults: { _controller: '\Drupal\tam_api\Controller\TamApi::getGroupMember' }
  methods: [GET, HEAD]
  requirements:
    _group_member: 'TRUE'
# or    _group_permission: 'view group membership content'
  options:
    _format : ['json']
    _auth: ['oauth2']
    parameters:
      group:
        type: entity:group
      member:
        type: entity:group_content

```

Note: the parameter argument must be named `{group}`
> 0 votes

---
Tags: 8, group
---


# Question
Title: How do I do a 'required if other field = x' using the entity validation api?
I have a field in a content entity that is required if another field in it is checked, otherwise it can be blank.

My guess is that I'd need to make some kind of Validation Constraint Plugin for this - is there an easier way to do this, or a module where something like this already exists?

# Answer
That sounds like a job for Drupal's Form API states.

Just add a hook\_form\_alter similar to this, in a custom module:

```
function MYMODULE_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id == 'FORM_ID_TO_ALTER') {
    $form['OPTIONALLY_REQUIRED_FIELD']['#states'] = array(
      'visible' => array(
        ':input[name="CHECKBOX_NAME"]' => array('checked' => 'checked'),
      ),
      'required' => array(
        ':input[name="CHECKBOX_NAME"]' => array('checked' => 'checked'),
      ),
    );
  }
}

```
> 2 votes

# Answer
The form\_alter() solution will only work when you're using a form to save the entity, so I believe that the answer is not the correct one. Here's how you do it with Drupal's Entity Validation API:

Create a constraint and add it to the entity type instead of adding it to a field. Ex:

```
## See hook_entity_type_alter().
function custom_validation_entity_type_alter(array &$entity_types) {
  if (isset($entity_types['node'])) {
    $entity_types['node']->addConstraint('ConstraintName');
  }
}

```

Next, in your `ConstraintValidator::validate()` method, you will get receive the entity as the first argument and you can perform the validation. Here's a code sample from the same article.
> 2 votes

# Answer
Managed to get this working a different way, though Change G's way looks a lot simpler. If you want to go pure entity this way worked for me.

I created an entity validation plugin, based on this blog article (https://www.drupalwatchdog.com/volume-5/issue-2/introducing-drupal-8s-entity-validation-api). The comment module in core modules has a working example of this.

One issue I ran into is that the comment CommentNameContraintValidator class declares a $context class property; I can't figure out how this works for that class, but when creating my own it overrode the $context class property in the ConstraintValidator abstract class you need to extend from. When I removed the $context class property, it correctly used the parent $context class property and worked.

My guess is that it has to do with the ContainerInjectionInterface, which the CommentNameConstraintValidator implements and I didn't. I've stopped digging for now though.
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Wrong User Image Display - Weird Twig Cache?
I'm having a weird issue with incorrect user images being displayed and it seems to be a caching issue or perhaps I am passing the user image incorrectly to my template.

**Problem:** If I login to a different user account I will still see the image from my account. If I rebuild the cache and then refresh the browser, I will receive the correct user image.

Am I building the user image incorrectly?

**mytheme.theme**

```
 <?php
  use Drupal\user\Entity\User;

 function gary_preprocess_block(&$variables) {
  $user = User::load(\Drupal::currentUser()->id());
  $file_uri = $user->get('user_picture')->entity->getFileUri();
  dpm($file_uri); //correct uri
  $styled_image_url = ImageStyle::load("user_pic")->buildUrl($file_uri);
  dpm($styled_image_url); //correct url
  $picture = $styled_image_url;
  $variables['user_pic'] = $picture;
 }

```

**block--gary-account-menu.html.twig**

```
<div class="user-info right-menu" nav-id="{{attributes.id}}">
  <img src="{{ user_pic }}">
</div>

```

The variables in the theme file are correct, but the output from twig when inspected, continues to give the wrong built url to the previous user image (until the cache is flushed).

I doubt I need to delete twig cache or flush caches anytime a user pic is changed or account is switched. Anyone know what I am doing wrong here?

# Answer
When you add data from the current user you also have to add this cache context:

```
$variables['#cache']['contexts'][] = 'user';

```

You can also add the cache dependencies of the user, file and image style. Then modifying one of these entities will be effective immediately, see https://www.drupal.org/docs/8/api/render-api/cacheability-of-render-arrays
> 5 votes

---
Tags: 8, theming, caching
---


# Question
Title: Change autocomplete results based users selected checkbox
I have a drupal 8 site that uses the paragraphs module. In one of the paragraph is a field that contains an autocomplete field. It is already set up to reference a small list of Content Types. For example, "News, Events, Product, Image" are four referenced for the autocomplete.

On another paragraph, it includes this autocomplete but also has a field called "Select a Content Type", it lists out ALL the content types. This is used on the content type. When someone adds a new content they are presented with a list of all the content types as a checkbox and the autocomplete field.

My goal is to only display the selected results from the "select a content type" field onto the autocomplete field.

So when a user selects a "news" / "events" / "Product" / "image" from the "Select a content type" field, the autocomplete only displays nodes of what was selected. If I select news then only news appears when I start entering data. If I select News and events, then both will show. If I select none then a custom message appears.

I have looked around and found how to overwrite getReferenceableEntities but I don't see a way to pass two variables: one from the checkbox field and the autocomplete entered value.

I suspect there will be JS involved to have the form send both checkbox and search value over but I don't know where to begin.

# Answer
> 0 votes
I don't know the exact UX you are going for, but with a mix of conditional fields an entity reference view and some `hook_views_pre_view` I think you can accomplish what you need.

**First** create a new view that has a display that is an Entity Reference. see: How to create a view type of Entity reference display?

* make sure that the Entity reference view filter returns the 4 content types you are interested in.
* Add a contextual filter for the content type

**Second**, configure the node autocomplete field to use the content entity reference view as it's datasource

Note: if you are setting up your form some other way (its not a node form display) you'll have to set this up in code - i don't have an example handy.

Lastly, when the user makes a content type choice store that value somewhere (session, on the content, whatever) so that the choice is accessable via the `hook_views_pre_view` hook.

```
/**
 * Implements hook_views_pre_view().
 *
 * @param ViewExecutable $view
 * @param QueryPluginBase $query
 * @return void
 */
function MY_MODULE_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
  // Get the content type choice from wherever you stored it
  $content_type = "SOME_TYPE";
  // add a filter to the brand view for the supplier's ICs
  if($view->id() == 'MY_CUSTOM_VIEW' && $view->getDisplay()->display['id'] == 'entity_reference_1') {
      $args = [$content_type];
  }
}

```

# Answer
> 2 votes
MYMODULE/src/EntityAutoCompleteMatcher.php:

```
class EntityAutocompleteMatcher extends \Drupal\Core\Entity\EntityAutocompleteMatcher {

  /**
   * Gets matched labels based on a given search string.
   */
  public function getMatches($target_type, $selection_handler, $selection_settings, $string = '') {

    $matches = [];

    $options = [
      'target_type'      => $target_type,
      'handler'          => $selection_handler,
      'handler_settings' => $selection_settings,
    ];

    $handler = $this->selectionManager->getInstance($options);

    if (isset($string)) {
      // Get an array of matching entities.
      $match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
      $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);

      // Loop through the entities and convert them into autocomplete output.
      foreach ($entity_labels as $values) {
        foreach ($values as $entity_id => $label) {

          $entity = \Drupal::entityTypeManager()->getStorage($target_type)->load($entity_id);
          $entity = \Drupal::entityManager()->getTranslationFromContext($entity);

          // Only return bundle types we want.
          if ($entity->bundle() == 'page') {
            $matches[] = ['value' => $label, 'label' => $label];
          }
        }
      }
    }

    return $matches;
  }

}

```

More work would need to be done, but this shows where we can control the returned list of referenced entities.

See:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityAutocompleteMatcher.php/8.8.x

---
Tags: 8, paragraphs
---


# Question
Title: Error with Event Subscriber using getRouteName()
I have a problem with event subscriber. Here is the error:

> The website encountered an unexpected error. Please try again later. Error: Call to a member function getRouteName() on null in Drupal\hello\_world\EventSubscriber\HelloWorldRedirectSubscriber-\>onRequest() (line 58 of modules\custom\src\EventSubscriber\HelloWorldRedirectSubscriber.php).

and my code is:

```
<?php

namespace Drupal\hello_world\EventSubscriber;

use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
//use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Drupal\Core\Routing\currentRouteMatch;
use Drupal\Core\Routing\LocalRedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Drupal\Core\Url;

/**
 * Subscribers to the Kernel Request event and redirects to the
 * homepage when the user has the "non_grata" role.
 */
class HelloWorldRedirectSubscriber implements EventSubscriberInterface {

  /**
   *  @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser; // Store the current user as a class property

  /**
   * HelloWorldRedirectSubscriber constructor.
   *
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   */
  public function __construct(AccountProxyInterface $currentUser) {
    $this->currentUser = $currentUser;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // $events['kernel.request'][] = ['onRequest', 0];
    // più elegante:
    $events[KernelEvents::REQUEST][] = ['onRequest', 0];
    return $events;
  }

  /**
   * Handler for the kernel request event.
   *
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   */

  public function onRequest(GetResponseEvent $event) {
    //$request = $event->getRequest();
    //$path = $request->getPathInfo();
    // if ($path !== '/hello')
    // {
    //   return;
    // } BEST PRACTICE FOR KEEP DYNAMICITY: currentRouteMatch Service
    $route_name = $this->currentRouteMatch->getRouteName();

    // check against the route name (and not path name)
    if ($route_name !== 'hello_world.hello')
    {
      return;
    }

    $roles = $this->currentUser->getRoles();

    if (in_array('inaccettabile', $roles)) {
      // $event->setResponse(new RedirectResponse('/'));
      $url = Url::fromUri('internal:/');
      // LocalRedirectResponse class redirect the user to a local (safe) path
      $event->setResponse(new LocalRedirectResponse($url->toString()));
    }
  }
}

```

I cannot figure out what could be the problem. :\

# Answer
An event subscriber is just a service tagged with `name: event_subscriber` and implemented by a class implementing the `EventSubscriberInterface` interface.

The code you are using is supposed to use a service, but the reference to that service isn't defined as parameter of the class constructor, nor it is initialized in any way.

The `MainContentViewSubscriber` class is an example of event subscriber implementation that uses the *current\_route\_match* service. The key parts of that event subscriber (the *main\_content\_view\_subscriber* service) are:

* The service definition

```
class: Drupal\Core\EventSubscriber\MainContentViewSubscriber
arguments:
  - '@class_resolver'
  - '@current_route_match'
  - '%main_content_renderers%'
tags:
  - { name: event_subscriber }

```
* The constructor of the `MainContentViewSubscriber` class

```
public function __construct(ClassResolverInterface $class_resolver, RouteMatchInterface $route_match, array $main_content_renderers) {
  $this->classResolver = $class_resolver;
  $this->routeMatch = $route_match;
  $this->mainContentRenderers = $main_content_renderers;
}

```

The *current\_route\_match* service is defined as argument of the event subscriber service, and it's defined as parameter of constructor of the event subscriber class.

Your event subscriber service/class needs to do the same. Of course, the other services used from the class I used as example aren't required in your case, so they can be omitted.
> 1 votes

---
Tags: routes, event-subscribers
---


# Question
Title: How do I render a table with a checkbox on each row?
In Drupal 7, I could achieve this using the following code.

```
$form['table'] = array(
  '#type' => 'tableselect',
  '#header' => $header,
  '#options' => $options,
  '#empty' => t('No data')
);

```

This doesn't work anymore in Drupal 8. I just want a page similar to the one at /admin/people. What's the correct way in Drupal 8?

# Answer
The form element type "**tableselect**" is available in Drupal 8

> Description: A table created with a far left column of radios or checkboxes. Build the table headings and columns with the #headers property, and the rows with the #options property.

https://api.drupal.org/api/drupal/developer%21topics%21forms\_api\_reference.html/8#tableselect

More info on "Adding checkboxes to a table" can be found in the handbook documentation here: https://www.drupal.org/node/945102
> 2 votes

# Answer
I spent many hours to figure this out and hope my code will help someone to save time. I am using Drupal 8 version I was working on some same sort of code where I wanted to output a listing of nodes after form submit and the listing should have checkbox in each row. Below is the sample code. Please modify as per your requirements.

```
$form['mytable'] = array(
    '#type' => 'table',
    '#title' => 'List of Nodes',
    '#header' => ["Checkbox","Title","Author"],
);

$nids = \Drupal::entityQuery('node')
        ->condition('status', 1)
        ->execute();
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
$nids = array_keys($nodes);

// Add input fields in table cells.
$i=0;
foreach($nids as $nid)
{

  $node = \Drupal\node\Entity\Node::load($nid);
  $contenttitle=$node->title->value;
  $receivername = $node->getOwner()->getDisplayName();
  \Drupal::entityManager()->getStorage('node')->resetCache(array($nid));

    $form['mytable'][$i][''] = array(
                                        '#type' => 'checkbox',
                                        '#return_value' => $nid,
                                    );

    $form['mytable'][$i]['Title'] = array(
                                        '#type' => 'label',
                                        '#title' => t($contenttitle),
                                    );
    $form['mytable'][$i]['Author'] = array(
                                        '#type' => 'label',
                                        '#title' => t($receivername),
                                    );
    $i++;
}
// Add a submit button that handles the submission of the form.
$form['actions']['submit'] = [
                                '#type' => 'submit',
                                '#value' => $this->t('Submit'),
                            ];
return $form;

```

below is the output example
> 1 votes

# Answer
You may be missing that the keys of header and respective keys of option should be same. Either both indexed or both associative. I face same issue having index key in header and associative key in option which gives empty table. https://www.drupal.org/node/945102 code will work
> 0 votes

---
Tags: theming, 8
---


# Question
Title: How to do an EntityQuery on a custom User field?
I'm having trouble figuring out how to use the EntityQuery on custom field values. As an example I have a custom field under the User bundle that stores the country in which the user lives. There are three options: US, Canada and Mexico. I'd like to use the EntityQuery to directly query the 'field\_country' to get a count of how many live in one country and get their uids. Here is an export from the database for this field:

The closest I've gotten is the code snippet below. This however is not working and I'm not sure where to go from here.

```
$results = \Drupal::entityQuery('user')
      ->condition('field_country', 'Canada')
      ->execute();

```

Does anybody know? Does the entityquery give me the ability to look specific columns in a field? Thanks!

P.S. I know I could do this with a database query but I'd prefer to do it the Drupal way.

# Answer
I think you might be missing a line:

```
$ids = \Drupal::entityQuery('user')
  ->condition('field_country', 'Canada')
  ->execute(); // This returns the user ids

// Load the users
$users = User::loadMultiple($ids);
foreach ($users as $uid => $user) {
    // $user contains the $user entity
}

```

More examples are located on the docs page.
> 1 votes

---
Tags: 8
---


title: node--front.html

text:
# Question
Title: node--front.html
I'm trying to isolate the node template for just the front page of Drupal 8. In Drupal 7 I could create a template node--front.html but this doesn't seem to work in Drupal 8, what's the best way to just target nodes on the front page. If I use:

```
{% if node.isPromoted() and not node.isSticky() %}

```

it effects the node on it's single page as well.

Update: I'm using Bartik as a sub theme

# Answer
You can do the following in your .theme file:

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

```

And then in your node--page--full.html.twig (name of twig file depending on content type and view mode) use:

```
{% if is_front %}
// frontpage stuff here
{% else %}
// other stuff here
{% endif %}

```
> 4 votes

# Answer
I think what you want to use is not rely on promoted/sticky but a given view mode. node--$viewmode.html.twig is available as a default template suggestion.

By default, the view mode used on the frontpage is teaser.

You probably want to use that in other places too and not all should look like the frontpage. Drupal 8 now has a UI built-in to create view modes and corresponding display configurations for the fields. You can then select which view module should be used in each view, entity reference and when you display nodes through the API.

Coupling layout/design of nodes to view modes and not e.g. a specific view or other attribute makes them re-usable. You can have other views that display them in the same way. Or not.
> 1 votes

# Answer
Try with **node--promoted.html.twig**.

From D8 documentation node.html.twig.

> **node--promoted** : Appears on nodes promoted to the front page.
> 0 votes

---
Tags: 8, theming
---


# Question
Title: Use hook to get the domain configuration from language
We have enabled English, Spanish, and French on our site. On *Regional and language \>\> Languages detection* we selected *URL* for *Content language detection \>\> Detection Method*. For *Part of the URL that determines language*, we selected *Domain*. We then set the following domains.

* English: example.com
* Spanish: es.example.com
* French: fr.example.com

How can we programmatically obtain the domain associated to each language? What code should we use in a preprocess function? Using the following code, we obtained the list of the language, but we are far from getting the domain that has been associated with each language.

```
function mymodule_preprocess_html(&$variables) {
  // to get all enabled languages
  $languages = \Drupal::languageManager()->getLanguages();

  // Did not find method to retrieve the domain configuration.
  foreach($languages as $key => $value) {
    ksm($languages[$key]);
    //stuck here on how to get domain configuration per language.
  }
}

```

# Answer
The domain associated with each language is stored as configuration. Using the following code, `$prefix` will contain the prefix, and `$domain` the domain used.

```
  $config = \Drupal::configFactory()->get('language.negotiation');
  $languages = \Drupal::languageManager()->getLanguages();
  $prefixes = $config->get('url.prefixes');
  $domains = $config->get('url.domains');
  foreach ($languages as $langcode => $language) {
    $prefix = $prefixes[$langcode];
    $domain = $domains[$langcode];
  }

```

I wrote the code basing on `NegotiationUrlForm::buildForm()`, which is the form builder for the form that sets the negotiation URL for each language.
> 1 votes

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


title: Migration Plus entity_lookup fails

text:
# Question
Title: Migration Plus entity_lookup fails
Drupal version: **8.7.1**. Used modules:

* Migrate
* Migrate Plus
* Migrate Tools
* Migrate Spreadsheet

I'm trying to generate a taxonomy term if this does not already exist. the migration file:

```
...
source:
  plugin: spreadsheet
  columns:
   ...
   - 'Functie'
   ...
process:
  ...
  field_function:
    plugin: entity_generate
    source: 'Functie'
    value_key: name
    ignore_case: true
    bundle: function
    entity_type: taxonomy_term
  ...

```

The taxonomy bundle name is **function** and the column in the spreadsheet containing the values is **'Functie'**. However, I'm getting the following error:

> \[error\] Error: Call to a member function getConfig() on null in Drupal\migrate\_plus\Plugin\migrate\process\EntityLookup-\>determineLookupProperties() (line 217 of /var/www/html/web/modules/contrib/migrate\_plus/src/Plugin/migrate/process/EntityLookup.php)
>
> /var/www/html/web/modules/contrib/migrate\_plus/src/Plugin/migrate/process/EntityLookup.php(182): Drupal\migrate\_plus\Plugin\migrate\process\EntityLookup-\>determineLookupProperties('field\_function')
>
> /var/www/html/web/modules/contrib/migrate\_plus/src/Plugin/migrate/process/EntityGenerate.php(116): Drupal\migrate\_plus\Plugin\migrate\process\EntityLookup-\>transform('Medewerker', Object(Drupal\migrate\_tools\MigrateExecutable), Object(Drupal\migrate\Row), 'field\_function')
>
> /var/www/html/web/core/modules/migrate/src/MigrateExecutable.php(394): Drupal\migrate\_plus\Plugin\migrate\process\EntityGenerate-\>transform('Medewerker', Object(Drupal\migrate\_tools\MigrateExecutable), Object(Drupal\migrate\Row), 'field\_function')
>
> /var/www/html/web/core/modules/migrate/src/MigrateExecutable.php(203): Drupal\migrate\MigrateExecutable-\>processRow(Object(Drupal\migrate\Row))
>
> /var/www/html/vendor/drush/drush/includes/drush.inc(223): Drupal\migrate\MigrateExecutable-\>import()
>
> /var/www/html/vendor/drush/drush/includes/drush.inc(214): drush\_call\_user\_func\_array(Array, Array)
>
> /var/www/html/web/modules/contrib/migrate\_tools/src/Commands/MigrateToolsCommands.php(766): drush\_op(Array)
>
> \[internal function\]: Drupal\migrate\_tools\Commands\MigrateToolsCommands-\>executeMigration(Object(Drupal\migrate\Plugin\Migration), 'profiles', Array)
>
> /var/www/html/web/modules/contrib/migrate\_tools/src/Commands/MigrateToolsCommands.php(321): array\_walk(Array, Array, Array)
>
> \[internal function\]: Drupal\migrate\_tools\Commands\MigrateToolsCommands-\>import('profiles', Array)
>
> /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call\_user\_func\_array(Array, Array)
>
> /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor-\>runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
>
> /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(178): Consolidation\AnnotatedCommand\CommandProcessor-\>validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
>
> /var/www/html/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(302): Consolidation\AnnotatedCommand\CommandProcessor-\>process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
>
> /var/www/html/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand-\>execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
>
> /var/www/html/vendor/symfony/console/Application.php(978): Symfony\Component\Console\Command\Command-\>run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
>
> /var/www/html/vendor/symfony/console/Application.php(255): Symfony\Component\Console\Application-\>doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
>
> /var/www/html/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application-\>doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
>
> /var/www/html/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application-\>run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
>
> /var/www/html/vendor/drush/drush/src/Runtime/Runtime.php(49): Drush\Runtime\Runtime-\>doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
>
> /var/www/html/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime-\>run(Array)
>
> /var/www/html/vendor/drush/drush/includes/preflight.inc(18): require('/var/www/html/v...')
>
> phar:///usr/local/bin/drush/bin/drush.php(141): drush\_main() /usr/local/bin/drush(10): require('phar:///usr/loc...')

If anyone could point out what's going wrong, by all means, enlighten me because I have no clue what's going on, the configuration seems right to me.

# Answer
> 0 votes
You need to explode your source - I used a comma in this case. You then need to generate against the specific vid you want to import into:

Try something like this:

```
fields:
-
  name: name_i_gave_this_field
  label: 'Taxonomy Term I want to Import'
  selector: termname
process:
  field_my_entity_reference_to_taxonomy:
 -
  plugin: explode
  source: name_i_gave_this_field
  delimiter: ','
-
  plugin: entity_generate
  lookupBundleKey: vid
  lookupBundle: my_vocabulary_name

```

Make sure that your Taxonomy Term reference field allows you to create content.

---
Tags: migrations
---


title: How do I override the mail system?

text:
# Question
Title: How do I override the mail system?
In my application, all mails aren't sent via the Drupal default mail system or SMTP. We have a third-party API which sends all emails. So, whenever the *plugin.manager.mail* service is called, the class I define in a custom module should be used.

How can I achieve this?

# Answer
> 1 votes
You can achieve this by overriding the service defined from Drupal core. Altering existing services, providing dynamic services describes the code to use.

In your case, the code should be similar to the following one.

```
namespace Drupal\my_module;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;

// @note: You only need Reference, if you want to change service arguments.
use Symfony\Component\DependencyInjection\Reference;

/**
 * Modifies the mail provider service.
 */
class MyModuleServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container) {
    $definition = $container->getDefinition('plugin.manager.mail');
    $definition->setClass('Drupal\MY_MODULE\MyMailProvider');
  }
}

```

---
Tags: 8, emails
---


# Question
Title: setHandler into views_pre_render OR count results in views_pre_render
I have a view that needs to have a custom views footer only if it get results. Otherwise the view needs to not be displayed

I can set up a view footer by using `$view->setHandler` with `hook_views_pre_render` and I can count results with `hook_views_pre_render`

How can I achieve both with a single function? Using `$view->setHandler` with hook\_views\_pre\_render does not attach the footer

# Answer
> 1 votes
Found an alternative solution, by using `hook_views_pre_render` and `$view->attachment_after`

```
$view->attachment_after = array('#markup' => '<a href="/" title="Title" class="button">Button</a>');

```

---
Tags: views, 8
---


title: How do I get comments to be indexed?

text:
# Question
Title: How do I get comments to be indexed?
I'm not sure if it's actually doing this; I can't see any options for comment fields in the configuration. How can I check? Does it say explicitly somewhere?

# Answer
> 0 votes
Apachesolr Comments

> By default the apachesolr module index comments attached to the node. So you can not search comments directly. This module separates comments from the nodes and allows you to search them directly.

**UPDATE:**

For **search api** apply this patch

```
diff --git a/modules/callbacks.inc b/modules/callbacks.inc
index dca9e1d..e12be6a 100644
--- a/modules/callbacks.inc
+++ b/modules/callbacks.inc
@@ -80,6 +80,12 @@ function entity_metadata_comment_get_node_properties($node, array $options, $nam

     case 'comment_count_new':
       return comment_num_new($node->nid);
+
+    case 'comments':
+      $select = db_select('comment', 'c')
+        ->fields('c', array('cid'))
+        ->condition('c.nid', $node->nid);
+      return array_keys($select->execute()->fetchAllKeyed(0, 0));
   }
 }

diff --git a/modules/comment.info.inc b/modules/comment.info.inc
index 4321b4c..a9d7fe9 100644
--- a/modules/comment.info.inc
+++ b/modules/comment.info.inc
@@ -136,6 +136,13 @@ function entity_metadata_comment_entity_property_info_alter(&$info) {
     'setter permission' => 'administer comments',
     'type' => 'integer',
   );
+  $properties['comments'] = array(
+    'label' => t("Comments"),
+    'type' => 'list<comment>',
+    'description' => t("The node comments."),
+    'getter callback' => 'entity_metadata_comment_get_node_properties',
+    'computed' => TRUE,
+  );
   $properties['comment_count'] = array(
     'label' => t("Comment count"),
     'description' => t("The number of comments posted on a node."),

```

Taken from the source https://drupal.org/node/1414688#comment-7037540 and also worth looking at this http://blog.merge.nl/shorts/search-api-indexing-nodes-including-comments

# Answer
> 0 votes
For Drupal 8 I had to write custom properties to get my comments into the index.

I followed this documentation https://www.drupal.org/docs/8/modules/search-api/developer-documentation/create-custom-fields-using-a-custom-processor

And than queried my Entity in addFieldValues() Method.

Like

```
$object = $item->getOriginalObject()->getValue();
$comment_ids = $this->entityTypeManager()->getStorage('comment')->getQuery()
 ->condition('comment_type', '<comment_type>')
 ->condition('entity_id', $object->id())
 ->execute();
$comments = $this->getEntityTypeManager()
  ->getStorage('comment')
  ->loadMultiple($comment_ids);
$fields = $this->getFieldsHelper()
  ->filterForPropertyPath($item->getFields(), NULL, '<my_property_definition>');
foreach ($fields as $field) {
  /** @var \Drupal\comment\Entity\Comment $answer */
  foreach ($comments as $comment) {
    $field->addValue($comment->comment_body->value);
  }
}

```

---
Tags: 8, search
---


# Question
Title: How can I provide an autocomplete filter for tags in a Search API view?
I'm working to create a Search API view. I have an exposed filter that's a fulltext search filter. I'd like to expose another filter that works similar to the exposed entity reference, which allows users to reference multiple tags, separated by commas; the field will then autocomplete the entered value.

Is there a way to achieve this using the Search API Views and the Search API Autocomplete modules? As far as I can see, there isn't a way to autocomplete multiple words/phrases, instead of just the first word/phrase.

# Answer
> 3 votes
Add the datasource (entity reference) as a exposed filter.

Check the "allow multiple selections".

Now, the user can add comma seperated tags (with autocompletion):

Used search api 8.x-1.13 on drupal 8.6.16

# Answer
> 1 votes
I would enable the Facet API module first of all, which will give you the facet interaction with Search API.

I would then point you towards a good, simple tutorial at https://medium.com/@swappyp20/creating-a-faceted-search-view-in-drupal-8-using-the-search-api-modules-2b2604ad37f4

Hopefully you should be able to sort it out from there.

# Answer
> 1 votes
In **Filter criteria** you need to Add the tag (Taxonomy) fields to extract right values from views. Also remember to select **expose this filter to visitors** and **selection type - Autocomplete and check Allow Multiple Selections**. You can see attached screenshots below.

I hope these will help.

---
Tags: 8, search
---


# Question
Title: Add product - price and sku field missing
When I want to add a product, the field price and SKU are missing.

Running on Drupal 8.7.1 on MAMP on macOS and PHP 7.1.23

Any idea?

# Answer
A variations tab, which is skus and prices. A product is paired to 1 or more variations.

Answer provided by smccabe from commerce slack.
> 0 votes

---
Tags: commerce
---


title: Set a multiple field value on a form

text:
# Question
Title: Set a multiple field value on a form
I use this field definition in the entity "message" class.

```
$fields['fichier'] = BaseFieldDefinition::create('file')
  ->setLabel(t('Fichier attaché'))
  ->setSetting('file_directory', 'messagerie/fichier') // dossier d'upload
  ->setSetting('max_filesize', '10MB') // taille max du fichier
  ->setSetting('file_extensions', 'pdf doc txt xls zip rar mp3 mp4 csv jpeg jpg ppt') // extensions autorisées, à séparer par un espace
  ->setSetting('description_field', FALSE) // si on veut activer un champ « description »
  ->setDisplayOptions('form', [
    'label' => 'hidden',
    'type' => 'file_generic',
    'weight' => 0,
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE);

```

In the associated form I need to set this field a multiple field (I can't find a way to set cardinality in the definition field). How can I do that ?

# Answer
> 3 votes
You can use `BaseFieldDefinition::setCardinality()` for that, e.g.:

```
$fields['fichier'] = BaseFieldDefinition::create('file')
  ->setLabel(t('Fichier attaché'))
  ->setSetting('file_directory', 'messagerie/fichier') // dossier d'upload
  ->setSetting('max_filesize', '10MB') // taille max du fichier
  ->setSetting('file_extensions', 'pdf doc txt xls zip rar mp3 mp4 csv jpeg jpg ppt') // extensions autorisées, à séparer par un espace
  ->setSetting('description_field', FALSE) // si on veut activer un champ « description »
  ->setDisplayOptions('form', [
    'label' => 'hidden',
    'type' => 'file_generic',
    'weight' => 0,
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE)
  ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);

```

# Answer
> 1 votes
Set the cardinality to unlimited:

```
  ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)

```

---
Tags: 8, forms
---


# Question
Title: REST Export Views and images alternative text
I have a simple REST export View. The View format is set to *"Show: Entity"*.

The content type I am exporting contains a standard image field. My image field settings is set to *"Enable Alt field"* and *"Alt field is required"*.

Therefore all my nodes that have an image, have an image alternate text (Alt).

In the JSON that my view outputs, there is nowhere that I can find the value of the image alternate text.

For each image, I get the filesize, the filename, the filemime, the uri, etc. etc. but no alt text.

Any idea why? And how could I retrieve it? (other than by replacing the image alt text by a separate field...)

# Answer
## Views Format: Fields

I don't think there is a special separate field in Views UI for the Alt field. Alt text is part of the Image field data, stored with the content entity (not the file).

So what you do is add *another* Image field to your Views, but configure it this way:

1. **Rewrite results**
2. **Override the output of this field with custom text**
3. Check `Replacement patterns` below to find your Alt token
4. Enter the replacement pattern into the above Text field **`{{ field_image__alt }}`**

Now you have the image Alt text showing as the field output instead of the actual image.

---

Edit: The above can only help if you're using `Fields` under your `Format` settings in Views.

## Views Format: Content/Entity

When showing full entities in Views you need to use Content Type/Entity View modes (not to be confused with anything Views related). On your CT add a new View mode on the `Manage display` page, or adjust the existing one you're using in your Views Format settings.

### Custom Image field formatter

This is where you *should* be able to adjust your Image field Formatter, but unfortunately the Image field doesn't seem to come with the "Alt" text formatter.

Other than creating the custom Formatter yourself you can check out this Issues and module:
> 5 votes

---
Tags: views, nodes, 8
---


# Question
Title: How to use view's relationships to pull user entity reference data?
I created 2 new user fields for the user (object/entity) on my D7 site. Using views, I can select 'content' or 'user' for querying data. When I use views to query the 'user', the 2 new fields come up just fine. However, when I select 'content', the 2 new fields are not there. This makes sense to me since the 2 new fields are tied to the user entity.

For my purposes, I need both content AND user data. The strange or weird thing is, when I select 'content' for my base and use relationships to find and pull user entity fields, SOME old custom created fields already tied to the User Entity is present and I can select them, BUT my 2 new fields are not.

I tried clearing caches and making sure I had active content with the 2 new fields enabled. So why can I find in relationships, entity references to old custom fields, but not my new fields I created?

It feels like a catch 22. If I select user, I have my new fields, but not the content, and vice versa.

# Answer
> 0 votes
There is a Relationship that introduces "backwards" Entity reference info into the Views.

In Drupal 7 that is called something like this (you can find this in the list of Relationships in your Content Views under the `Entity Reference` Category):

> **Entity Reference: Referencing entity**
> A bridge to the User entity that is referencing Content via field\_\[myERfield\]

After you have that you will be able to add the `User: Name` field, it will automatically use the above Relationship, and it will show which user referenced that particular node, for your each Views row.

---

In Drupal 8 the Relationship is called

> **User using field\_\[myERfield\]**
> Relate each User with a field\_\[myERfield\] set to the content.

The procedure is the same, you can now add Fields or Filters relating to User fields/data, if they're set to use the Relationship the user shown will be the one referencing the content of that Views row.

---
Tags: 7, views, users
---


# Question
Title: Extending a base template file such as field.html.twig renders no results?
So I have a custom content entity that has the typical attributes. Name, Author, Creation Date, ect. In the 'view' tab of this content entity, it displays said name, author, ect.

When I hover over the name or title, it will display that this particular area uses field.html.twig as its default base template. I created my own custom template that extends the base template, and wanted to edit it so it would look different.

However, doing so renders the field invisible. I tried copying the base template and pasting it into my custom twig template, however the field is still invisible. Only when I delete my custom template does it revert back to the original base template and display the field.

Here is where I am confused. My custom twig template is taking precedence, it shows that in the debug info, but I am copying the field.html.twig code into my custom code before I start editing. Why then is the fields disappearing off the page or not rendering considering that I am using the exact same coding?

Just for reference, this is a custom module template and not a themeing template I am working with.

Here is a picture of what the field looks like when its displaying properly, otherwise it vanishs.

My hook theme code for this particular field:

```
  $theme['field__parent_task'] = [
    'render element' => 'content',
    'variables' => ['content' => NULL],
    'file' => 'task.page.inc',
  ];

```

I don't know what to put for the key names in the theme array, so I just copy and pasted from another one that was already there.

# Answer
> 2 votes
If you want to only override the field template.

Try with with the following.

1. Implement `hook_theme` like the following no needs for `variables` and `file` keys.

```

  /**
     * Implements hook_theme().
     */
    function myModule_theme($existing, $type, $theme, $path) {
      return [
        'field__parent_task' => [
          'template' => 'field--parent-task',
          'base hook' => 'field',
        ],
      ];
    }

```
2. Create `templates` folder in your module root.
3. Create `field--parent-task.html.twig` inside your templates folder.
4. Copy and the paste the base template code into your template file.
5. Clear the cache.

---
Tags: 8, theming, debugging
---


title: How to reference without tagging?

text:
# Question
Title: How to reference without tagging?
My problem is a priori simple: I would like in a node to refer to the terms of taxonomy that concerns this node, but without "tag" this node, ie: without the node is referenced in the list corresponding to the terms of selected taxonomy.

Indeed, currently, I use an "entity reference" field for "taxonomy terms", and when I refer to a taxonomy term, the node is automatically tagged and appears in the list of nodes related to these terms of taxonomy.

Now, in other words, I would like to "quote", "link", but not "tag".

Example:

I have a node: ***"Ernest Hemingway"***, I would like to reference in this node the term taxonomy ***"The books of Ernest Hemingway"***, which allows to link / access to all the books of this writer, but for all that, I do not wish the node **"Ernest Hemingway"** appears in the list **"The books of Ernest Hemingway"**, which is a list of books.

It sounds simple, but I do not find how!

Do you know how to do it?

# Answer
The pages that list content related to specific Taxonomy terms are created through views called `Taxonomy term` (usually at `/admin/structure/views/view/taxonomy_term`).

You can control what those pages output by editing that Views. I usually disable that original View and Duplicate it to work on overrides, so I can always refer back to the original if something goes wrong.

Which exact steps to take to exclude depends on your particular needs.

If there aren't that many nodes that need to be excluded you can just add the filter for node ID, use the `Is not equal to` Operator and enter the ID of the node that is not supposed to be found on Taxonomy term pages.

This solution will exclude that node from **all** the terms pages. If that node is referencing more than one term, it will **not** display on any of the terms pages.

To exclude more than one node you can add as many ID filters as you need, or more conveniently use the `Regular expression`, see this answer for more info: How to exclude multiple nodes based on their ID in taxonomy term view?

If you need to exclude your list of nodes from terms from one Vocabulary, but not from all the other Vocabularies, you'd have to modify the Contextual filter settings in those Views and configure separate ones for that special vocabulary and then the other Contextual for all the rest. You'd have to use the OR instead of AND (there's a module for that). This requires a bit more experience with Views configuration.

---

Another way may be to create a new field on your content, it probably makes the most sense to make it of type Boolean, that only have true/false states, and set those special nodes to True for that field (hide that field on Manage display, this is just your internal mark). Then in Taxonomy Views exclude the nodes that have that field set to True.

The advantage of this approach is that you control that when creating/editing nodes, while in the above solution you have to go edit Views each time.

Anything more than that you'd have to think about your site structure and change filters in Views to match that logic.
> 0 votes

---
Tags: 8
---


# Question
Title: What search tool to use for data living outside of Drupal on the external API?
I have an external API with Doctors data. Every doctor item will have:

* Title
* Location ( geolocation address )
* Opening hours
* Short description
* Area of expertise
* Price range

On my Drupal 8 website, I want to be able to utilize a search of Doctors data that will have filters ( location proximity and zip, some checkboxes, and dropdowns ).

I also want to have a google map view with these filters.

I'm looking for the best approach in the selection of search tools. My current options are:

* Search API ( i used it before but never with external data )
* Elastic Search ( still not sure about implementation )
* Introducing Feeds to import data into Drupal and then use Search API
* Something else?

I'm open to any suggestion in terms of implementation and tools selection.

# Answer
> 1 votes
If you have access to the external database credentials, there is a module called views database connector that gives you access to an external database in views.

I think it might be possible to configure a view to search through an external database with that module.

UPDATE: Otherwise you might consider creating a rest export view, there are a ton of guides on how to do that, here is one.

Good luck.

---
Tags: views, search
---


title: How do I prevent anonymous sessions?

text:
# Question
Title: How do I prevent anonymous sessions?
I'm working on a site hosted on Acquia and we're using Varnish and Akamai. We don't want anonymous sessions from being saved in the db, as it breaks the caching. I've made a few tweaks, and I'm trying to track down where the sessions are coming from. We're using simplesamlphp\_auth for admin logins using Okta and LoginRadius module from /user/login, so it's not a default Drupal 8 installation in regards to login and sessions.

I'm trying to track down where the anonymous sessions are coming from. But I was wondering if there's a way outside of fixing either of these modules to force Drupal 8 to NOT save anonymous sessions to the database. Is there a hook or event that I could use to prevent the anonymous sessions from being saved?

If so, what are the implications? I guess lost cookies that some contrib module may be trying to set?

I'm seeing sessions like this appear:

```
*************************** 333. row ***************************
      uid: 0
      sid: _oo8QqyuF4tMOIIWr-uCOj8aqsknzV1WWkmf0bHzlmQ
 hostname: 23.220.148.70
timestamp: 1557934618
  session: messages|a:1:{s:7:"warning";a:1:{i:0;O:48:"Drupal\Core\StringTranslation\TranslatableMarkup":3:{s:9:" * string";s:57:"Your session was deliberately ended from another session.";s:12:" * arguments";a:0:{}s:10:" * options";a:0:{}}}}
*************************** 334. row ***************************

```

or this:

```
          uid: 0
      sid: _VmVWTDsbgQYOcZFxN15Z5j-s4jt4YmsjSZGggphAIM
 hostname: 72.247.190.102
timestamp: 1557928795
  session: _symfony_flashes|a:1:{s:5:"error";a:1:{i:0;s:49:"Access denied. You must log in to view this page.";}}_sf2_meta|a:3:{s:1:"u";i:1557928795;s:1:"c";i:1557928795;s:1:"l";s:7:"2000000";}
*************************** 335. row ***************************

```

I think part of the issue may be that messages aren't getting displayed to the user on cached pages, so the anonymous sessions aren't being emptied of their \_symfony\_flashes

The most concerning one dumps a ton of user data, I think this from loginradius:

```
*************************** 332. row ***************************
      uid: 0
      sid: _2PXluVM2rAY29hE-HFkNQQ8_nPdP4QeU4Y3PoX40ws
 hostname: 184.25.157.170
timestamp: 1557870161
  session: _sf2_attributes|a:5:{s:12:"access_token";s:36:"fb98d952-f1a2-4ba3-820e-2db2c7313008";s:17:"user_profile_data";O:8:"stdClass":146: etc. (I'm not going to post the data here)

```

# Answer
> 3 votes
Find out which modules set session data by dumping these variables for anonymous requests:

```
var_dump(\Drupal::request()->getSession()->all());
var_dump($_SESSION);

```

You can ignore the symfony metadata starting with \_symfony or \_sf2.

Then search the code base for session set() commands setting this data. You can then either change this code or remove the session data in your own code with remove().

When all session data is removed the session will be destroyed automatically at the end of the request. The metadata doesn't count.

A special case is the symfony flash bag. Data stored here is normally only kept between two requests. Ideally the first one is a redirect so the second one happens immediately. Drupal uses the flash bag for system messages. The messages are displayed and removed by the status messages block, which is enabled by default. The messages block is uncacheable and re-built on each request, because of how the caching system handles requests containing a session.

# Answer
> 0 votes
In this article from Varnish explain how to remove the anonymous user sessions: https://www.varnish-software.com/wiki/content/tutorials/drupal/drupal\_step\_by\_step.html#cookies

If Varnish works fine, Drupal should not know that there are anonymous users around it.

---
Tags: 8
---


title: Drupal console set site:mode

text:
# Question
Title: Drupal console set site:mode
I installed a site use composer with command

```
composer create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction

```

I would like to set site mode to dev. If site install drupal from drupal.org, I can run command

```
drupal smo dev

```

But with composer I run

```
vender/bin/drupal list

```

and don't saw any command about setting site mode. How can do that with Drupal site install by composer. I would like to run command line, **don't want config file service.yml**.

**Note: I ready run composer update.**

# Answer
> 1 votes
The correct command for setting site in development mode is

```
drupal site:mode dev

```

Check here for more details - Debugging compiled Twig templates

# Answer
> 1 votes
drupal site:mode dev is disabled in current version (RC 17) of Drupal Console.

See here: https://github.com/hechoendrupal/drupal-console/issues/3079

and in code: https://github.com/hechoendrupal/drupal-console/blob/master/config/services/drupal-console/site.yml

# Answer
> 0 votes
I recently ran into this issue. The error message I got was:

```
[ERROR] Command "site:mode", is not a valid command name.

```

My Drupal Console version was 1.8.0.

I had to specify the URI parameter to get it to work like this as I did not have a default site:

```
drupal --uri="example.org" site:mode dev

```

---
Tags: console
---