# Question
Title: How to tell if a field has renderable content before printing HTML around it?
I have a half dozen reference fields on a content type that sits at the bottom of a page under a heading of "Related" and some markup structure. I was checking `if node.field_name is not empty, ...` in twig before entering and printing "Related" and then each individual field, but in cases where the referenced entities are unpublished, this results in just "Related" and nothing else.

How can I figure out ahead of time if the field I am about to render has actual accessible content to show the user? is `content.field_name|render|striptags|trim` still the only way?

```
<div class="info-grid {% if horizontal %}info-grid--horizontal{% endif %}">
    <h2 class="info-grid__title">Related</h2>
    <div class="info-grid__grid">
      {% if node.field_topics is not empty  %}
        {{ content.field_topics }}
      {% endif %}

      {% if node.field_programs is not empty  %}
        {{ content.field_programs }}
      {% endif %}

      {% if node.field_working_groups is not empty  %}
        {{ content.field_working_groups }}
      {% endif %}

      {% if node.field_projects is not empty  %}
        {{ content.field_projects }}
      {% endif %}

      {% if node.field_papers is not empty  %}
        {{ content.field_papers }}
      {% endif %}

      {% if node.field_datasets is not empty  %}
        {{ content.field_datasets }}
      {% endif %}
    </div>
  </div>

```

Edit: updating with Hudri suggestion, it still prints the h2 of Related:

```
{% set display_related = false %}

{% if not (node.field_programs.isEmpty == true) and content.field_programs is defined %}
  {% set display_related = true %}
{% endif %}

{% if display_related %}
  <div class="info-grid {% if horizontal %}info-grid--horizontal{% endif %}">
...

```

# Answer
The answers so far are only valid for non reference fields. A reference field is different, because the referenced entities can have different access results than the parent entity. The rendered field can be empty although the field in the node object is not. As explained in How do I hide an empty field if my custom field formatter removes all items? there are two unambiguous empty conditions for the output of the field formatter in `{{ content.field_name }}`:

1. Check the first field delta, which always starts with `0`:

```
{% set display_related = content.field_name.0 is defined %}

```
2. or check whether the field formatter could find any renderable children and has added the field wrapper:

```
{% set display_related = content.field_name['#theme'] is defined %}

```

For a reference field it is important to render `content.field_name` even if the result is negative, because it contains the cacheable metadata of the access checks. When for example a referenced node is published, the parent node needs to be invalidated and rerendered.

So checking `content.field_name|render|striptags|trim` is not so bad at all, because this check renders the field content and if the result is negative you don't have to render the field again, because the metadata bubbled up already.

---

**Field Groups**

For halve a dozen fields you could use Field Groups. Place all reference fields in a group "Related" and display the header in the field group template. If the field group template doesn't hide automatically you can check with `striptags` as before. You get the entire rendered result of all fields in the variable `children`.

Although I would prefer to check the specific content you expect to be inside of the field group and so ignore labels or other things that may be added later. The already rendered field group content is in a markup object and you need to render it again in twig, so you can check it casted as a string. For example whether it contains a linked node:

*field-group-html-element.html.twig:*

```
{% set display_related = '<a href' in children|render %}

```
> 7 votes

# Answer
> Is content.field\_name|render|striptags|trim still the only way?

That's a way a lot of people choose to do this check, if you're doing it purely in twig. But I would argue it's not the **only way** to achieve this.

What you can also do is check the `node` (or paragraph, term etc any Drupal fieldable content entity) object's field instead of the `content` array. So instead of `{% if content.field_name...` you do `{% if not node.field_name.isEmpty %}` which also works iirc...

What's also possible is to just use a PHP preprocessor to set a `count` or some such variable, which counted the number of values in the node, and you can just `{% if not count %}`. Hope this helps.
> 0 votes

# Answer
My own bullet-proof version that worked even in the most weirdest edge cases:

* it works for all field types
* it checks if the field exists
* it checks if the field is not empty
* it checks if the field is not hidden in display mode

```
{% if not (node.field_whatever.isEmpty == true) and content.field_whatever is defined %}
  <div class="whatever_markup">
    {{ content.field_whatever }}
  </div>
{% endif %}

```

Replace `node` and you can drop it into *any* entity template.
> 0 votes

---
Tags: 8, theming
---


title: Place a block inside a twig template

text:
# Question
Title: Place a block inside a twig template
I've got a custom content type 'professor', and a 'node--professor.html.twig' in my theme (derived from 'classy') to override the standard markup. The designer wants me to put a list (a view?) of the professor's 'courses' (which is another content type) between the professor's contacts and biography, basically, INSIDE the 'node--professor.twig.html'. Is there a Drupal-way to do it?

And, by the way, what is the main difference between a page with a custom content type and a custom content entity? Do I need to write a module and a content entity, or custom content type can do the trick?

# Answer
Download and enable **Twig tweak** module:

> Twig Tweak module provides a Twig extension with some useful functions and filters that can improve developer experience.

And then on your twig template put:

```
<dd>{{ drupal_view('view_name', 'block_1') }}</dd>
<dd>{{ drupal_block('block_id') }}</dd>

```

---

**Themers Little Helper**

> Some of the Filters and functions, backported from TFD7 theme engine and other things that can help a themer getting stuff done without to much hassle :)

```
{{ drupal_block(block_delta) }}

```

---

**Bamboo Twig**

> The Bamboo Twig module provides some Twig extensions with some useful functions and filters aimed to improve the development experience.
>
> Bamboo Twig has a lot of advantages and brings a lot of new features to the Twig landscape of Drupal 8. It boosts performance by using lazy loading, improves the code quality with automated workflow. It also includes automated unit and kernel tests to ensure stability.

```
{# Render the `system_powered_by_block` block #}
{{ bamboo_render_block('system_powered_by_block') }}

```
> 16 votes

# Answer
You can create an instance of a block plugin in a custom module in the preprocess hook for your professor content type:

```
function mymodule_preprocess_node__professor(&$vars) {
  $vars['courses'] = \Drupal::service('plugin.manager.block')
    ->createInstance('professor_courses')
    ->build();
}

```

I like the simplicity of this approach This creates an instance of a custom block class as a variable in your node template.

You could then output it in node--professor.html.twig like this:

```
{{ courses }}

```

If you have a view that you have created that creates a block, you'd have to load the existing instance, which is slightly different.

```
$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
$vars['courses'] = $render;

```

There's another thread that goes into great detail about loading blocks programmatically.
> 2 votes

# Answer
This could be an aside, but for some people it might be of use.

If your list is a view \[block\], it's worth considering the EVA module, which if memory serves can be moved about between fields in the manage display UI. Not sure how it would fair in the twig stakes, but it's still something to bear in mind.

https://www.drupal.org/project/eva
> 0 votes

# Answer
@NikLP I got "This block is broken or missing. etc" until I used the value of the `#plugin` key in the Devel output for my Custom Block. This was the output in Devel:

```
Block {#725 ▼
  #id: "mycustomblock"
  #settings: array:7 [▶]
  #region: "content"
  #weight: 0
  #plugin: "block_content:de79f8de-8e8f-4a56-b787-790347b4f104"
   ...

```

Then in my template, this worked:

```
{{ bamboo_render_block('block_content:de79f8de-8e8f-4a56-b787-790347b4f104') }}

```

Using the `#id` key did NOT work:

```
{{ bamboo_render_block('mycustomblock') }}

```
> 0 votes

---
Tags: theming, 8
---


# Question
Title: How to create programmatically multiple URL alias of same taxonomy term?
I have category cars and I want to create its URL alias according to the region like if the user location is Australia than URL will `mysite/australia/cars` similar if the user location is USA than URL will be `mysite/usa/cars`.

Can you please anyone tell how can I achieve this kind of functionality?

Thanks in Advance.

# Answer
If you use pathauto module:

You can use `hook_pathauto_alias_alter` like the following:

```
/**
 * Implements hook_pathauto_alias_alter().
 */
function YourModuleName_pathauto_alias_alter(&$alias, array &$context) {
  // Change tags here by your term name
  if ($context['module'] == 'taxonomy_term' && isset($context['type']) && $context['type'] == 'tags'){
   // Get the current user the location for example australia
    $user_location = 'australia';
    // Change the alias to be
    $alias = $user_location. '/cars/[term:name]';
  }
}

```
> 0 votes

---
Tags: 7, uri, path-aliases
---


# Question
Title: Strange behavior: Extra css classes are NOT merged with the 'Search Block' form tag classes but with those of BLOCK wrapping the form tag
i'm experiencing such 'strange' behavior with `Drupal (v8.7.10)` when trying to add css classes to the default `Search Form` **form tag** using `MYTHEME_form_FROM_ID_alter` hook, the classes are **NOT** merged with the form tag classes as expected but with those of the **BLOCK** wrapping the form tag itself.

this is my code:

```
function MYTHEME_form_search_block_form_alter(&$form,\Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['#attributes']['class'] = 'form-inline';
}

```

and this is the rendered output in question

```
<div class=" form-inline " data-drupal-selector="search-block-form" novalidate="" role="search" id="block-MYTHEME-search">
  <form action="/search/node" method="get" id="search-block-form" accept-charset="UTF-8">
    <div class="form-group">
      <label for="edit-keys" class="sr-only">Search </label>
      <input title="Enter the terms you wish to search for." placeholder="Search .." data-drupal-selector="edit-keys" type="search" id="edit-keys" name="keys" value="" size="15" maxlength="128" class="form-search form-control rounded-0">
    </div>
    <div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions">
      <input data-drupal-selector="edit-submit" type="submit" id="edit-submit" value="Search" class="button js-form-submit form-submit btn btn-primary rounded-0">
    </div>
  </form>
</div>

```

any thoughts ?

# Answer
> 0 votes
after digging for hours on drupal.org docs, i ended up with this solution

```
function mytheme_preprocess_form(&$variables) {
  // kint($variables);
  if ($variables['element']['#form_id'] == 'search_block_form') {
    $variables['attributes']['class'][] = 'form-inline ';
  }
}

```

it works as expected, but `hook_form_FORM_ID_alter` make more sens to me than `hook_preprocess_form`.

# Answer
> 1 votes
It's fairly straight forward PHP mistake `$form['#attributes']['class']` is an array of classes

And by doing `$form['#attributes']['class'] = 'form-inline';` you're saying forget whatever `$form['#attributes']['class']` was before its now a string that contains 'form-inline'. So you're changing the variable from an array to a string.

Long story short you should be adding your class to the existing array with:

```
 $form['#attributes']['class'][] = 'form-inline';

```

Note the \[\] after \['class'\]

That explains why you have no classes coming out on your form. The issue about the classes on your outer div isn't related to this code and you must have something else going on too. Perhaps a block alter hook

# Answer
> 1 votes
I have tested it too, it seems not working with `MYTHEME_form_FROM_ID_alter` there is another way to do so.

1. Implements `hook_theme`

```

/**
 * Implements hook_theme().
 */
function MyModule_theme($existing, $type, $theme, $path) {
  return [
    'search_block_form' => [
      'base hook' => 'form',
      'template'  => 'form--search-block-form',
    ],
  ];
}

```
2. Create `form--search-block-form.html.twig` in templates folder of your module put in it.

```
{# add your inline-form class here #}
 <form{{ attributes.addClass('search-form', 'search-block-form', 'inline-form') }}>
  {{ children }}
</form>

```
4. Clear cash.

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


# Question
Title: Importing Webform Submissions to create content
Is it possible to use data a user submits via a webform via a simple import into a site. It would not be the same site. The webform is being used to collect specific data.

e.g. webform data = user name, address, photo file, csv file submitted via webform in site A

webform submission data imported in to site B

# Answer
You can make a view of your results (built-in webform) and with the https://www.drupal.org/project/views\_data\_export module turn in it into a CSV. Plenty of ways to import that.
> 0 votes

# Answer
You could try the Webform Import module for Drupal 7: https://www.drupal.org/project/webform\_import
> 0 votes

---
Tags: webforms
---


# Question
Title: Having issues saving altered value in a view pre render
I am trying to remove image tags in the view prerender. I've looked through articles and StackExchange and I have set it up correctly. But when I refresh the page containing the view, all the HTML tags are now present as a string.

Here's my code.

```
function mytheme_views_pre_render(Drupal\views\ViewExecutable $view) {
  if ($view->id() == "news" && $view->current_display == 'block_1') {
    foreach ($view->result as $row) {
      $body = $row->_entity->body->value;
      $stripped_img = preg_replace('/<img[^>]+\>/i', '', $body);
      if ($stripped_img != $body) {
        $row->_entity->body->setValue($stripped_img);
      }
    }
  }
}

```

# Answer
You should set the format of body to `full_html` try with:

```
function mytheme_views_pre_render(Drupal\views\ViewExecutable $view) {
  if ($view->id() == "news" && $view->current_display == 'block_1') {
    foreach ($view->result as $key => $row) {
      $body = $row->_entity->body->value;
      $stripped_img = preg_replace('/<img[^>]+\>/i', '', $body);
      if ($stripped_img != $body) {
        $row->_entity->body->setValue($stripped_img);
        // Here set the format of body to full_html
        $row->_entity->body->format='full_html';
      }
    }
  }
}

```
> 2 votes

---
Tags: views, 8
---


# Question
Title: Collapsed and collapsible Field Sets in Admin
I have created a fieldset (which groups a field collection). Because it has a few nested levels and many fields, I want it to be shown collapsed. I am trying this code but it does not work. The **id** is retrieved directly from the source code of the web browser. The fieldset is the top-level, and there are more fieldsets inside of it. The form is displayed in the Admin page, the node edit form. The field "field-seo-general" is a #container.

```
function hook_form_alter(&$form, &$form_state, $form_id){
    if($form_id == "my_form"){
        $form["field-seo-general"]['options']['attributes']["#collapsible"] = TRUE;
        $form["field-seo-general"]['options']['attributes']["#collapsed"] = TRUE;
      ...
} // function

```

# Answer
> 0 votes
I have solved it installing the module Field Collection Fieldset, and instead of Embedding the Field Collection, I have put it as a Fieldset, and then one of the options is to be shown Collapsed at rendering. All with a module.

# Answer
> 0 votes
> The field "field-seo-general" is a #container.

The The Form API entry for `container` does not include `#collapsed` or `#collapsible` as properties.

It seems that `fieldset` is the only element that can use the `#collapsed` and `#collapsible` properties.

Change the `#type` for `field-seo-general` to `fieldset` to make it collapsible. If `field-seo-general` needs to be a `container`, then a second option would be to create a `fieldset` and place the `field-seo-general` container within it. However, doing this will add one more dimension within the `values` array for your fields when the form is submitted, so you need to take that into account.

```
$container_seo_general = $form['field_seo_general'];
unset($form['field_seo_general']);
$fieldset = array(
  '#type' => 'fieldset',
  '#title' => 'My fieldset title',
  '#collapsible' => TRUE,
  '#collapsed' => TRUE,
);
$fieldset['field_seo_general'] = $container_seo_general;
$form['my_module_fieldset'] = $fieldset;

```

---
Tags: 7, forms
---


# Question
Title: How can I create a page with four content types displayed with infinite scroll?
I need a page where i display a list of 4 contents types articles.

The articles for each content type must grouped, and when scrolling i want load page for each groupe.

What is the better way to do it ?

Thanks

# Answer
You can create a view with one content type with a page display and then in that view add three displays, one each for each of the other content types, and attach these displays to the first page view. That will give four different lists in the same page. You will have one scroll for the page. I do not think an infinite scroll would make sense in this context.

If you want as one single list with all the articles but with each type of content grouped together do the following. This is the only way infinite scroll is going to work well for you.

You can create a content view and filter by the four content types that you want to list in the view. And then add a sort by on the content type and then date created (asc or desc as you wish). You should have https://www.drupal.org/project/views\_infinite\_scroll set up as well to allow infinite scroll.
> 0 votes

---
Tags: views
---


# Question
Title: Create a Corresponding Entity Reference preset programmatically
I'm using the CER module in Drupal 7. Is there a way to create a preset programmatically?

# Answer
> 0 votes
\[EDIT\]

Almost a year later, I found a better way (the entity\_import way actually did not work).

CERs are entities. The best way to create one is using `$cer = entity_create('cer', array('bundle' => 'cer'));` adding appropriate values to the fields of the created entity, and saving it by using `entity_save('cer', $cer);`

=======================

Finally figured it out. You can use the entity\_import function.

1. Create a variable containing a JSON-like string of the entity (which you can get by exporting a CER entity), something like:

$j = '{ "identifier" : "node:time\_slot:field\_ref\_student\*commerce\_line\_item:registration:field\_ref\_slots", "cer\_bidirectional" : { "und" : \[ { "value" : "1" } \] }, "cer\_enabled" : { "und" : \[ { "value" : "1" } \] }, "cer\_weight" : { "und" : \[ { "value" : "0" } \] }, "cer\_left" : { "und" : \[ { "path" : "node:time\_slot:field\_ref\_student" } \] }, "cer\_right" : { "und" : \[ { "path" : "commerce\_line\_item:registration:field\_ref\_slots" } \] }, "rdf\_mapping" : \[\] }';
2. Then import and save:

$e = entity\_import('cer', $j); entity\_save('cer', $e);

# Answer
> 0 votes
I know it's an old question, but for anybody looking for a way to do this argiepano's answer is not very clear. Found that their first solution works just fine, and actually that's how it's done by the code that does the importing in the CER admin UI:

```
// Create the entity using the JSON string.
$entity = entity_import('cer', '{JSON STRING HERE}');
// Now do the actual saving.
entity_save('cer', $entity);

```

---
Tags: 7
---


title: Export blocks added as default content

text:
# Question
Title: Export blocks added as default content
I am using Layout Builder to add blocks into my nodes. I am adding several instances of different custom block types to specific content individually.

I wander if it is it possible to export those blocks added to node through layout builder as a default content using: Default content module?

I have tried standard `drush dce` and while it exports the node, I could not find block data into exported JSON.

I tried `drush dcer` to export references as well but no luck with it as well.

I am thinking finding specific block IDs and export those entities manually one by one but before I do that I want to find out if there is a way to do it in more elegant fashion.

Also if this something new, it would be good feature to contribute to Default content module, so if we find out that's the case I would happily try to contribute.

# Answer
> 1 votes
Yes It is possible. Core patch is required to fix this issue. It will fix node JSON structure and attach block\_content to json files. See my comment #63 for details: https://www.drupal.org/project/drupal/issues/2942975#comment-13315805

---
Tags: 8, blocks, layout-builder
---


# Question
Title: How to get parent node values on inline entity form hook alter?
I am using inline entity forms to create a paragraph in a node form. When I add a node I want the title of the node form to be copied to the paragraph when I click on "Add paragraph". I use hook\_inline\_entity\_form\_entity\_form\_alter to prefill the title field. That works, only I can't get the values from the node form. Not with the below code.

```
function example_forms_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->getType() == "task" && $entity_form['#bundle'] == "improvement") {
    \Drupal::logger('Form state values')->debug("<pre>" . print_r($form_state->getValues(), TRUE) . "</pre>");
    \Drupal::logger('Node values')->debug("<pre>" . print_r($node, TRUE) . "</pre>");
    $entity_form['title']['widget'][0]['value']['#default_value'] = 'This is Jessica';
  }
}

```

Can someone help me solve this?

# Answer
> 0 votes
Perhaps you should try altering the paragraph form instead. When the paragraph is created, you will have access to it's host entity. Then just get the label of the host entity and assign it to the form element as a default value or value(can't remember which one).

# Answer
> 0 votes
This is a quite old question, I'm not sure if it's still relevant but you can use parent node title from the userInput array.

```
function example_forms_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->getType() == "task" && $entity_form['#bundle'] == "improvement") {
    $userInput = $form_state->getUserInput();
    $entity_form['title']['widget'][0]['value']['#default_value'] = $userInput['title'][0]['value'];
  }
}

```

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


# Question
Title: How can I have a employee ID read-only in Drupal Profile, set by Admin?
I need to have a field in user profile named Employee ID, this field should only be set by admin (Read and write), read-only to user, and hidden from all other users. Thank you.

# Answer
You can use the field\_permissions module to set up permissions for fields by user role and then limit access to admin. If you want to limit to one person then set up a separate role and give that role only to one person.
> 0 votes

# Answer
Well, finally found the answer, use this module: field\_readonly The best way of having it to work is to install field\_permissions module (or any field permission module or code) first, set all the permissions (this will hide the field completely but do not worry go ahead) and then just install field read-only, the module gets it from there and make it visible and read only :)
> 0 votes

---
Tags: users
---


# Question
Title: How to find a field name/column name of a field in database where I have only the label of that field?
I am working on an integration part with drupal framework. Here it's hard to find the table names of the field which is present in the view as I know only the field label name.

Is there any way to sort this out?

# Answer
You can derive the database table name by the host entity and the field name. The name schema is `ENTITYTYPE__FIELDNAME`

Views don't directly show the field name, but you can look at the entity's "Manage field" page to get the field name by label. (e.g. for nodes `/admin/structure/types/manage/BUNDLENAME/fields`)

Examples:

```
node__body
node__field_image
users__field_whatsapp
taxonomy_term__field_text

```

Exception:
Some special fields (like `title` or `created`) are stored as a column on the base table of an entity. Base tables follow the schema `ENTITYTYPE_field_data`, e.g.

```
node_field_data
users_field_data
taxonomy_term_field_data

```
> 1 votes

---
Tags: views, entities, database
---


# Question
Title: Alter Add to Cart form POST data provided by #action
I am going to be phasing out Drupal Commerce on our website in favor of a new custom built application that is hosted at another URL. Without completely rebuilding everything I am trying to override the Add to Cart form to redirect with POST data to the new app.

Using $form\['#action'\] I can redirect properly and dumping out shows something like this:

```
array(7) {
    ["quantity"]=>
    string(1) "2"
    ["product_id"]=>
    string(4) "8566"
    ["form_build_id"]=>
    string(48) "form--90fc5Yp9qgp4CVFJlq03jfEZyYBkAhDX-j7E5g9oBQ"
    ["form_token"]=>
    string(43) "T08Fl1dNHuI4BCZ4JuLNwxbw6gUTOfnodbc1zcQMR4E"
    ["form_id"]=>
    string(35) "commerce_cart_add_to_cart_form_8566"
    ["field_are_you_a_product"]=>
    array(1) {
        [0]=>
        array(1) {
            ["field_are_you_a_"]=>
            array(1) {
                ["und"]=>
                string(3) "yes"
            }
        }
    }
    ["op"]=>
        string(11) "Add to cart"

```

This is helpful but the product\_id is useless as I need more info, like the SKU or a custom ID field I have on the product level. I can't seem to get this to provide me with the product info I need.

I initially tried using a custom submit handler instead but that didn't work. drupal\_http\_request isn't right as it just sends post data, does actually redirect with post data like action does.

So since setting the action works great, how would I alter this form to send more information during that step within hook\_form\_alter?

# Answer
You can add other fields to your form as hiden, in the `hook_form_alter` for example add SKU field as hidden.

```
  $form['sky'] = [
    '#type'  => 'hidden',
    '#value' => YOUR_VALUE,
  ];

```

Hidden fields will submitted like others.
> 1 votes

---
Tags: 7, forms
---


title: Appending Multiple Fields In Twig

text:
# Question
Title: Appending Multiple Fields In Twig
I'm attempting to append two fields with some text in the middle. Using the changed date and a plain, core, text field, I can do something like this, and it works:

```
{{ node.changed.value|date('m.d.y') ~ ' | By, '}}{{ content.field_author_name.0 }}

```

However, if I attempt to do that in a single tag, the changed date, and the 'By' text is output, but I don't get the author name field.

```
{{ node.changed.value|date('m.d.y') ~ ' | By, ' ~ content.field_author_name.0 }}

```

Is that not valid twig syntax, or is there something else needed to get that to work in a single statement?

# Answer
> 1 votes
When using `{{ content.field_author_name.0 }}` it works because field is rendered with the twig.
The *~* operator converts all operands into strings and concatenates them. Given that `content.field_author_name.0` is a render array you need point to the string value of this field. To do this you can inspect it with the devel or twig\_vardumper module using `dump(content.field_author_name.0)`. More about debugging twig templates: https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates#s-viewing-variables

Assuming that *field\_author\_name* is simple text field with the *Plain text* formatter, this should work:

```
{{ node.changed.value|date('m.d.y') ~ ' | By, ' ~ content.field_author_name.0['#context'].value }}

```

To display node creator name you can use this:

```
{{ node.changed.value|date('m.d.y') ~ ' | By, ' ~ node.uid.entity.name.value }}

```

# Answer
> 0 votes
To get the author name you can use `{{ node.Owner.name.value }}` or `{{ node.uid.entity.name.0.value }}`. Try with:

```
{{ node.changed.value|date('m.d.y') ~ ' | By, ' ~ node.Owner.name.value }}

```

---
Tags: 8, theming
---


# Question
Title: Migrating input formats for taxonomies with empty description
I am trying to write custom migrations to migrate my Drupal 7 website to Drupal 8. I am currently using Drupal 8.7.10 and Drupal 7.61 for a copy of the production website.

I have tried to migrate description from drupal 7 source and set format as "full\_html" for drupal 8.

I have read a lot of sources, for example Migrating input formats causes errors

I have used this code for migration

```
description/value: description
description/format: format2

```

and for process plugin

```
public function prepareRow(Row $row) {
  $row->setSourceProperty('format2', 'full_html');
}

```

but format didn\`t saved for empty description.

How to save the format if the description is not filled?

# Answer
The field is empty so it'll get a format set from the configured default when someone enters a description. If there's no value it doesn't need a format, because the format is purely there to say how the value should be displayed.

In theory a value of an empty string with a format attached might give a different result to a null value (the empty string might be wrapped in `<p>` tags for example) but this will not usually matter in practice.

So the migration is doing what is expected, by not creating an entry for an empty field value.
> 1 votes

---
Tags: 8, migrations
---


# Question
Title: Programmatic access to metatag module fields
I am wondering how to programmatically access `metatag` module data. For example, my node has an entry for metatag description, and I see in the generated page the meta description tag, which is great. However, it's not clear how I can access this programmatically.

Right now, I am trying the following:

```
$metatag_manager = \Drupal::service('metatag.manager');
$tags = $metatag_manager->tagsFromEntityWithDefaults($node);
$elements = $metatag_manager->generateRawElements($tags, $node);

```

Inspecting the data, I see that `$tags` includes a `'description'` entry, but `$elements` does not. Is there a better way of accessing this data?

The `metatag` module includes documentation for programmatically setting data, but unfortunately does not mention accessing the data.

Edit: Alas, it seems I was inspecting the wrong node -- one with the same title as a node with metadata entries. Working now with the correct node, it seems all I need to use is:

```
$metatag_manager = \Drupal::service('metatag.manager');
$tags = $metatag_manager->tagsFromEntity($node);

```

Which returns an array with a `description` key and the description value entered for that node.

# Answer
> 1 votes
If you have node object loaded, you can access the meta tags as below:

```
$metaTags = $node->get('field_meta_tags')->value;
if (!empty($metaTags)) {
      $metaTagsArr = unserialize($metaTags);
echo "<pre>";
print_r($metaTagsArr);
echo "</pre>";
}

```

---
Tags: 8
---


# Question
Title: Development with git branches/ gitflow and new modules
I wonder if somebody found a solution for the following issue related to Drupal 8 development with Git branches:

* You work on a new feature in a local feature branch
* for that you activate a contributed module or you write a custom module. This maybe delivers an own entity type and therefore creates a table after installing
* Meanwhile you need to fix a bug -\> you change to a newly created bugfix branch which starts from the current dev branch
* After checking out the bugfix branch you import the current configurations to have the current active configuration of the branch -\> the module you installed in feature branch is not activated anymore, the files of this module do not exist in the current bugfix branch
* You do your bugfixing and merge ths bugfix branch into develop branch.
* you change to your feature branch. To bring your local Drupal project to the status of this branch again you will import the configurations again

And here it comes to an exception: the table already exists in your database. When doing a drush cim it stops every following processing and you need to restart drush cim to import any further configurations.

Who does work with different feature branches and found a solution during development process to deal with this kind of situation?

# Answer
I always have a somewhat up-to-date DB dump from live/master available. When switching between feature branches I can `drush sql-drop` the DB, `drush sql-cli < live.sql` and `drush cim` the branch config. If needed. When switching back into the develop or master branch I do the same steps again.

This means you routinely have to commit your feature's configs into its branch. Or to write really cool install.yml in a custom module and enable that after you switched back into the feature branch.

I guess we will have something automating this in half a year. But for now, it's perfectly fine. At least for me.
> 3 votes

# Answer
Working with a very large database, it is not always practical to run `drush sql-cli < live.sql`

Ideally, `composer install` would be run with an option to disable module uninstalls, followed by `drush cim` and `drush updb` and finally a normal `composer install`, but that is currently not possible.

My solution for now is to capture the `composer install` removals in a script that runs after the command to re-require the removed packages. Later `git checkout` restores the state of composer.\*, then `composer install` runs again. So the sequence is:

1. Update my local repository
2. Run `composer install` and filter the output to remove ANSI codes and pull out lines starting with " - Removing" followed by lines starting with "Deleting" and reformat them as `composer require` commands in a script called `composer.reinstall.sh`:

```
composer install | tee >(perl -pe 's/\e\[[0-9;]*m//g'|grep -B1 "^Deleting"|grep "^  - Removing"| perl -pe 's/^  - Removing ([^ ]+) \(([^\)]+)\)/composer require \1:\2/g' > composer.reinstall.sh)

```
3. Run the generated script: `sh composer.reinstall.sh`
4. Run Drupal scripts (`drush cim` and `drush updb`) which depend on package existence
5. Reinitialize composer files: `rm composer.reinstall.sh; git checkout composer.*`
6. Run `composer install` to uninstall any packages removed from `composer.json`
> 0 votes

---
Tags: 8, configuration, version-control
---


# Question
Title: Article "promoted to front page" also displays all images of featured slideshow
Currently using Shinbun theme and Drupal 7 (based on an existing site, as required for a project) and was struggling to create a slideshow of selected images, which I finally managed on the article pages with Views Slideshow module.  Works fine for all Article pages, using one image as static or more as a slideshow. Unfortunately, when using more as a slideshow and selecting the option "promoted to front page" and "sticky on top", to project the article in the front page, it also displays the images of the articles... And in the case of our slideshow, it shows them all, one under the other.

What I would like to do is, preferably, find a workaround to display only ONE of the slideshow images, OR show none of them.

Any suggestions? Thanks in advance.

# Answer
> 0 votes
It's not very clear from your question or the accompanying screenshot, but perhaps you are using a different view mode and/or Views display for the Article content type on the front page, and not actually using your slideshow Views display at all in that context. To be sure, I'd need more info:

* In what context is the slideshow working? (Sounds to me like it works when you view an Article node)
* In what context is the slideshow not working? (Sounds to me like this happens when an Article is displayed in a Views Block display on the homepage)

If this is the case, then you're not using Views Slideshow to display the article in this context, and you may also be using a different view mode (i.e., Teaser) to display the Article on the homepage.

---
Tags: views
---


title: Event subscriber to invalidate a cache

text:
# Question
Title: Event subscriber to invalidate a cache
I am invalidating a cache tag in `KernelEvents::REQUEST` event:

```
public static function getSubscribedEvents() {
  $events[KernelEvents::REQUEST][] = ['onRequest', 100];
  return $events;
}

```

```
public function onRequest(GetResponseEvent $event) {
  if ($this->request->cookies->has('myValue')) {
    $this->cacheTagsInvalidator->invalidateTags(['my_tag']);
  }
}

```

When I refresh the page the tag is invalidated but the changes are showing on the next refresh, to which event/hook/etc. do I need to subscribe me to see my changes in single refresh ?

**Edit 1:** I have 'Internal Page Cache' module installed. If I uninstall it, the code above works fine.

**Edit 2:** Added the `if` condition.

# Answer
I did it implementing a middleware:

`mymodule/mymodule.services.yml`:

```
mymodule.http_middleware:
  class: Drupal\mymodule\StackMiddleware\BeforePageCache
  arguments:
    - '@cache_tags.invalidator'
  tags:
    - { name: http_middleware, priority: 280, responder: true }

```

`mymodule/src/StackMiddleware/BeforePageCache.php`

```
...
/**
 * {@inheritdoc}
 */
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
  if ($request->cookies->has('myValue')) {
    $this->cacheTagsInvalidator->invalidateTags(['my_tag']);
  }

  return $this->httpKernel->handle($request, $type, $catch);
}
...

```
> 0 votes

---
Tags: 8, caching, event-subscribers
---


# Question
Title: Copying over all the elements to a new page
I have a website where we post our events. We would love to copy the 2018 event post and then edit it, rather than copying over all the elements to a new page. Is this possible?

# Answer
If your events are part of a content type, then try this module. It should let you clone a node

https://www.drupal.org/project/quick\_node\_clone
> 1 votes

---
Tags: 8
---


# Question
Title: How to display an add to cart button for each product displayed in my views grid?
I am creating an online store, for which I am using the Views module (grid) for product displays.

I want a 'Add to cart'-button to appear for every product displayed. How can I do so?

Note: I can display the product, but without the 'Add to cart'-button.

# Answer
Surely your issue was solved a long time ago, but this could be useful for other people, so in short :

* in advanced settings of the view, add a relationship *Commerce Product: Referencing Node (Relate a product to the Node referencing it through field\_product)* with your product type
* then add a Contextual filter *(Node referencing products from field\_product) Content: Nid*
* then you're be able to pick up **Add to cart form** from Add fields menu

Enjoy ;)
> 1 votes

# Answer
In case you are using Drupal Commerce, you might be able to solve your issue (question) as described in this issue, i.e:

> The problem is the "Add to Cart form" Views field that you're using doesn't have the node context. As far as the node and the View are concerned, that View is the sole place you're displaying that Add to Cart form. What you'd really need to do is to have the actual Product Reference field from the node rendered. When that happens, Views will load the full node and its field will be rendered individually - and it's during that process that it adds the node context to the Add to Cart form for use in the display\_path field.
> 0 votes

# Answer
Along with the other fields, add the product variations field and choose the add to cart form from the formatter dropdown. That will add add to cart button to all the products listed in the view.
> 0 votes

---
Tags: views, commerce
---


# Question
Title: How do I collect field values of a submitted webform?
I'm trying to integrate a Mailchimp mailing list into Drupal. The Mailchimp list requires:

* First Name
* Last Name
* E-Mail

The client already has a list in this format so ideally I need to collect this data in Drupal.

I want to have a newsletter block that collects the email address and forwards a user to another page that has the full newsletter sign up with first name last name and the email but pre filled out.

I know I'm going to need Rules and Webform. But how can I collect the value of the webform field and use it again as a token later?

**Note**: I am using this within the Drupal setup, but the list requires three fields of data (first/lastname/email). I want to have a block that initially collects the email and forwards them to the full newsletter signup page. I have the webform and rules working to direct the user from the page with the block to the signup page, but I need to find out how to create a custom token from the field.

# Answer
> 0 votes
Have a look at Webform Mailchimp , different approach but may be of use

> Provides a webform component that lets users subscribe to a Mailchimp newsletter as they submit a webform.

# Answer
> 0 votes
You do have access to all ***labels*** and all ***values*** of any field of a webform, ie:

* `[data:MachineFieldName-title]` contains the **Label** of a field with machine name MachineFieldName.
* `[data:MachineFieldName-value]` contains the **Value** of a field with machine name MachineFieldName

So in your case, you might be able to get it to work using something like `[data:email-id]` (assuming that's what corresponds to the "*email field*" in your case).

For way more details on this, and a prototype rule about this, refer to the answer to "How to create a node from a Webform using rules?":

* the *1st attempt* relates to using "Entity has field" (which doesn't work for Webform)
* the *2nd attempt* explains what to do in case of Webform.

Even though the above is a good start, it may not be sufficient to achieve your goal (= "*... how can I collect the value of the webform field and use it again as a token later ...*", as in your question). However, you can use a technique similar to what is described in my answer to "How to do a data comparison to submitted webform data when using the Rules module?". For short:

* Add an extra Rules Action to `Add a variable`, with a value assigned to it equal to your `[data:EmailField-value-raw]` (and with an appropriate data type). I'm assuming your eMail field in your webform has a machine name like `EmailField` (adapt to fit your machine name).
* In your subsequent Rules Actions you can refer to the value of this variable you just added (that's the clue!).

PS: I'm assuming this question is about D7.

# Answer
> 0 votes
I dedicate a blogpost on how to add a custom `WebformSubmitHandler` to process the data. Read about it here: https://stefvanlooveren.me/blog/how-create-mailchimp-subscription-drupal-8-webform-module

---
Tags: 7, rules, webforms, emails, tokens
---


# Question
Title: How to save custom label as parameter for a custom entity_reference field widget?
I am creating a custom field widget for an `entity_reference` field. This has a custom select field and an Ajax Submit button. Once the user selects an option (entity) from the select\_field and submits it, I am adding the entity in a `dragTable` below.

I could achieve that until now, but my need is to add a custom label for the entity selected. I provided a textfield to capture the custom values and I am able to fetch the values. But, I am unable to save this custom `text_field` data. I am extending the core `WidgetBase` class for my custom field Widget. For an entity\_reference field, is it possible to save custom label parameters along with the entities?

**Updated:** After enabling fieldType, duplicate results are appearing while creating field. Any help on this? .

# Answer
You need to create a custom field type that can hold the value along with the entity reference.

A field widget can not store any data that the field type has not provided space for.

You must create a new field type would look similar to this:

```
<?php

namespace Drupal\MY_MODULE\Plugin\Field\FieldType;

use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;

/**
 * @FieldType(
 *   id = "entity_reference_with_value",
 *   label = @Translation("Entity reference with value"),
 *   category = @Translation("Reference"),
 *   default_widget = "my_custom_field_widget",
 *   default_formatter = "some_formatter",
 *   list_class = "\Drupal\Core\Field\EntityReferenceFieldItemList",
 * )
 */
class EntityReferenceWithValue extends EntityReferenceItem {

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    $schema = parent::schema($field_definition);
    $schema['columns']['value'] = [
      'type' => 'varchar',
      'length' => 255,
    ];
    return $schema;
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);
    $properties['value'] = DataDefinition::create('string')
      ->setLabel(new TranslatableMarkup('Value'))
      ->setRequired(TRUE);

    return $properties;
  }

}

```

Now you can get the value with `$entity->field_name->value`.

It would also be better to extend `EntityReferenceAutocompleteWidget` in your field widget, instead of `WidgetBase`. Then you can just do like this in the `formElement` method:

```
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
  $widget = parent::formElement($items, $delta, $element, $form, $form_state);

  $widget['value'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Value'),
    '#default_value' => $items[$delta]->value,
    '#weight' => 999,
  ];

  return $widget;
}

```
> 5 votes

---
Tags: 8, entities, forms
---


# Question
Title: Drupal Leaflet View loading view block through Ajax
I created a view block for displaying geocodeed nodes on a View Leaflet map. Everything working, the map displays the markers as I want. Now, I would like to load this map throught drupal ajax

I attached the leaflet libraries to the page. Then I load the view with:

```
$view = Views::getView('map');

$view->setArguments($args);
$view->setDisplay('block');
$view->preExecute();
$view->execute();
$content = $this->renderer->render($view->render());

$response->addCommand(
    new HtmlCommand('.result__map', $content)
 ));

```

The $content contain only an empty div generatated from the view and when the response is instered in the Dom nothing happen. I suspesct that the map is missing some JS trigger to instanciante the map and maybe some JS settings.

Could someone send me an example or point me in the right direction.

# Answer
You must use the ViewExecutable::buildRenderable function.

Instead of:

```
$content = $this->renderer->render($view->render());

```

You must do like this:

```
$content = $view->buildRenderable('block', $args);

```
> 1 votes

---
Tags: views, 8, ajax
---


# Question
Title: How do I add a CSS class to a form label?
I want to add a CSS class to a label on a page that is using Drupal 8 Form API. I have been unable to find a reference online on how to apply that. I have used the following workaround, but it produces some strange results.

```
public function buildForm(array $form, FormStateInterface $form_state)
{
    $form['label1']  = array(
        '#type' => 'label',
        '#title' => $this->t('QUESTIONNAIRE'),
        '#id'         => 'lbl1',
        '#prefix'     => '<div class="caption1">',
        '#suffix'     => '</div>',
    ) ;

```

and the HTML rendered is:

```
<div class="caption1"><label for="lbl1" class="control-label">
<div class="caption1"></div>QUESTIONNAIRE
  </label>

```

Not only is the div statement in the wrong place but it is rendered twice.

I had found postings from several years ago that show this was not possible, but I am hoping that since then, and with D8, it has been fixed. I do not want to do it with prefix/suffix, but as a separate array element.

PS: this site is Drupal 8.0.0-rc2

# Answer
> 20 votes
I know this is an old thread, but for anyone Googling.

The clue to this is in `template_preprocess_form_element()`.

```
$element += [
    '#title_display' => 'before',
    '#wrapper_attributes' => [],
    '#label_attributes' => [],
  ];

```

`#label_attributes` is a standard attribute array, so very easy to set a class with `['class' => ['my-class', 'other-class']]`

`#title_display` takes 3 values:

* before: The label is output before the element. This is the default.
* after: The label is output after the element. For example, this is used for radio and checkbox #type elements.
* invisible: Labels are critical for screen readers to enable them to properly navigate through forms but can be visually distracting. This property hides the label for everyone except screen readers.
* attribute: Set the title attribute on the element to create a tooltip but output no label element. This is supported only for checkboxes and radios

# Answer
> 8 votes
I just checked this and I don't believe it is possible to add a class directly to a label element.

As you most probably know, classes are normally added with #attributes as follows:

```
 $form['foo'] = array(
  '#type' => 'textfield',
  '#title' => 'Foo',
  '#attributes' => array('class' => array('first-class', 'second-class')),
);

```

However, I just tested and #attributes does not add classes to a Label element.

Is it possible for you to add a wrapper form element, give a class to it and then style your label based on the fact that it is a child of the wrapper element? Like this:

```
$form['container'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('your-class')),
);
$form['container']['foo'] = array(
  '#type' => 'textfield',
  '#title' => 'Foo',
);

```

Now, this will render the example textfield (and its label) inside of a DIV element that has your-class i.e. you can style you label:

```
.your-class label {
  /* your CSS here */
}

```

# Answer
> 6 votes
There are several options to do this in Drupal \>=8.0.0. These all really revolve around template overrides in a theme, but a module should be able to implement template preprocess hooks defined by other modules

1. The simplest, but non-dynamic option is to override form-element-label.html.twig directly. This could work if all labels will get the `form-control` class.
2. Following along these lines, implementing template\_preprocess\_form\_element\_label would allow you to do the same thing and add `form-control` class to attributes without overriding the template.
3. You could also implement template\_preprocess\_form\_element, and add logic to not overwrite `$variables['label']`, but take its values from some defined key on the form element array.

# Answer
> 2 votes
For submit buttons we can add class like below :

$form\['actions'\]\['submit'\]\['#attributes'\]\['class'\]\[\] = 'use-ajax-submit';

# Answer
> 1 votes
Cleanest option I found is as per @mradcliffe's #3 suggestion above. Eg in your form definition -

```
$form['distance'] = [
        '#type' => 'select',
        '#title' => 'Distance',
        '#required' => true,
        '#options' => [
            '10' => '10 Miles',
            '25' => '25 Miles',
            '50' => '50 Miles',
            '100' => '100 Miles'
        ],
        '#label_classes' => [
            'some-label-class'
        ]
    ];

```

Then in a custom module implement hook\_preprocess\_form\_element:

```
/**
* Implementation of hook_preprocess_form_element
* @param $variables
*/
function your_module_preprocess_form_element(&$variables)
{
    if(isset($variables['element']['#label_classes'])) {
        $variables['label']['#attributes']['class'] = $variables['element']['#label_classes'];
    }
}

```

Note this will override any label classes Drupal wants to add. In my case that is fine. Code above can be altered to prevent this if necessary.

# Answer
> 1 votes
To complete @Nate answer, if you want to add theses classes to an existing form, you can do it in hook\_form\_alter :

```
function your_module_form_alter(&$form, FormStateInterface &$form_state, $form_id)
{
    // for a textfield
    $form['distance']['widget'][0]['value']['#label_classes'] = ['some-label-class'];
    // for a radio field
    $form['country']['widget']['#label_classes'] = ['some-label-class'];
}

```

And then use the hook\_preprocess\_form\_element for the text field or a hook\_preprocess\_fieldset for the radio field :

```
/**
 * Implements hook_preprocess_hook().
 */
function your_module_preprocess_fieldset(&$variables)
{
  if(isset($variables['element']['#label_classes'])) {
    foreach ($variables['element']['#label_classes'] as $class) {
      $variables['legend']['attributes']->addClass($class);
    }
  }
}

```

---
Tags: 8, forms
---


# Question
Title: Get Relationship for the Author of the Latest Comment
In a Node view, I am trying to group the latest comments by the author's `field_last_name`, but I am having difficulty adding this field.

I tried using the the "Last comment" and "Last comment author" relationship, but they both don't appear to work. (Neither exposes the user fields or the "Comment: Author" relationship.)

Am I missing something here? Or must I switch my Node view into a Comment view?

# Answer
I'm going to assume here that `field_last_name` is a field you added yourself to the account fields. I tested using just the user name, and got it to work fine using the following relationships (starting from a Node):

1. From the node to all comments: was called "Comments of the node using field: comment" here
2. And then from the comment to the author: just called "Author" here in the Comment category

Then I added the "Name" field (User category), and Bob was my proverbial uncle.
> 1 votes

---
Tags: views, 8, comments
---


# Question
Title: What is x-speed-cache-key? What is its purpose?
Our drupal site was pentested. The pentest report labeled an action involving the header X-Speed-Cache-Key as a security concern.

The finding stated:

> Arbitrary parameters supplied to the query string are returned to the user unencoded in the X-Speed-Cache-Key response header.

I'm not familiar with caching or with the header x-speed-cache-key. For a Drupal site functionality should the x-speed-cache-key function as stated in the finding? Is this a valid security concern for Drupal? Is the x-speed-cache-key header provided by a module, or is it a part of Drupal core?

# Answer
Best I can find on Google is that this header (and its companion header `'X-Speed-Cache'`) are added by a web server level module called "Speed Booster" touted as part of the Drupal Platform 'BOA': https://groups.drupal.org/node/173219 and https://omega8.cc/features .

The purpose of the header seems to be nothing more than a debug header to check which key has been used to retrieve the cached version in Speed Booster.

You probably want to contact your hosting company to see if they can disable that header.
> 0 votes

---
Tags: caching, security
---


title: Ajax not working in text field

text:
# Question
Title: Ajax not working in text field
I made custom module that implements `hook_form_alter` that marks the `field_text_field_1` textfield as `Ajax-enabled`. When a key is pressed inside the `field_text_field_1`, it should change the value in a second textfield: `field_text_field_2`.

```
$form['#prefix'] = '<div id="my_form_submit_wrapper">';
$form['#suffix'] = '</div>';

// $form['field_village']['#attributes']['id'] = 'edit-field-cities-wrapper';

$form['field_text_field_1']['widget']['#ajax'] =array(
    "callback" => "ajax_change1",
    'wrapper' => 'my_form_submit_wrapper',
    "event" => "change",
    "effect" => "fade",
);

```

The callback function:

```
function ajax_change1(array &$form, FormStateInterface $form_state){
      $form['field_text_field_2']['widget'][0]['value']['#value']='hello';
      return $form;
}

```

But it's not changing the value of \`field\_text\_field\_2 to "hello".

# Answer
You need to declare on what object (or class if static) to call the callback, like

```
'callback' => [get_called_class(), 'settingsAjax']

```

or

```
'#ajax' => [
            'callback' => [get_class($this), 'addMoreAjax'],
            'wrapper' => $wrapper_id,
            'effect' => 'fade',
          ],

```

or at least

```
'callback' => '::settingsAjax'

```

depending on your code.
> 1 votes

# Answer
> Don't change fields in the AJAX callback, the results won't be saved. Always change it in the form build based on a form state variable. - Clive

I think this is what he is referring to

```
$form['#prefix'] = '<div id="my_form_submit_wrapper">';
$form['#suffix'] = '</div>';

// $form['field_village']['#attributes']['id'] = 'edit-field-cities-wrapper';

$form['field_text_field_1']['widget']['#ajax'] =array(
    "callback" => '::ajax_change1',
    'wrapper' => 'my_form_submit_wrapper',
    "event" => "change",
    "effect" => "fade",
);

if (!empty($form_state->get('field_text_field_2')) {
    $form['field_text_field_2']['widget'][0]['value']['#default_value'] = $form_state->get('field_text_field_2');
}

function ajax_change1(array &$form, FormStateInterface $form_state){
    $form_state->set('field_text_field_2', 'hello');
    return $form;
}

```
> 0 votes

# Answer
What's wrong on my code i don't know. I have done this:

```
     $form['field_full_name']['#prefix']="<div id='email-id-validation'>";
     $form['field_full_name']['#suffix']='</div>';

      $form['field_email']['widget']['#ajax'] =array(
      "callback" => "ajax_change",
      'wrapper' => 'email-id-validation',
      "event" => "change",
      "effect" => "fade",
      );

```

And on callback i have done this code:

```
  function ajax_change(array &$form, FormStateInterface $form_state){
           $form['field_full_name']['widget'][0]['value']['#value']='hello';
       return $form;  }

```

Simply first i want to check if email field focus out than hello value is print on `$form['field_full_name']` or not.
> 0 votes

---
Tags: 8, hooks, ajax
---


# Question
Title: Update fails with undefined function system_rebuild_module_data in update.inc but the function is defined in system.module
When I run `drush updb` on my Drupal 8.3.1 site, I get:

> PHP Fatal error: Call to undefined function system\_rebuild\_module\_data() in /var/www/mysite/web/core/includes/update.inc on line 46

`system_rebuild_module_data()` is defined in web/core/modules/system.module on line 1102.

So I'm guessing this is not a bug in Drupal 8.3.1 given that it has been released; rather it must be something to do with my setup. Perhaps the PHP class autoloader or equivalent isn't working properly such that the function in system.module is not being made visible to update.inc.

Can you advise what the root cause might be and how I could overcome this fatal error stopping me running `drush updb`?

This is my composer.json file.

```
{
  "name": "my-site",
  "description": "My Site Website",
  "type": "project",
  "authors": [
    {
      "name": "",
      "role": ""
    }
  ],
  "repositories": [
    {
      "type": "composer",
      "url": "https://packages.drupal.org/8"
    },
    {
      "type": "composer",
      "url": "https://packagist.org"
    }
  ],
  "config": {
    "preferred-install": "source",
    "discard-changes": true
  },
  "require": {
    "composer/installers": "^1.0.20",
    "cweagans/composer-patches": "~1.0",
    "drupal/core": "8.3.1",
    "drush/drush": "8.1.2",
    "drupal/migrate_tools": "2.0.0-beta1",
    "drupal/migrate_upgrade": "2.0.0-beta1",
    "drupal/admin_toolbar": "1.19.0",
    "drupal/coder": "8.2.5",
    "drupal/libraries": "3.x-dev",
    "drupal/pathauto": " 1.0.0",
    "drupal/honeypot": "1.24.0",
    "drupal/metatag": "1.0.0",
    "drupal/mollom": "1.1.0",
    "drupal/smtp": "1.0.0-beta2",
    "drupal/token": "1.0.0",
    "drupal/simple_sitemap": "2.9.0",
    "drupal/google_analytics": "2.1.0",
    "wkse/google_tag": "8.0.2",
    "drupal/video_embed_media": "1.5.0",
    "drupal/video_embed_field": "1.5.0",
    "drupal/masquerade": "2.0.0-beta1",
    "drupal/paragraphs": "1.1.0",
    "drupal/slick": "1.0.0-rc3",
    "drupal/blazy":"1.0.0-rc1",
    "drupal/slick_extras": "1.0.0-beta2",
    "drupal/slick_media": "1.0.0-rc1",
    "drupal/responsive_menu": "2.4.0",
    "drupal/addtoany": "1.8.0",
    "drupal/videojs": "1.0.0",
    "drupal/redis": "1.0.0-beta1",
    "drupal/views_infinite_scroll": "1.3.0",
    "drupal/twig_tweak": "1.7.0",
    "drupal/maxlength": "1.0.0-beta1",
    "drupal/entity": "1.0.0-alpha4",
    "drupal/migrate_plus": "3.0.0-beta1",
    "drupal/focal_point": "1.0.0-beta4",
    "drupal/crop": "1.2.0",
    "mollom/client":"dev-psr4",
    "drupal/ctools": "3.0.0",
    "drupal/superfish": "1.0.0-rc6",
    "drupal/devel": "1.0.0-rc2"
  },
  "require-dev": {
    "behat/mink": "~1.6",
    "behat/mink-goutte-driver": "~1.2",
    "jcalderonzumba/gastonjs": "^1.1@dev",
    "jcalderonzumba/mink-phantomjs-driver": "~0.3.1",
    "mikey179/vfsStream": "~1.2",
    "phpunit/phpunit": "~4.8",
    "symfony/css-selector": "2.7.*"
  },
  "conflict": {
    "drupal/drupal": "*"
  },
  "prefer-stable": true,

  "scripts": {
    "post-install-cmd": "sh ./scripts/composer/post-install.sh"
  },
  "extra": {
    "installer-paths": {
      "web/core": ["type:drupal-core"],
      "web/modules/contrib/{$name}": ["type:drupal-module"],
      "web/profiles/contrib/{$name}": ["type:drupal-profile"],
      "web/themes/contrib/{$name}": ["type:drupal-theme"],
      "drush/contrib/{$name}": ["type:drupal-drush"]
    },
    "patches": {
      "drupal/core": {
        "Contextual links broken because of JS error": "web/modules/patches/core-js-fix-contextual.patch",
        "Fix quick edit contextual link not available and throwing js error": "web/modules/patches/drupalbehaviorerror.patch"
      }
    }
  }
}

```

This is the full stack trace that was outputted with the error at the terminal. I have included my Composer, Drush and PHP versions in the output.

```
[07:56 PM]-[vagrant@redisvmadded]-[/var/www/mysite.dev/web]-[git mysite_security_updates_apr2017]
$ drush updb
The following module is missing from the file system: minimal bootstrap.inc:240                                                                                [warning]
PHP Fatal error:  Call to undefined function system_rebuild_module_data() in /var/www/mysite.dev/web/core/includes/update.inc on line 46
PHP Stack trace:
PHP   1. {main}() /var/www/mysite.dev/vendor/drush/drush/drush.php:0
PHP   2. drush_main() /var/www/mysite.dev/vendor/drush/drush/drush.php:12
PHP   3. Drush\Boot\BaseBoot->bootstrap_and_dispatch() /var/www/mysite.dev/vendor/drush/drush/includes/preflight.inc:66
PHP   4. drush_dispatch() /var/www/mysite.dev/vendor/drush/drush/lib/Drush/Boot/BaseBoot.php:67
PHP   5. call_user_func_array:{/var/www/mysite.dev/vendor/drush/drush/includes/command.inc:185}() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:185
PHP   6. drush_command() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:185
PHP   7. _drush_invoke_hooks() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:217
PHP   8. call_user_func_array:{/var/www/mysite.dev/vendor/drush/drush/includes/command.inc:366}() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:366
PHP   9. drush_core_updatedb() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:366
PHP  10. update_main() /var/www/mysite.dev/vendor/drush/drush/commands/core/core.drush.inc:462
PHP  11. update_fix_compatibility() /var/www/mysite.dev/vendor/drush/drush/commands/core/drupal/update.inc:112
PHP  12. update_check_incompatibility() /var/www/mysite.dev/web/core/includes/update.inc:22

Fatal error: Call to undefined function system_rebuild_module_data() in /var/www/mysite.dev/web/core/includes/update.inc on line 46

Call Stack:
    0.0001     224136   1. {main}() /var/www/mysite.dev/vendor/drush/drush/drush.php:0
    0.0018     390448   2. drush_main() /var/www/mysite.dev/vendor/drush/drush/drush.php:12
    0.2686    9406544   3. Drush\Boot\BaseBoot->bootstrap_and_dispatch() /var/www/mysite.dev/vendor/drush/drush/includes/preflight.inc:66
    0.8071    8732656   4. drush_dispatch() /var/www/mysite.dev/vendor/drush/drush/lib/Drush/Boot/BaseBoot.php:67
    0.9030   11534768   5. call_user_func_array:{/var/www/mysite.dev/vendor/drush/drush/includes/command.inc:185}() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:185
    0.9030   11535120   6. drush_command() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:185
    0.9032   11540088   7. _drush_invoke_hooks() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:217
    0.9069   11583864   8. call_user_func_array:{/var/www/mysite.dev/vendor/drush/drush/includes/command.inc:366}() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:366
    0.9069   11584144   9. drush_core_updatedb() /var/www/mysite.dev/vendor/drush/drush/includes/command.inc:366
    0.9109   11771208  10. update_main() /var/www/mysite.dev/vendor/drush/drush/commands/core/core.drush.inc:462
    1.9984   26727888  11. update_fix_compatibility() /var/www/mysite.dev/vendor/drush/drush/commands/core/drupal/update.inc:112
    2.0147   26930512  12. update_check_incompatibility() /var/www/mysite.dev/web/core/includes/update.inc:22

Drush command terminated abnormally due to an unrecoverable error.                                                                                [error]
Error: Call to undefined function system_rebuild_module_data() in /var/www/mysite.dev/web/core/includes/update.inc, line 46

[07:56 PM]-[vagrant@redisvmadded]-[/var/www/mysite.dev/web]-[git mysite_security_updates_apr2017]
$ drush --version
 Drush Version   :  8.1.2

[08:13 PM]-[vagrant@redisvmadded]-[/var/www/mysite.dev]-[git mysite_security_updates_apr2017]
$ composer --version
Composer version 1.4.1 2017-03-10 09:29:45

[09:48 PM]-[vagrant@redisvmadded]-[/var/www/mysite.dev]-[git mysite_security_updates_apr2017]
$

[09:48 PM]-[vagrant@redisvmadded]-[/var/www/mysite.dev]-[git ou82_security_updates_apr2017]
$ php -v
PHP 5.6.30-7+deb.sury.org~trusty+1 (cli)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
with Xdebug v2.5.1, Copyright (c) 2002-2017, by Derick Rethans

```

I'm running the site locally inside a Vagrant/puphpet.com provisioned VM running Ubuntu 14.04 LTS 64bit on top of a Mac OS X Sierra 10.12.4 host.

# Answer
> 1 votes
We ran into exactly the same issue. It turns out it that our caches were broken as the host Drupal was running on was rebooted without Drupal having the chance to shutdown cleanly.

To resolve this we used Drush and simply ran `drush cr`. After this Drupal was back to normal.

# Answer
> 0 votes
It can happen if `drush updb` run from the parent of the docroot and it cannot see the docroot (docroot might be `web`)

```
cd docroot
drush updb

```

solved it for us. Some older installations can not see the docroot from the parent directory.

Perhaps one can also specify the root

```
drush updb --root=/var/www/example

```

# Answer
> 0 votes
This can happen when the files of installation profile of the site are missing.

Restore the files of the installation profile(s) it into `web/code/profile`, and rerun `drush updb`

---
Tags: drush, updating
---


# Question
Title: Showing local tasks in toolbar with hook_toolbar: caching problem
I'm creating a module using the toolbar api showing all administrative functions in a more compact toolbar. I'm having "cache" troubles showing the local tasks in the toolbar... How can I keep these items outside the toolbar cache?

In my custom module I use hook\_toolbar to add the local tasks

```
/**
 * Implements hook_toolbar().
 */
function compact_toolbar_toolbar() {

    $items = [];
    ...

    $tasks = _compact_toolbar_local_tasks();
    $items = array_merge($items,$tasks);

    return $items;
}

```

And a function to generate the toolbar local tasks...

```
/**
 * Create local tasks toolbar items
 */
function _compact_toolbar_local_tasks() {

    $items = [];
    $route = \Drupal::routeMatch()->getRouteName();
    $manager = \Drupal::service('plugin.manager.menu.local_task');
    $primary = $manager->getLocalTasks($route, 0);

    foreach($primary['tabs'] as $key => $tab) {

        // add toolbar tab
        $items[$key] = [
            '#type' => 'toolbar_item',
            '#cache' => [ // Can I overrule the toolbar cache here?
                'max-age' => 0,
            ],
            'tab' => [
                '#type' => 'link',
                '#title' => $tab['#link']['title'],
                '#url' => $tab['#link']['url'],
                '#access' => $tab['#access'],
                '#attributes' => [
                    'title' => $tab['#link']['title'],
                ],
            ],
            '#weight' => $tab['#weight'],
        ];

        // check if task is active
        if($tab['#active']) {
            $items[$key]['tab']['#attributes']['class'][] = 'is-active';
        }

        // get secondary tabs for each primary tab
        $route = $items[$key]['tab']['#url']->getRouteName();
        $secondary = $manager->getLocalTasks($route, 1);

        // get secondary tabs as tray
        if (!empty($secondary['tabs'])) {

            $links = [];
            $items[$key]['tab']['#attributes']['class'][] = 'toolbar-parent';

            // create renderable array of secondary links
            foreach ($secondary['tabs'] as $skey => $stab) {
                $sname = substr($skey, strrpos($key, '.') + 1);
                $links[$sname] = [
                    'type' => 'link',
                    'title' => $stab['#link']['title'],
                    'url' => $stab['#link']['url'],
                ];
            }

            // add tray with secondary tasks
            $items[$key]['tray'] = [
                '#heading' => t('Secondary tasks'),
                'toolbar_secondary_tasks' => [
                    '#theme' => 'links__toolbar',
                    '#links' => $links,
                    '#attributes' => ['class' => ['toolbar-menu']],
                ],
            ];

        }

    }

    return $items;
}

```

When I disable the cache in hook\_page\_top in core/modules/toolbar/toolbar.module everything works like a charm. Otherwise my custom items won't follow the current page...

```
/**
 * Implements hook_page_top().
 *
 * Add admin toolbar to the top of the page automatically.
 */
function toolbar_page_top(array &$page_top) {
  $page_top['toolbar'] = array(
    '#type' => 'toolbar',
    '#access' => \Drupal::currentUser()->hasPermission('access toolbar'),
    /*
    '#cache' => [
      'keys' => ['toolbar'],
      'contexts' => ['user.permissions'],
    ],
    */
  );
}

```

Can I overrule the toolbar cache by using the #cache array in my custom toolbar items? Which tags/context should I use?

This is how the toolbar looks like with my compact\_toolbar module enabled... (but toolbar cache disabled) I really like the result! - I also made the menu behave like a simple dropdown menu and added a "content menu" to quickly add new content...

# Answer
> 0 votes
"The toolbar is a container for administrative and site-global interactive components."

https://api.drupal.org/api/drupal/core!modules!toolbar!toolbar.api.php/function/hook\_toolbar/8.2.x

That would indicate that the toolbar is not the solution you are looking for as the more contextual tabs are not site global but page specific.

# Answer
> 0 votes
For anyone stumbling across this, the following worked for me:

```
'#cache' => [
   'contexts' => [
     'url.path',
   ],
 ],

```

The key is to look at the available cache contexts, in this case, setting by URL.

So example including above would be:

```
 $items[$key]['tray'] = [
 '#heading' => t('Secondary tasks'),
 'toolbar_secondary_tasks' => [
   '#theme' => 'links__toolbar',
   '#links' => $links,
   '#attributes' => ['class' => ['toolbar-menu']],
 ],
 '#cache' => [
   'contexts' => [
    'url.path',
   ],
 ],

```

\];

---
Tags: 8, caching, toolbar
---


title: How do I run hook_views_data_alter()?

text:
# Question
Title: How do I run hook_views_data_alter()?
So I have already read and followed everything I could find on that issue:

1. putting my\_module\_views\_data\_alter(array &$data) in my\_module.views.inc file in the root directory of my\_module,
2. disabling cache for my view,
3. clearing caches million times,

but still I can never stop at a breakpoint inside this hook, nor can I see any effects of the code I have put in it.

What am I missing?

**EDIT: updating with some code**

In my\_module I have already created a computed field user\_age, calculating user age from a custom user profile field with date of birth.

**my\_module/my\_module.module**

```
function my_module_entity_base_field_info(EntityTypeInterface $entity_type) {
  if ($entity_type->id() === 'user') {
    $fields = [];
    $fields['user_age'] = BaseFieldDefinition::create('user_age_field')
      ->setName('user_age')
      ->setLabel(t('User age'))
      ->setComputed(TRUE)
      ->setClass('\Drupal\my_module\UserAgeIntegerItemList')
      ->setDisplayConfigurable('view', TRUE)
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'weight' => -5,
      ]);

    return $fields;
  }
}
function my_module_field_formatter_info_alter(array &$info) {
  $info['number_integer']['field_types'][] = 'user_age_field';
}

```

This field is working and is accessible in my user profile template.

Knowing that since Drupal 8.4

> Computed fields can now be displayed by Views

I wanted to use field user\_age as an exposed filter in my search\_users view:

**my\_module/my\_module.views.inc**

```
/**
 * Implements hook_views_data_alter().
 */
function my_module_views_data_alter(array &$data) {
  if (isset($data['users_field_data'])) {
    $data['users_field_data']['user_age'] = [
      'title' => t('User age'),
      'field' => [
        'id' => 'my_module_view_user_age',
      ],
    ];
  }
}

```

**my\_module/src/Plugin/views/field/MyModuleViewUserAge.php**

```
<?php

namespace Drupal\my_module\Plugin\views\field;

use Drupal\views\ResultRow;
use Drupal\views\Plugin\views\field\FieldPluginBase;

/**
 * A handler to provide proper displays for user user_age.
 *
 * @ingroup views_field_handlers
 *
 * @ViewsField("my_module_view_user_age")
 */
class MyModuleViewUserAge extends FieldPluginBase {

  /**
   * {@inheritdoc}
   */
  public function render(ResultRow $values) {
    $relationship_entities = $values->_relationship_entities;
    $age = '';
    // First check the referenced entity.
    if (isset($relationship_entities['user'])) {
      $user = $relationship_entities['user'];
    }
    else {
      $user = $values->_entity;
    }

    $type = get_class($user);
    if ($type === 'Drupal\user\Entity\User') {
      $age = $user->get('user_age')->getvalue();
    }

    return $age;
  }

  /**
   * {@inheritdoc}
   */
  public function query() {
    // This function exists to override parent query function.
    // Do nothing.
  }
}

```

but my\_module\_views\_data\_alter() seems to never be executed and user\_age field is not present in the filter criteria for my view.

# Answer
You can't xdebug in hook itself, you need to go to method calling this hooks which is in **class ViewsData** path /core/modules/views/src/ViewsData.php and put breakpoint in getData, clear cache and you will get what you need.
> 4 votes

# Answer
we should empty cache\_default table. The only way I know is by MYSQL "**TRUNCATE cache\_default**"
> 1 votes

# Answer
Here is an example MYMODULE.views.inc I've used recently in a module:

```
/**
 * Implements hook_views_data().
 */
function MYMODULE_views_data() {

  $data['schema_name']['nid'] = [
    'title' => t('NID'),
    'help' => t('NID from schema_name'),
    'field' => [
      'handler' => 'views_handler_field_numeric',
      'click sortable' => TRUE,
      'float' => TRUE,
      'id' => 'numeric',
    ],
    'relationship' => [
      'title' => 'NID',
      'label' => t('NID'),
      'help' => t('NID from schema_name'),
      'id' => 'standard',
      'base' => 'node',
      'base field' => 'nid',
      'relationship field' => 'nid',
      'handler' => 'views_handler_relationship',
    ],
    'sort' => [
      'id' => 'standard',
    ],
    'filter' => [
      'id' => 'numeric',
    ],
    'argument' => [
      'id' => 'numeric',
    ],
  ];

  return $data;

}

```

Some things I don't see in your code:

1. no `handler` for the views field
2. no `filter` or `sort` key for your field
3. not printing `return $data;` in your views.inc file

I know this is not a *direct answer*, but hoping it helps.
> 0 votes

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


# Question
Title: How to hide a webform field from a node display when the per-user submission limit has been reached
I have a Webform field on my node, which links to an application form. The form is set to allow one submission per user (per node). I want the link to disappear after the user has submitted the form.

Any good ways to do this?

# Answer
> 1 votes
You can try to implement hook\_entity\_field\_access

```
function hook_entity_field_access($operation, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Session\AccountInterface $account, \Drupal\Core\Field\FieldItemListInterface $items = NULL) {
  if ($field_definition->getName() === 'field_registration_form' && $operation === 'view') {
  $webform = Webform::load('WEBFORM_ID');
  // Using webform config entity to check submission create.
  $access_result = $webform->access('submission_create', $account, TRUE);
  // Adding the current account as a cacheable dependency and the 'webform_submission_list' cache tag
  // to keep track of any new submission per user.
  $access_result->addCacheableDependency($account)
  ->addCacheTags('webform_submission_list');
  return $access_result;
  }
  return AccessResult::neutral();
}

```

# Answer
> 0 votes
This works (below, added to MY\_THEME.theme), but I haven't stress-tested it:

```
function TEMPLATE_preprocess_node(&$variables) {
  // Hide field_registration_form if already submitted to it.
  if($variables['node']->bundle() == 'CONTENT_TYPE') {
    $current_user = \Drupal::currentUser();
    $uid = $current_user->id();
    $webform = Webform::load('WEBFORM_ID');
    if ($webform->hasSubmissions()) {
      $query = \Drupal::entityQuery('webform_submission')
        ->condition('webform_id', 'WEBFORM_ID');
      $result = $query->execute();
      $submission_data = [];
      foreach ($result as $item) {
        $submission = \Drupal\webform\Entity\WebformSubmission::load($item);
        $submission_data[] = $submission->getData()['user'];
      }
      if (in_array($uid, $submission_data)) {
        unset($variables['content']['field_registration_form']);
      }
    }
  }
}

```

---
Tags: 8, webforms
---


# Question
Title: How do I modify the URL to a taxonomy term?
I have a vocabulary called Industry with four terms. I have edited the terms to keep the URL to be automatically generated. They are following this convention:

```
industry/term1, industry/term2, etc...

```

I want the convention to be (without the "industry/"):

```
term1, term2, etc...

```

I configured the URL alias patterns like so for Taxonomy Term paths:

**Default pattern:** \[term:vocabulary\]/\[term:name\]

**Pattern for all *Industry* paths:** \[term:name\]

However, when I navigate to the URL (i.e. /term1), I get this message:

```
The requested page "/term1" could not be found.

```

On top of that, I have a view for a block that generates this vocabulary as a list with the links so users can click on them and go to the taxonomy page. I have the option selected for each term:name that we need to "Link this field to its taxonomy term page". When that block is rendered, it generates a URL like so:

```
[term:vocabulary]/[term:name]

```

This is not what I expected. I expected the URL to be `[term:name]`. I am new to Drupal and still learning things about it. What am I doing wrong?

# Answer
Please check if you have a URL Alias in the system for "/term1".

It might be mostly the case of all your old Alias existing in the system not the new once. If you don't find the update URL alias under admin/config/search/path. Then it just a simple bulk regenerate (admin/config/search/path/update\_bulk).

Please ensure you have selected

* Taxonomy term
* Update the URL alias for paths having an old URL alias (at Times you may want to use the option Regenerate URL aliases for all paths)
> 1 votes

---
Tags: views, taxonomy-terms, path-aliases
---


# Question
Title: How can I get single keys in multi-item config objects using debug:config?
For example, in drush I can run

`drush cget search_api.server.iges_solr backend_config.connector_config.port`

and get a useful answer.

(`'search_api.server.iges_solr:backend_config.connector_config.port': 8988`)

In Drupal Console, I've tried the same formatting as in the drush command, I've tried a colon between the main config item, and the sub item

(`drupal dc search_api.server.iges_solr:backend_config.connector_config.port`)

I've tried a fair number of other things, and I've read the docs to no avail. Is it possible to do without just grepping?

# Answer
No, Drupal Console doesn't support selecting a key from a configuration object. This is clear from `drupal help debug:config` which even mention grepping.

Using grep isn't beautiful, but it works:

```
drupal debug:config system.date | grep -A1 timezone

```

does return the timezone with the first subkey. (Changing the value after A, you get more lines/the user subkey.)

I would of course prefer to get the configuration object as proper JSON and then pipe it to jq to select a key robustly, but Drupal Console doesn't support an output format option yet - see Github issue.
> 2 votes

---
Tags: 8, console
---


# Question
Title: Why all core services cannot be registered in core.services.yaml?
> DrupalKernel
> Building of Dependency Injection Container and registration of Service Providers Core provides the CoreServiceProvider, which, in addition to registering any core services that cannot be registered in the core.services.yaml file, adds any compiler passes needed by core, e.g. for processing tagged services. Each module can add its own service provider, i.e. a class implementing Drupal\Core\DependencyInjection\ServiceProvider, to register services to the container, or modify existing services.

Why cannot all the core services be registered in core.services.yaml?
Why do we need a service provider class to register services or modify existing services, when we can register services in module.services.yml?

# Answer
> Why cannot all the core services be registered in core.services.yaml?
>
> Why do we need a service provider class to register services or modify existing services, when we can register services in module.services.yml?

I think the answer to both these questions is that likely some of the services are dynamic. Yaml files can only be used for static registration of services.
> 1 votes

---
Tags: 8, symfony-services
---


# Question
Title: I would like to create a field type "Time"
not within or as a date. If I use a number field, I'm not able to display a colon instead of comma or decimal dot.

How would you solve this problem?

# Answer
I recommend using the Time Field module which provides a time field for you.

> TimeField for Drupal 8 solves displaying and submitting time and time-range for Drupal site.
> 2 votes

---
Tags: datetime
---


title: JOIN subquery as right table in Views

text:
# Question
Title: JOIN subquery as right table in Views
I have a node field named `event_date` which contains multiple values of dates.

The table for the field looks like this:

```
node__field_event_date
+----------------+------------+
| entity_id(nid) | event_date |
+----------------+------------+
|              1 | 2019-1-1   |
|              1 | 2019-1-2   |
|              2 | 2019-1-3   |
|              2 | 2019-1-4   |
+----------------+------------+

```

I would like to join only **earliest** `event_date` for each node to the node base table(`node_field_data`).

```
node_field_data(short version)
+-----+--------+
| nid | title  |
+-----+--------+
|   1 | event1 |
|   2 | event2 |
+-----+--------+

```

The ideal result is:

```
+-----+--------+----------------+-------------------+
| nid | title  | entity_id(nid) | EarliestEventDate |
+-----+--------+----------------+-------------------+
|   1 | event1 |              1 | 2019-1-1          |
|   2 | event2 |              2 | 2019-1-3          |
+-----+--------+----------------+-------------------+

```

In raw sql, it can be written like this:

```
SELECT * FROM `node_field_data`
INNER JOIN (
  SELECT entity_id, MIN(field_event_date) AS EarliestEventDate
  FROM node__field_event_date
  GROUP BY entity_id
) AS event_date
ON node_field_data.nid = event_date.entity_id

```

But the problem is, the join should be done as a part of query for a View.

I tried the code below, but the Views didn't parse the subquery at all.

```
// in MY_MODULE.module

/**
 * Implements hook_views_query_alter().
 */
function MY_MODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() === 'events') {

    $subquery = "(SELECT entity_id, MIN(field_event_date_value) AS EarliestEventDate FROM node__field_event_date GROUP BY entity_id) AS node__field_event_date";

    $definition = [
      'table' => $subquery,
      'field' => 'entity_id',
      'left_table' => 'node_field_data',
      'left_field' => 'nid',
    ];

    $join = Drupal::service('plugin.manager.views.join')->createInstance('standard', $definition);
    $query->addRelationship('event_date', $join, 'node_field_data');
  }
}

```

What appeared on SQL preview in the view editing page:

```
LEFT JOIN {SELECTentity_idMINfield_event_date_valueASEarliestEventDateFROMnode__field_event_dateGROUPBYentity_idASnode__field_event_date} event_date ON node_field_data.nid = event_date.entity_id

```

Maybe I should try Views Plugin? But I don't have much experience making it and have no idea plugins can accept subquery like this.

If anyone have thoughts or ideas please give me advice...

# Answer
It worked (in views plugin).

```
// create subquery using database api
$sub_query = \Drupal::database()->select('node__field_event_date', 'n');
    $sub_query->addField('n', 'entity_id');
    $sub_query->addExpression("MIN(n.field_event_date_value)", 'EarliestEventDate');
    $sub_query->groupBy("n.entity_id");

// create join
$join_definition = [
      'table formula' => $sub_query,
      'field' => 'entity_id',
      'left_table' => 'node_field_data',
      'left_field' => 'nid',
      'adjust' => TRUE,
    ];
$join = $this->joinManager->createInstance('standard', $join_definition);
$this->query->addRelationship('event_date', $join, 'node_field_data');

```

Edit: If you do the same thing in hook\_query\_alter, change the last two lines like this.

```
$join = Drupal::service('plugin.manager.views.join')->createInstance('standard', $join_definition);
$query->addRelationship('event_date', $join, 'node_field_data');

```
> 6 votes

---
Tags: 8
---


# Question
Title: How can I inject container to a class with constructor having arguments?
> Fatal error: Declaration of Drupal\migrate\_upgrade\MigrateUpgradeDrushRunner::create(Psr\Container\ContainerInterface $container, $options = Array) must be compatible with Drupal\Core\DependencyInjection\ContainerInjectionInterface::create(Symfony\Component\DependencyInjection\ContainerInterface $container)

Below is `MigrateUpgradeCommands.php` file where I am creating an instance of new MigrateUpgradeDrushRunner() and passing two arguments `$options` and `$this->logger`

```
    class MigrateUpgradeCommands extends DrushCommands {
    /**
       * Logger service.
       *
       * @var \Drupal\Core\Logger\LoggerChannelInterface
       */
      protected $logger;

      /**
       * MigrateUpgradeCommands constructor.
       *
       * @param \Drupal\Core\State\StateInterface $state
       *   State service.
       * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerChannelFactoryInterface
       *   The logger.factory service.
       */
      public function __construct(StateInterface $state, LoggerChannelFactoryInterface $loggerFactory) {
        $this->state = $state;
        $this->logger = $loggerFactory->get('drush');
      }
/**
   * Perform one or more upgrade processes.
   *
   * @command migrate:upgrade
   *
   * @usage drush migrate-upgrade --legacy-db-url='mysql://root:pass@127.0.0.1/d6'
   *   Upgrade a Drupal 6 database to Drupal 8
   * @usage drush migrate-upgrade --legacy-db-key='drupal_7'
   *   Upgrade Drupal 7 database where the connection to Drupal 7 has already
   * been created in settings.php ($databases['drupal_7'])
   * @usage drush migrate-upgrade --legacy-db-url='mysql://root:pass@127.0.0.1/d7' --configure-only --migration-prefix=d7_custom_ --legacy-root=https://www.example.com
   *   Generate migrations for a custom migration from Drupal 7 to Drupal 8
   *
   * @validate-module-enabled migrate_upgrade
   *
   * @aliases migrate-upgrade, mup
   *
   * @throws \Exception
   *   When an error occurs.
   */
  public function upgrade(array $options = []) {
    $runner = new MigrateUpgradeDrushRunner($options, $this->logger);

    $runner->configure();
    if ($options['configure-only']) {
      $runner->export();
    }
    else {
      $runner->import();
      $this->state->set('migrate_drupal_ui.performed', \Drupal::time()->getRequestTime());
    }
    // Remove the global database state.
    $this->state->delete('migrate.fallback_state_key');
  }

    }

```

Now file MigrateUpgradeDrushRunner.php

```
class MigrateUpgradeDrushRunner implements ContainerInjectionInterface {
  /**
   * Logger channel.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $logger;

  public static function create(ContainerInterface $container, $options = []) {
    return new static(
      $container->get('logger.factory'),
      $options
    );
  }

  /**
   * MigrateUpgradeDrushRunner constructor.
   *
   * @param array $options
   *   Drush options parameters.
   * @param \Drupal\Core\Logger\LoggerChannelInterface $logger
   *   Drush logger.
   */
  public function __construct(array $options = [], LoggerChannelInterface $logger) {
    $this->setOptions($options);
    $this->logger = $logger;
  }

}

```

Basically, how can I inject Container into `MigrateUpgradeDrushRunner` so that I can fetch logger.factory service and pass it in the construct ?

# Answer
Instead of adding `$options` to your create method you shall add a method to set the options.

Take a look at this code to see how you can inject `$logger` in your class:

```
class MigrateUpgradeDrushRunner implements ContainerInjectionInterface {

  /**
   * The logger channel factory.
   *
   * @var LoggerChannelFactoryInterface
   */
  protected $logger;

  /**
   * The options.
   *
   * @var array
   */
  protected $options = [];

  /**
   * MigrateUpgradeDrushRunner constructor.
   *
   * @param LoggerChannelFactoryInterface $logger
   *   The logger channel factory.
   */
  public function __construct(LoggerChannelFactoryInterface $logger) {
    $this->logger = $logger;
  }

  /**
   * {@inheritDoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('logger.factory')
    );
  }

  /**
   * Set the options.
   *
   * @params array $options
   *   The options.
   */
  public function setOptions(array $options) {
    // Do something...
  }

}

```
> 3 votes

# Answer
There are too many possible answers because you can inject dependencies in different ways. Normally Drupal uses the container injecting method for Controllers and Plugins, but your class is neither of it. So it is unclear what you are trying to achieve.

You can however use this also for other classes, like this utility class to update config entities. Then you have to use the class resolver to instantiate the class, which you see in the annotations of the class:

```
namespace Drupal\Core\Config\Entity;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * A utility class to make updating configuration entities simple.
 *
 * Use this in a post update function like so:
 * @code
 * // Ensure Taxonomy module installed before trying to update vocabularies.
 * if (\Drupal::moduleHandler()->moduleExists('taxonomy')) {
 *   // Update the dependencies of all Vocabulary configuration entities.
 *   \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'taxonomy_vocabulary');
 * }
 * @endcode
 *
 * The number of entities processed in each batch is determined by the
 * 'entity_update_batch_size' setting.
 *
 * @see default.settings.php
 */
class ConfigEntityUpdater implements ContainerInjectionInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The number of entities to process in each batch.
   * @var int
   */
  protected $batchSize;

  /**
   * ConfigEntityUpdater constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param int $batch_size
   *   The number of entities to process in each batch.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, $batch_size) {
    $this->entityTypeManager = $entity_type_manager;
    $this->batchSize = $batch_size;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('settings')->get('entity_update_batch_size', 50)
    );
  }

  ...

}

```
> 3 votes

---
Tags: 8, migrations, dependency-injection
---