title: Installing modules without FTP

text:
# Question
Title: Installing modules without FTP
So I have installed the latest Drupal 7 stable on my new server, and it asks for an FTP user/password every time I try to install a new module from a .zip file. (Or using an URL).

The problem is that I don't have an FTP installed on the machine, and I don't really want to install one. I'm pretty sure this is related to some configuration/permission, but I'm not sure where to start. Tried searching around about the question, but only found "random" answers. Nothing clean and/or official.

# Answer
> 8 votes
It is a permissions issue...basically your web server needs permission to write to 'sites/all/modules' for Drupal to be able to get the new module folder there without using FTP.

However, it's a security risk to do this, so if your server is already configured in such a way that *stops* the apache/php daemons from writing to those folders you should keep it that way.

The better way to install modules automatically in Drupal is to use the Drush command line tool. You can issue a couple of commands:

```
drush dl views
drush en views

```

And the module will be automatically downloaded and installed on your site. Drush is infinitely more powerful than that (you can perform all sorts of administration tasks easily from the command line) so if you haven't come across it before I'd thoroughly recommend giving it a go.

# Answer
> 2 votes
1. move with the shell to the parent root where your site is for example `cd /var/www`
2. give proper permission to the directory where your site is:

`chown -R www-data {your_directory_name_here}`

example `chown -R www-data Drupal`

reference: http://allabouttodd.com/ecommerce/drupal-7-update-manager-unable-connect-ftp

I hope it helps!

# Answer
> 0 votes
This can happen when `sites/default` folder is not owned by the user that executes the install script. Make sure the folder `sites/default` is **owned** by the apache user (from your drupal root) and modules will be installed without asking for FTP credentials:

*Ubuntu*:

```
chown www-data sites/default

```

*Fedora*:

```
chown apache sites/default

```

# Answer
> -1 votes
I had the same problem before I started using drush to install, enable, and manage themes and modules. Try these commands from the terminal.

```
drush dl;
drush en;
drush cc all;

```

---
Tags: files
---


# Question
Title: Drush migration no longer working in 8.5
I've been migrating a site from Drupal 7 to Drupal 8. The site was 8.4 when I ran the migrations. I've since updated the site to Drupal 8.5. Now, when I type `drush migration-status` or any migration-related command, I get the following error:

```
[error]  The file_entity plugin must define the source_module property.

```

# Answer
Ok answering this myself. I keep forgetting that Drupal often introduces breaking changes and treats comments as code. It looks like the annotation changed in 8.5

What was in 8.4:

```
/**
 * Drupal 7 file_entity source from database.
 *
 * @MigrateSource(
 *   id = "file_entity",
 *   source_provider = "file"
 * )
 */

```

in 8.5 should now be:

```
/**
 * Drupal 7 file_entity source from database.
 *
 * @MigrateSource(
 *   id = "file_entity",
 *   source_module = "file",
 * )
 */

```
> 0 votes

---
Tags: 8, drush, migrations
---


# Question
Title: Why doesn't a cloned theme work as the original theme?
I've cloned a theme, by duplicating and renaming it, in /sites/all/themes/. When I switch to the new theme, portions of the theme, a slideshow, don't work.

It looks like `views_get_view_result()` in template.php is not returning anything. Is there some configuration I need to set up per theme?

I'm new to Drupal and I am helping out a friend. The site is using Drupal 7.

# Answer
In `template.php` the functions that begin with the template name e.g. `themename_preprocess_page` need to be renamed to have the new theme name in them e.g. `newthemename_preprocess_page`.
> 0 votes

---
Tags: 7
---


title: White screen after deleting a module

text:
# Question
Title: White screen after deleting a module
I have a white screen "The website encountered an unexpected error.". The "update.php" is not working.

I deleted a module that still was installed (big mistake). I moved the module back into the folder. But has the white screen. The watchdog table in SQL says that the used module is still missing.

Is there a chance to fix this?

Maybe in SQL? (I use Sequel Pro in place of myPHPadmin). Installing Drush seems to be complicated. I'm no programmer but a little experienced in coding with Drupal.

I looked many links online, but did not found the right solution. Thank you.

# Answer
If you deleted and returned a module to its original place, then all it takes for the website to start working normally again is to get cache refreshed, which will bootstrap it.

You can do it by:

1. Running the `update.php` file. Make sure to set `$settings['update_free_access'] = TRUE;` on the settings.php file.
2. Using `drush`. Installing drush is not as complicated as it might sound. Just follow instructions on http://docs.drush.org/en/master/install.
3. By clearing cache tables directly in the database. Just use some kind of user interface for the database like, for example, phpMyAdmin, open the website's database and truncate all the tables starting with `cache`.
4. If none of the above methods works, then try to uninstall and re-install the module or manually remove all database references to the fields which were created by the module.
> 2 votes

---
Tags: 8, database
---


# Question
Title: Create update table of features vs plans
I am looking for a way to achieve this with minimum custom module work.

Imagine a table with features listed down the left, and the plan names are going across the top as headings. Where these columns and rows meet is an icon to say whether this plan has that specific feature.

The ability to add new features needs to be possible easily through Drupal.

I was thinking of creating a plan content type and then the feature could be a field collection with a boolean, and some other data (a booleon on its own is not sufficient).

The issue with this is that you can't reuse field collections, so that would mean creating a field collection for each feature, not very user friendly and too much work for the end-user when they have to add a booleon, and a couple of other fields, also the template file would need to be modified to allow for this new field.

My next thought was to set the field collection as unlimited and then have the features as taxonomy terms, to then use hook\_form\_alter to first pull in the taxonomy terms and then pre-populate a term reference field for each instance of the field collection.

However this gets a little complicated when you think about a scenario in which someone adds a new feature as a taxonomy term. The custom module would need to look at the fields on the node in the field collections and check to see if the term exists already.

Maybe this would work, but is there a better way?

# Answer
> 0 votes
You might want to give a try to Editable Views module. So you would create a view page with columns and rows as you desire, making all the fields editable. Then you could change any field value (boolean if checkbox is used) just in place.

---
Tags: forms
---


# Question
Title: How do I set up Search API index as cron task?
From what I've read in Search API's settings, it sounds like pages should be indexing when cron is ran. This doesn't seem to be the case, but perhaps my logic is flawed.

I help manage a blog/news site. All of the content is indexed through search API, and I'm rendering lists of that indexed content using Views. One View display renders a list of the site's most popular content. This is calculated using the Statistics module. You can see here that I'm sorting this view using the `Number of views` field:

Initially, I didn't think that the sort criteria was working at all. I added the `Number of views` to the rendered output for testing, and found that the pages weren't being reordered when the page views changes.

However, I eventually discovered that the nodes will reorder, only after Search API is reindexed manually. Currently, Search API is set to index nodes immediately upon publishing, but I'm assuming that a full reindex does not occur when this happening. I tested this by creating a new node, and found that the order of nodes did not update. I've also run Cron manually, and have found that this does not work either.

Now, I'm of the impression that Search API is not reindexing when running Cron, but I'm unsure if this is a valid assumption. If it's not, I'd like to set up a nightly reindexing. How do I go about writing this cron task?

# Answer
You are right insofar as a node will only get reindexed when it is updated. Someone viewing the node isn't seen as an update, so incrementing the number of views won't cause the node to be reindexed.

It's not normal to rebuild the entire index on a schedule. Cron only re-indexes those nodes that have been marked as needing to be indexed.

There are two ways I can think of you might schedule a nightly rebuild of the index.

1. If you have access to the server at command line level you could run the drush command "search-api-reindex" via a custom cron job. Run it as the same user as the web-server (eg. apache or www-user) and use the -l option to specify the url so the cron line would be something like: `0 23 * * * cd /var/www/home && drush sapi-r default`
2. Otherwise you could write your own cron hook in a custom module to do the same. The module elysia\_cron would help with scheduling it for the right time. You'd need to call `search_api_index_reindex('default');` to have the same effect as the cron job in point 1.
> 2 votes

---
Tags: 7, views, search, cron, nodes
---


# Question
Title: How do I print the node title from the object?
How do I print the title of a node entity? Printing the node object, I get this output.

```
stdClass Object
(
    [__CLASS__] => Drupal\node\Entity\Node
    [in_preview] =>
    [values] => Array
        (
            [vid] => Array
                (
                    [x-default] => 2
                )

            [nid] => Array
                (
                    [x-default] => 2
                )

            [type] => Array
                (
                    [x-default] => common
                )

            [title] => Array
                (
                    [x-default] => Terms of Use
                )
}

```

# Answer
Are you in a twig template rendering a node? If so:

`{{ label }}` or `{{ node.label }}`

Via code in PHP:

`$node->label();` via `label()` and/or also `$node->getTitle();` via `getTitle()`
> 15 votes

# Answer
Tested: look for your node--.html.twig file, find the {{ content }}, then add this above or below, or anywhere you like to print the title: {{ node.label }}, it will show the current page/node title in your template, make sure you empty your cache to see the changes.
> 0 votes

---
Tags: 8, nodes
---


# Question
Title: Drupal Views converts Twig variable to zero when performing operations
I have a Drupal 8 view that has a counter in it. I want to have one behavior when the counter is odd and a different behavior in the counter is even. However, the counter is always evaluated as even. Here's some code:

```

Counter: {{ counter }}
Counter is even: {{ counter is even }}
Counter is odd: {{ counter is odd }}

{% set foo = (counter + 0) %}

Foo: {{ foo }}
Foo is even: {{ foo is even }}
Foo is odd: {{ foo is odd }}

```

And the output:

```
Counter: 1
Counter is even: 1
Counter is odd:

Foo: 0
Foo is even: 1
Foo is odd:

Counter: 2
Counter is even: 1
Counter is odd:

Foo: 0
Foo is even: 1
Foo is odd:

Counter: 3
Counter is even: 1
Counter is odd:

Foo: 0
Foo is even: 1
Foo is odd:

Counter: 4
Counter is even: 1
Counter is odd:

Foo: 0
Foo is even: 1
Foo is odd:

```

As you can see, the counter is counting up. But, as foo demonstrates, whenever math is done on counter, it's always zero, so it always evaluates as even.

I've done counter.value as well, which doesn't change the fact that counter always registers as zero whenever there is an operation done on it. The output of dump(counter) is zero.

So, the question is: Why does counter always evaluate as zero and therefore even, although it's clearly counting up?

EDIT: It seems like the counter was coming through as something that would just always turn to zero when put into twig operations. We were able to fix the problem by adding a render function to the views core module, to return an integer value and not the array or whatever was being returned before.

# Answer
> 0 votes
"The output of dump(counter) is zero" ... I think you don't have the twig debug environment enabled, otherwise you should see an array, for example with a `#markup` key inside:

```
{% set counter_value = counter['#markup'] %}

```

---
Tags: views, theming
---


# Question
Title: How to handle a Drupal core change that have an impact in the next release of a contrib module?
Reading the Drupal Changes records I found that drupal\_get\_message() and drupal\_set\_message() replaced by Messenger service so lets suppose that I have a module that use the `drupal_get_message()` function and I want to replace it with the new Messenger service. If I do it my module only will works starting from Drupal Core \>= 8.5.

So, in this point what is the correct way to produce the next module release?

Should I restrict the next release to a specific Core version adding a comment in the release notes or should I create a new branch (lets says 8.x-2.x) to implement this changes and have two module versions like 8.x-1.x (working for Core \< 8.5) and 8.x-2.x (working for Core \>= 8.5)?

# Answer
> 4 votes
There is no need for a new branch in your module as long as your own API doesn't change IMHO. The version definition will prevent that users update too early.
There is also no need to continue providing versions compatible with old core versions, they are no longer supported.

If it's just about deprecated usages, there's no reason to hurry, you can easily wait a few month/next core minor before starting to use it to give your users time to update. All those deprecated functions will only be removed in the 9.x branch, so you have plenty of time to update. It's different if core broke something in your module and you're forced to update asap or if there is a completely new API that you'd want to use.

See also last paragraph on PHP 7.1 requirement for Doctrine packages: Their PHP version dependency is similar to your Drupal core dependency.

---
Tags: 8, community-official-site
---


# Question
Title: Why the path alias is like http://domain/http://domain/path?
Adding a simple alias for media \[media:url\] causes the domain to be listed twice in the URL on media listing page in admin, for example http://domain/http://domain/path. How do I change it to http://domain/path?

# Answer
I ended up using a different token which fixed the issue. I believe using token URL in the URL field is the cause of the double URLs.
> 0 votes

---
Tags: path-aliases
---


# Question
Title: How to grant referenced user access to Profile page
I use Node access user reference module in many projects. I have a very similar task: Grant access to a profile page for those user who is referenced in that profile. Unfortunately, Node access user reference doesn't work in this case, since it's not a node but a different kind of entity. Is there any solution for this task?

# Answer
> 1 votes
Here is ready to use code. For this to work you need to enable the Entity reference module, add entity reference field on `admin/config/people/accounts/fields` page targeting user entity and setting to unlimited, and finally giving access to `View user profiles` to all `authenticated user` role members.

Create `my_module.info` file and paste:

```
name = My Module
description = Does awesome things. Makes tea. Washes up. Favours of a personal nature.
dependencies[] = entityreference
core = 7.x

```

Create my\_module.module file and paste:

```
/**
 * Implements hook_user_view_alter().
 */
function my_module_user_view_alter(&$build) {
  global $user;
  if ($build['#account']->uid == $user->uid || in_array('administrator', array_values($user->roles))) {
    // Return early if user is administrator or is at their own profile.
    return;
  } elseif (isset($build['field_users'])) {
    foreach ($build['field_users']['#object']->field_users[LANGUAGE_NONE] as $key => $referenced) {
      if ($user->uid == $referenced['target_id']) {
        return;
      }
    }
  }
  drupal_access_denied();
}

```

Go to a user profile, add some user references and try to view that user's profile as the referenced user to gain access and then as non-referenced user to get denied access.

---
Tags: 7, users, entities
---


# Question
Title: Are there alternatives to using URL to Image Formatter?
We had a need to set an image as a background element for a `<div>` tag (see example below). When we tried to the following (with Image as formatter) it only returned the original image url, not the image URL based on the image style.

Without having to use preprocess hooks to modify the URL, we have set the display formatter to be "URL to Image" on the default View Mode and we get the desired results. If I want to use Image formatter, I had to write a preprocess hook, which I want to avoid and adding an additional module like twig\_tweak seems over complicating it.

Are there any other alternatives to using the URL to Image formatter and `{{ content.field_image.0['#markup] }}` without having to use a preprocess hook?

Example using Image formatter

```
{{ content.field_image.entity.uri.value }}

```

Results

```
<div style="background-image: url('/sites/default/files/original-image-url.png')"></div>

```

Example using "URL to Image" formatter

```
{{ content.field_image.0['#markup] }}

```

Results (desired results)

```
<div style="background-image: url('/sites/default/files/styles/extra-large/public/original-image-url.png')"></div>

```

---

Alternative solution

This looks like it will get the url to image with image style.

1. Set formatter as URL to Image
2. in twig template use `{{ content.field_image.0 }}`

# Answer
> 2 votes
Background Image Formatter provides a new formatter that can do this. You will probably want a unique identifier on your target div, but this module should do the trick otherwise. There's a responsive\_bg\_image\_formatter submodule for using responsive image styles for your bg image.

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


# Question
Title: FormState getValue on checkbox elements in hierarchical / tabular form structures broken?
I can't seem to retrieve correct posted checkbox form element values using an array-style key in a call to the `FormState::getValue` method. If I flatten the elements into a non-nested structure, the getValue method works. But, I need to lay out the components using a table form element. The values that I get back (empty or "0") do not match the actual user-checked box states by the time they post in `submitForm`. I've also tried a zillion variants of reversed `#parent` array hints, `#array_parent` hints, `#return_value`, etc. It *feels* like there may be a bug in the `getValues` method in how it handles array-style keys? Or, am I doing something dumb?

```
class DataFsFolderSharingForm extends ContentEntityForm {

  // … stripped down to the bare essentials...

  public function buildForm(array $form, FormStateInterface $form_state, DataFsFolderInterface $folder = NULL) {
    // Documentation for for element attributes (eg: '#parents’, '#array_parents’, '#return_value’, etc):
    //   @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21FormElement.php/class/FormElement/8.2.x

    $form = [];
    $form['#tree'] = TRUE;

    // Show the current access settings as a table.
    //   @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Table.php/class/Table/8.2.x
    $form['access'] = [
      '#type'    => 'table',
      '#caption' => $this->t('Sharing Access'),
      '#header'  => [
        $this->t('User Email'),
        $this->t('View'),
        $this->t('Edit'),
        $this->t('Operation'),
      ],
      // '#array_parents' => array( 'access' ),
      // '#name' => 'access',
    ];

    // Non-nested element structure doesn’t break getValue method.
    $form['flat'] = [
      '#type' => 'checkbox',
      // '#name' => 'check-2',
      // '#return_value' => 1,
      // '#default_value' => 1,
      // '#array_parents' => array( 'flat' ),
    ];

    // Nested element structure breaks getValue method.
    //   @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Table.php/class/Table/8.2.x
    $form['access'][0]['view'] = [
      '#type'          => 'checkbox',
      // '#name' => 'check-1',
      // '#return_value' => 1,
      '#default_value' => 1,
      // '#array_parents' => array( 'access', 0, 'view' ),
    ];

    // ...more table elements added, who's rows are indexed by the middle integer array value...

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    // The non-nested getValue returns the correct checkbox state (checked or unchecked).
    $checked = $form_state->getValue('flat');

    // The nested getValue returns the incorrect checkbox state (checked or unchecked).
    //  @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormState.php/function/FormState%3A%3AgetValue/8.2.x
    $checked = $form_state->getValue(['access', 0, 'view']);

    // Also tried ['access', '0', 'view’ ]
    // Also tried ['view’, 0, 'access’ ]
    // Also tried ['view’, '0', 'access’ ]
    // Also tried setting '#parents’ form element attribute.
    // Also tried not setting '#array_parents’ form element attribute.
    // Also tried reversed version of '#parents’ form element attribute.
    // Also tried reversed version of '#array_parents’ form element attribute.
    // Also tried setting '#return_value’ form element attribute (using 1, 0, TRUE, FALSE, '0’, '1’, etc).
    // Also tried setting '#default_value’ form element attribute (using 1, 0, TRUE, FALSE, '0’, '1’, etc).
  }
}

```

# Answer
> 0 votes
It appears that ContentEntityForm ignores all posted form element values for anything but the intrinsic fields of the entity. I switched to sub-classing the FormBase class and the getValue calls started returning values reflected by user-entered form values as expected.

# Answer
> 2 votes
Anyone still having this problem please allow collections of form elements using `#tree` set to `TRUE`. Its applied to the "parent" element, as the `#tree` property cascades to sub-elements. Use where you previously used in form calls. See D7 #tree and #parents on drupal.org.

# Solution

Example for above case, change `$form['#tree'] = TRUE;` to `$form['access']['#tree'] = TRUE;` then the value will be obtained using `$checked = $form_state->getValue(['access', 0, 'view']);`.

---
Tags: forms, 8
---


# Question
Title: 8 - How can I detect when an entity is being autocreated?
I have an `entity_reference` field that autocreates entities (i.e., the 'Create referenced entities if they don't already exist' option is enabled in the field's configuration). I'm looking for a way to set some values on those autocreated entities before they are saved (e.g., author, revision message, ...).

What I've tried so far:

* `hook_node_presave()`, but there is no indication on the `$entity` object that it's being 'autocreated' through an entity reference field.
* I can see that the new entities are being autocreated in `\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::preSave`, but it's not clear to me if/how I can override that method without implementing my own entity\_reference field type.

Any suggestion for how to set values on an entity when it is being autocreated?

# Answer
You need a custom EntityReferenceSelection handler plugin. An example would be how the node module sets the autocreated entity to published:

*Drupal\node\Plugin\EntityReferenceSelection\NodeSelection:*

```
  public function createNewEntity($entity_type_id, $bundle, $label, $uid) {
    $node = parent::createNewEntity($entity_type_id, $bundle, $label, $uid);

    // In order to create a referenceable node, it needs to published.
    /** @var \Drupal\node\NodeInterface $node */
    $node->setPublished(TRUE);

    return $node;

```

You find more information in the plugin annotation class https://cgit.drupalcode.org/drupal/tree/core/lib/Drupal/Core/Entity/Annotation/EntityReferenceSelection.php
> 3 votes

---
Tags: 8, entities
---


title: Automate installation with Composer

text:
# Question
Title: Automate installation with Composer
It was easy to get Drupal installed with a single drush command before:

```
            drush si $profile -y \
            --db-url=mysql://$MYSQL_USER:$PASS@localhost/$DB \
            --site-name=$DOM \
            --site-mail=$EMAIL \
            --account-mail=$EMAIL \
            --account-name=$USER \
            --account-pass=$PASS >> /dev/null 2>&1

```

and it would completely finish Drupal installation without expecting user to do anything on UI.

Now with Drupal switching to Composer package manager, I am using the following command

```
composer --quiet create-project drupal-composer/drupal-project:8.x-dev $HOME --stability dev --no-interaction

```

however, unfortunately this method expects user to finish Drupal 8 installation on UI entering database, username and password manually. I wonder is there any way to make Composer do installation till the very end without any human interaction?

# Answer
> 2 votes
So since nobody provided acceptable answer, based on the above comments I tried the following bash-script and it worked flawlessly:

```
sudo -u $USER /usr/local/bin/composer --quiet create-project drupal-composer/drupal-project:8.x-dev $HOME/public_html --stability dev --no-interaction
cd $HOME/public_html/web
drush si -y \
  --db-url=mysql://$MYSQL_USER:$PASS@localhost/$DB \
  --site-name=$DOM \
  --site-mail=$EMAIL \
  --account-mail=$EMAIL \
  --account-name=$USER \
  --account-pass=$PASS >> /dev/null 2>&1

```

---
Tags: 8, composer
---


# Question
Title: 8 - Is It Possible To Create Routes Through The Admin
**Question:** Is there a way for users to create routes in the admin?

**Issue:** I have a bunch of nodes and tax terms that are being used in Views but no where else. They shouldn't be accessible to the public either. Changing their path to /admin didn't give me the result I wanted, where in D7, that would automatically set them to the admin theme and I could set the permissions that way. I haven't found a decent entity module to create them like I want either.

**Solution:** Created a module that used a wildcard route. Then create a service that uses RouteSubscriberBase and alterRoutes to block any access to it without X permission.

I think there is some potential for others to use this but cannot find a way to set the routes to be blocked through the admin. x

# Answer
> 2 votes
You may want to check out the Rabbit Hole module.

> Rabbit Hole is a module that adds the ability to control what should happen when an entity is being viewed at its own page.
>
> Perhaps you have a content type that never should be displayed on its own page, like an image content type that's displayed in a carousel. Rabbit Hole can prevent this node from being accessible on its own page, through node/xxx.

---
Tags: routes
---


title: Enable filter format per field?

text:
# Question
Title: Enable filter format per field?
Is there a simple way in Drupal 8 to set a filter format on a field and **not** show other format options that are accessible by the role of the current user?

I want to have a field with a very stripped down editor and default to that format, but I also do not want to show the formatting options on this field. I already tried the Simplify module, not quite what I am looking for.

EDIT: Sure, you can form alter... just wondering if someone solved it in a more modular way for 8.2.x.

# Answer
> 5 votes
The Better Formats module provides this type of functionality.

See Better Formats Module.

> Better formats is a module to add more flexibility to Drupal's core input format system.
> **Features**
> Set allowed text formats per field.
> Set default order of text formats per field.
> Hide format tips per role.
> Hide more format tips link per role.
> Hide format selection per role per entity.

# Answer
> 3 votes
The D8 port of Better Formats seems to have stalled. A better (sorry, no pun intended) option would probably be Allowed Formats. That seems to be more actively maintained, and has a stable 8.x-1.1 release.

Enjoy, -Derek (dww)

---
Tags: 8, entities, input-formats
---


title: How to display image inside a form

text:
# Question
Title: How to display image inside a form
I want to show image insida a form I've try it with tag inside form but it's doesnt render anything heres my code

```
$form['y']['image_div'] = array(
            '#prefix' => '<div class="image"><img src="https://4.bp.blogspot.com/-tGbw82Gz8hA/WPR6WiOGPaI/AAAAAAAAEjk/JDPdpK3p-8wAUe2QTQbtWSdTZR_DBc-QACLcB/s640/Checkout.png" />',
            '#suffix' => '</div>',
        );

```

How do I render an image inside form.inc in drupal ?

# Answer
> 2 votes
```
$form['y']['image_div'] = array(
  '#prefix' => '<div class="image">',
  '#suffix' => '</div>',
  '#markup' => theme('image', array(
    'path' => 'https://4.bp.blogspot.com/-tGbw82Gz8hA/WPR6WiOGPaI/AAAAAAAAEjk/JDPdpK3p-8wAUe2QTQbtWSdTZR_DBc-QACLcB/s640/Checkout.png',
  )),
);

```

And in your template file:

```
print drupal_render($form['y']['image_div']);

```

Result:

# Answer
> 0 votes
In your function that creates the form, add a $form element for your image that uses theme\_image() to create the '#markup':

`$form['element_id'] = array(
 '#prefix' => '',
 '#suffix' => '',
 '#markup' => theme_image(array(
 'path' => file_create_url('uri_goes_here'),
 'width' => [your_image_width],
 'height' =>[your_image_height],
 'title' => t('Image title for when the pointer hovers over the image'),
 'attributes' => array(
 'class' => 'some-image-class',
 'id' => 'some_image_id',
 ),
 )
 ),
);`

Your 'path' element can be created using file\_create\_url().

If you would like to render your image using an image style that is defined in your site, use theme\_image\_style() to create your form element's #markup:

`$form['element_id'] = array(
 '#prefix' => '',
 '#suffix' => '',
 '#markup' => theme_image_style(array(
 'style_name' => 'some_style_name',
 'path' => file_create_url('uri_goes_here'),
 'width' => [your_image_width],
 'height' =>[your_image_height],
 'title' => t('Image title for when the pointer hovers over the image'),
 'attributes' => array(
 'class' => 'some-image-class',
 'id' => 'some_image_id',
 ),
 )
 ),
);`

---
Tags: 7
---


# Question
Title: ABT term reference field hidden in Node View
I am using "Access by Term" configuration to control VIEW and UPDATE access for a content type with a Term Reference field in the content type. See screenshot.

But setting this configuration hides the term ref field in Node View.

How do I fix this?

screenshot of the term ref ABT config fieldset:

# Answer
> 1 votes
Make sure to assign "Allow users to view ABT terms on node page." permission to desired roles.

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


# Question
Title: Add stock field to product display containing multiple SKUs
I've been trying forever to create a stock field for a product display that contains multiple product skus. I want to do this so that when each variation is purchased, it is subtracted from the total number of items in stock. Commerce Stock seems to let you track stock for individual skus, but not for one product with multiple skus. For example, I have a total of 100 shirts, but 10 shirts are pink, 10 are red, 10 are blue (hence, the different SKUs). That said, when 2 blue shirts have been purchased, I want the stock to drop from 100 to 98 on the product display. Out of the box, this isn't possible.

I tried using the answer in Synchronize commerce stock for product variations, but I'm unable to achieve the same result. I created a master stock text field on the product display, but I can't seem to set rules to subtract from the new field. Does anyone have clear instructions for doing this via rules?

In short: I am looking for a simple way to synchronize all product variant's stock in a single product display.

\** **UPDATE**

I have SUCCESSFULLY obtained the nid of a product display, and then, fetched Product Display by that nid with the below rule settings. That said, when I try and add an action to set data for my custom stock field (product\_stock) located on my content type Product Display, rules can't seem to find it? How is this happening?

**FETCH ENTITY BY ID SCREEN**

**THE SELECTORS I DO GET WHEN I DO FETCH ENTITY BY PROPERTY:**

# Answer
First, you will need to add an entity reference field to your line items. This will reference the product display node.

Then using Views Rules create a line item view with a "Rules Display"

* For "contextual filter" add Order ID.
* For "fields"
    + Add the quantity
    + Add Node ID (nid) of the referenced Product Display Page.

Now in your rule simply add a view loop and pass the Order ID as a parameter.

Inside the View loop:

* Fetch entity from ID, pass the NID from the view result.
* Do Calculate a value. Get the fetched entity quantity - view result quantity
* Set a data Value for fetched quantity field, calculated value.
> 1 votes

---
Tags: 7, commerce
---


# Question
Title: Can't pass variable to views style plugin template
How do I pass a variable to a twig template from a preprocess function of a views style plugin in a custom module?

In `alpha.module`, I have tried:

```
function alpha_preprocess_views_view(&$variables) {
  $variables["beta"] = "1";
}

```

and

```
function alpha_preprocess_page(&$variables) {
  $variables["beta"] = "1";
}

```

The template file is `alpha-gamma.html.twig` and the plugin is `Gamma.php`:

```
/**
* Style plugin.
*
* @ViewsStyle(
*   id = "gamma",
*   title = @Translation("Gamma"),
*   help = @Translation("Displays gamma."),
*   theme = "alpha_gamma",
*   display_types = {"normal"}
* )
*/
class Gamma extends StylePluginBase {
...
}

```

The template file is invoked and renders its output on the view's row results. However, `{{ beta }}` yields no result in the same file. I know I'm missing something important, but none of the examples I've found are specific to this type of row style template.

Guidance would be appreciated!

# Answer
In below code you preprocess the variables for `views-view.html.twig` file

```
function alpha_preprocess_views_view(&$variables) {
  $variables["beta"] = "1";
}

```

and, `function alpha_preprocess_page(&$variables)` will preprocess the variables for `page.html.twig`

So, if you create a file views-view.html.twig then you will get your variable `{{ beta }}`
> 1 votes

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


# Question
Title: How do I disable a single option from select
I have used a taxonomy entity reference to fill the values of a select form field. Based on the user roles, I want to limit the options between *Submitted*, *Reviewed*, *Accepted*, and *Rejected*.

I have used a content type to submit ideas. The field *idea status* is disabled for a *subscriber* role and available for *moderator* role and *approver* role. I want the *Moderator* to get the status Reviewed and Rejected. *Approver* should see Accepted and Rejected status.

How can I achieve this?

# Answer
The options can be hidden by a one liner code,

```
unset($form['field_name']['und']['#options'][1]);

```

where

*\['field\_name'\]* is the name of the your field

*\[1\]* is the index of the option in the list

In my case \[1\] is Submitted, \[2\] is Reviewed, \[3\] is Accepted and \[4\] is Rejected
> 0 votes

---
Tags: 7, forms
---


# Question
Title: How to get project's data from packages.drupal.org
Drupal projects can be searched similarly as Packagist:

From Packagist can be also extrated the project's data (e.g. versions):

Is it possible to get project's data also from the Drupal repository?

---

More info:

# Answer
> 3 votes
Yes, the Composer documentation on repositories describes this mechanism, specifically, the `provider-includes` and `providers-url` properties.

These properties describe the package indexes & the URL pattern used for look up, for example:

---
Tags: composer, community-official-site
---


title: Vocabularies with terms on a view

text:
# Question
Title: Vocabularies with terms on a view
I need to create a page with listed vocabularies and terms related to it in 3 columns.

```
Vocabulary 1       Vocabulary 2     Vocabulary 3
Term 1             Term 4            Term 7
Term 2             Term 5            Term 8
Term 3             Term 6            Term 9

```

If it's possible, I'd like to accomplish that by configuring a view. I'm not very good with custom code.

Do you have any idea?

# Answer
> 2 votes
Unfortunatelly for Drupal 8 @No Sssweat's solution of creating 3 seperate views (blocks) is the ONLY possible solution using views at the moment. Then you can put them in region of your liking and with css can display them one next to the other (inline).

When Taxonomy vocabulary data not available as views fields is not an issue anymore you will be able to do it with just 1 view and grouping terms by vocabulary name.

Otherwise another solution would be to make your own custom module that gathers and displays the vocabulary terms.

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


# Question
Title: webform telephone field validation fails
I am using webform-8.x-5.0 and created a telephone field with international phone numbers support. Before submitting the form if i enter some number like "+91fdfgdfg45646" it shows "Invalid phone number" (which i am not sure if it is a valid number or not). But when I submit the form it gets submitted. The issue is if it is invalid, the form should not have been submitted. Please suggest a solution. The form should not be submitted if it is invalid number.

Thanks in advance

Image for reference:

# Answer
> 1 votes
The international phone number element is only a client-side enhancement which is using the International Telephone Input library.

To validate the phone number via server-side validation you would need write custom code and to use a PHP library like https://github.com/giggsey/libphonenumber-for-php

---
Tags: 8, webforms
---


title: Why isn't Drush recognized as command?

text:
# Question
Title: Why isn't Drush recognized as command?
I ran `composer global require drush/drush:8.1.3` and added C:/Users/username/AppData/Roaming/Composer/vendor/drush/drush to the value of the PATH variable.

`drush status` returns the following output.

```
 PHP configuration      :  C:\xampp\php\php.ini
 PHP OS                 :  WINNT
 Drush script           :  C:\Users\username\AppData\Roaming\Composer\vendor\dr
                           ush\drush\drush
 Drush version          :  8.1.3
 Drush temp directory   :  C:\Users\username\AppData\Local\Temp
 Drush configuration    :
 Drush alias files      :

```

When I change directory to the one containing the Drupal files, and I run `drush status`, I get this error.

> 'C:\xampp\htdocs\drupal-project\drush' is not recognized as an internal or external command,operable program or batch file.

Why?

# Answer
There are many things to comment here: Why are you installing Drush 8 and why the specific (outdated) version 8.1.3?

What happens is that your global Drush looks for a site local Drush, finds something ("C:\xampp\htdocs\drupal-project\drush") and tries to execute it.

The recommended approach - at least if you have a site local Drush, which you have if you installed Drupal using Composer and "drupal-composer/drupal-project" - is to use Drush Launcher (instead of a global Drush). NB! Read this issue so it works smoothly on Windows.

After you have fixed the path so Drush Launcher is used instead of the global Drush, try `drush status` again. I expect it to find the correct site local Drush. You migh also want to try `drush --version`to verify which version of the launcher and Drush itself that is used.

You can test that the setup is correct by running Drush inside the directory containing Drupal:

1) If you have installed Drush Launcher correct, you should get the following output:

```
# drush --version
Drush Launcher Version: 0.6.0
Drush Commandline Tool 9.2.3

```

2) If you however have installed a global Drush 9 (using Compser) in stead of Drush Launcher, you get the following output:

```
# drush --version
'PATH_TO_DRUPAL_PROJECT/vendor/drush/drush/drush' is not recognized as an internal
or external command, operable program or batch file.

```
> 1 votes

---
Tags: drush
---


title: Link to download pdf from webform email

text:
# Question
Title: Link to download pdf from webform email
I have created a webform, after the submession the customer is sent the registration confirmation e-mail. How do I include in this email a link to download a pdf ?

# Answer
> 0 votes
Resolved !

All i want was how make the customer can download the mail as pdf by one click on link "Télécharger ici votre confirmation":

So i used the library jsPDF to generate mail as pdf

---
Tags: 7, webforms, files
---


# Question
Title: Unsupported operand types error when creating new Webform handler
Following the example here: https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-programmatically-add-a-handler-to-a-new-webform

I've created my handler manager sucessfully, however, when I go to create the handler, I get the error

> Error: Unsupported operand types in Drupal\webform\Plugin\WebformHandlerBase-\>setConfiguration() (line 363 of /var/www/sitename/web/modules/contrib/webform/src/Plugin/WebformHandlerBase.php

Here's a sample of the code I'm using to get this error

```
$webform_machine_name = 'form_id';
$webform = \Drupal\webform\Entity\Webform::load($webform_machine_name);

$handler_manager = \Drupal::service('plugin.manager.webform.handler');

// Create webform handler.
$handler_configuration = [
  'id' => 'my_form_handler',
  'label' => 'My form handler',
  'handler_id' => 'my_form_handler',
  'status' => 1,
  'weight' => 0,
  'settings' => [],
];

$handler = $handler_manager->createInstance('my_form_handler', $handler_configuration );

```

# Answer
> 2 votes
When I look at line 263 in \Drupal\webform\Plugin\WebformHandlerBase there is the below code...

```
$this->configuration = $configuration['settings'] + $this->defaultConfiguration();

```

Your `Unsupported operand types` error message indicates that one of those variables/properties is not an array.

My best guess is that `\Drupal\webform\Plugin\WebformHandlerBase::defaultConfiguration` is not returning an `array()` because your `$configuration['settings']` is set to an empty array.

---
Tags: 8, webforms
---


# Question
Title: How to add pagination (pager) to field collection module?
How to add pager to the content created by the Field collection module?

I tried to achieve it with the Views module but Views takes the whole field collection content as single item, so it is not feasible.

I tried the Smart Paging module, but smart pager is for breaking one single content in many, so it is also not applicable.

# Answer
> 1 votes
After trial and error, I found the perfect solution to provide **Paging** to the **content created by Field Collection module**. This can be done by Views module.

You need to create the View of the your content which you have created using the field collection.

*Important Part:* In the Views setting as described in the following snapshot in the section of **Multiple Field Setting**, you need to uncheck the **Display all the values in the same row**. Because by default it is checked so Views considers your entire content in single row, so pager of views considers it as only one item. But if you uncheck, your each field set considered as single row and so Pager of the Views module will calculate accordingly. Hence unchecking this setting in Views and providing pager in the Views module will solve the issue.

Hope this will help others.

# Answer
> 0 votes
Smart Paging

> Provides splitting up long Drupal content into sub pages by number of characters/words or by a placeholder HTML tag for node, user and taxonomy term entities.

OR

you can do it using view adding contextual filter after put view field in your field collection field using views field module

# Answer
> 0 votes
Pagination might be an alternative way to do this. It allows for paging based on

> Method 1: Content is paginated by a selectable "words per page" count.
>
> Method 2: Content is paginated by manual breaks, inserted by the content creator.
>
> Method 3: Content is paginated by manual breaks, based on tags.

---
Tags: 7, entities, paging
---


title: Alternative to RedirectResponse

text:
# Question
Title: Alternative to RedirectResponse
I have a module that returns a redirect response in `hook_node_insert()`.

```
$url = 'announcements';
$response = new Symfony\Component\HttpFoundation\RedirectResponse(\Drupal::url($url, [], ['absolute' => TRUE]));
$response->send();

```

I have another module that implements `hook_node_insert()` for the same content type. Since I have written redirectResponse in the first module, the `hook_node_insert()` implementation in the second module is not getting called.

Is there any other way to do it? Drupal 7 has `$_GET['destination']` and it works for Drupal 7.

# Answer
> 2 votes
Generally speaking, directly redirecting from a hook is something you should not do because it would not allow other hooks to be invoked, and it would stop what Drupal is doing.
In the specific, `hook_node_insert()` would also be invoked when a node is programmatically created from a module, for example in a `hook_install()` or `hook_cron()` implementation, or from a Drush plugin. In those cases, redirecting inside `hook_node_insert()` would just break Drupal core or third-party modules.

If you want to redirect users, the proper moment is after a form has been submitted. It is also preferable, because you can tell Drupal where you want to redirect users, and Drupal will do it after all the involved hooks are invoked.

You just need to add a form submission handler to the node edit form. Inside that, you redirect users with `$form_state->setRedirect($route_name)` or `$form_state->setRedirectUrl($url)` where `$route_name` is the name of the route (a string), and `$url` is a `\Drupal\Core\Url` object.

---
Tags: 8, redirection
---


title: Service provider not loaded

text:
# Question
Title: Service provider not loaded
I have:

```
services:
  entity.query.external:
    class: Drupal\m_entities\Entity\Query\External\QueryFactory
    arguments: ['@plugin.manager.my_entity_storage_client', '@my_entity.storage_client.response_decoder_factory', '@http_client', '@entity.manager']
    tags:
      - { name: backend_overridable }
  my_entity.storage_client.response_decoder_factory:
    class: Drupal\m_entities\ResponseDecoderFactory
    tags:
      - { name: service_collector, tag: my_entity_response_decoder, call: addDecoder }
  plugin.manager.my_entity_storage_client:
    class: Drupal\m_entities\MyEntityStorageClientManager
    parent: default_plugin_manager
  entity.my_entities.routes:
    class: Drupal\m_entities\Routing\MyEntityRoutes
    arguments: ['@entity.manager']
  access_check.my_entities.add:
    class: Drupal\m_entities\Access\MyEntityAddAccessCheck
    arguments: ['@entity.manager']
    tags:
      - { name: access_check, applies_to: _my_entity_add_access }

```

but my service provider is not loaded in below code:

ModifyServiceDefinitionsPass

```
$providers = $kernel->getServiceProviders('app'); // <-- not loaded in here
foreach ($providers as $provider) {
  if ($provider instanceof ServiceModifierInterface) {
    $provider->alter($container);
  }
}

```

how to make a service provider loaded?

# Answer
services.yml files are not service providers.

ServiceProviders are to dynamically add or modify service definitions, a yml file is just content that's parsed and merged together with everything else.

If that's not loaded then my guess is that you named it incorrectly, but you didn't include the filename, please add that including the other files you have, specifically the info.yml file.
> 2 votes

# Answer
To add a service provider, you have to create a class in your module respecting a defined naming convention :

```
Drupal\<module_name>\<Camelized module name>ServiceProvider

```

So for a module named `my_module`, the class you have to create would be

```
namespace Drupal\my_module;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;

class MyModuleServiceProvider implements ServiceModifierInterface {

  /**
   * Modifies existing service definitions.
   *
   * @param ContainerBuilder $container
   *   The ContainerBuilder whose service definitions can be altered.
   */
  public function alter(ContainerBuilder $container) {
    // TODO: Implement alter() method.
  }
}

```

You can find the documentation here : https://www.drupal.org/docs/8/api/services-and-dependency-injection/altering-existing-services-providing-dynamic-services

And the related logic here : https://github.com/drupal/drupal/blob/8.5.0/core/lib/Drupal/Core/DrupalKernel.php#L592-L599

```
<?
// Load each module's serviceProvider class.
foreach ($module_filenames as $module => $filename) {
  $camelized = ContainerBuilder::camelize($module);
  $name = "{$camelized}ServiceProvider";
  $class = "Drupal\\{$module}\\{$name}";
  if (class_exists($class)) {
    $this->serviceProviderClasses['app'][$module] = $class;
  }
  $filename = dirname($filename) . "/$module.services.yml";
  if (file_exists($filename)) {
    $this->serviceYamls['app'][$module] = $filename;
  }
}

```
> 2 votes

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


# Question
Title: Programmatically set updated time on node
I'm creating duplicates of nodes by doing

```
$node->createDuplicate();

```

It duplicates all the values of all the fields but but it duplicates the created and updated time as well. I want both of those set to now. I know how to set the created time.

```
$clone->setCreatedTime(time());

```

However there doesn't seem to be a function or a property for setting the updated time. I read up on the source code of the Node class but couldn't find any mention of it.

Is there any kind of method where you can set the updated time of a node?

# Answer
I think you can change the value by accessing the variable and saving it then

```
$clone->changed->value = time();
$clone->save();

```
> 4 votes

---
Tags: 8, nodes
---


# Question
Title: Hide page title if the image field has a value
I have a image field (field\_image) on my content type. I want to show the image below the header with the node title inside. I am successfully doing that in page.html.twig.

```
{% if node.field_image %}
  <div id="feature-image">
    <div class="container">
      <h1 class="feature-image">{{ node.label }}</h1>
    </div>
  </div>
{% endif %}

```

However, the page title is also showing up in the page title block inside of the Header region. I'm trying to find a way to hide the second page title, on the full node view, if the field\_image field has a value.

How can I achieve this?

# Answer
> 3 votes
This method works for me. (Thanks to kim.kennof on Slack for the assistance.)

In my **THEME.theme** file:

```
function THEME_preprocess_page_title(&$variables) {
  if ($node = \Drupal::routeMatch()->getParameter('node')) {
    if ($node instanceof \Drupal\node\Entity\Node) {
      $variables['node'] = $node;
    }
  }
}

```

Then in **page-title.html.twig**:

```
{% if node.field_image is empty %}
  {% if title %}
    <h1{{ title_attributes.addClass('page-header') }}>{{ title }}</h1>
  {% endif %}
{% endif %}

```

# Answer
> 1 votes
You an add a hook\_block\_access to a .module file in a custom module.

Include these use statements at the top of the file

```
use Drupal\node\NodeInterface;
use Drupal\Core\Access\AccessResult;

```

Then implement your hook like so.

```
/**
 * Hide page title block when the node being viewed has a hero image.
 *
 * Implements hook_block_access()
 */
function ifde_blog_block_access($block, $op, $account) {
  if ($block->id() == 'REPLACE_WITH_PAGE_TITLE_BLOCK_ID' && $op == 'view') {
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node instanceof NodeInterface && $node->hasField('field_image') && !empty($node->field_image->getValue())) {
      return AccessResult::isForbidden();
    }
  }
  return AccessResult::neutral();
}

```

---
Tags: 8, theming
---


# Question
Title: I cannot get fields to render in a view fields template
I created a view "Blog Listing Cards" \[machine name: blog-listing-cards\] I created a views view fields template \[views-view-fields--blog-listing-cards.html.twig\] The template is properly 'picked up' and the static content displayed.

However, any time I try to print a field in the template, whether a Drupal default or custom field, it doesn't render in the browser.

The syntax seems correct when compared to documentation, other templates, and others with the same issue.

Examples of code not rendering

```
<div class="entry-meta">{{ fields.created.content }}</div>

<h2 class="display-4 mb-4 text-light">{{ fields.title.content }}</a></h2>

```

What am I missing?! Sorry, I'm a Drupal 7 guy re-learning in Drupal 8. Thanks in advance :-)

# Answer
> 3 votes
The problem is because those fields are hidden in the view and `{{field.<field-name>.content}}` will be empty.

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


# Question
Title: Configuring Blocks and the use of wild cards
Quite inexperienced in Drupal. I want to place a Block in my site, but I want it hidden on Front Page, on any node and on any user page (except */user/login* and */user/register* and */user/password*). If I chose to “Hide for the listed pages”: */node/* /user/\* * The pages: */user/login* and */user/register* and */user/password* will also be excluded

Is there a will card just for numbers? That would allow me to exclude the user profiles but not those 3 pages?

# Answer
> 1 votes
Regular expressions based matching is not yet supported on D8 block visibility patterns and wildcards. The best bet at this point is the following module: https://www.drupal.org/project/block\_visibility\_groups

You can add multiple rules to show or hide blocks.

---
Tags: blocks
---


title: Views_infinite_scroll not working

text:
# Question
Title: Views_infinite_scroll not working
I'm using Drupal 8 latest stable version: 8.5.x

I have 2 blocks (Upcoming events and Past events).

On Past events views infinite scroll is working with a button enabled providing the user ability to view more. It has many items and the module works as designed.

Same structure Upcoming events block returning only one upcoming event. When user clicks view more button the page is returning nothing and even the one item listed get disappeared.

Ajax is enabled on both views, the only difference is that upcoming events is returning only one result.

How can i solve this?

# Answer
Why don't you duplicate the view that works and just reconfigure the filter criteria to met your requirements?
> 1 votes

---
Tags: views, 8
---


title: Anonymous user cache control

text:
# Question
Title: Anonymous user cache control
We have written some custom blocks that render dynamic content; unfortunately, the caching defaults cache the first render of this block (and don't refresh for anonymous users). Cache control seems to only work for authenticated users. Are we missing something obvious? Is it possible to control anonymous caching on a block (or page) basis?

# Answer
There are two different page caches.

The *Internal Dynamic Page Cache* works with all kind of elements like blocks and nodes and is uses the cache tags, cache contexts and cache max-age provided by these elements.

The *Internal Page Cache* is for complete pages for anonymous users and only uses cache tags.

You can control the page cache for anonymous users with one parameter.

Go to the perfomance configuration:

```
admin/config/development/performance

```

And configure the page cache maximum age with the time how long your information is valid. This is also important for proxies and the browser cache, because it would not help to invalidate the drupal cache, if the page is cached in other places. After that time the page expires and should be built again. According to the documentation:

> Configuring the internal page cache On the Performance page, you can configure how long browsers and proxies may cache pages; that setting is also respected by the Internal Page Cache module. There is no other configuration.

But this is not true. You should configure this time for proxies and browser cache, but the internal page cache does not respect the time you set there. The only reliable solution I found is to uninstall the module *Internal Page Cache* or set an expire time in an EventSubscriber (for example 3600 sec in the future):

**/src/EventSubscriber/SetExpiresSubscriber.php**

```
<?php

namespace Drupal\mymodule\EventSubscriber;

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

class SetExpiresSubscriber implements EventSubscriberInterface {

  public function onResponse(FilterResponseEvent $event) {
    $request = $event->getRequest();
    $response = $event->getResponse();
    if ($event->isMasterRequest()) {
      $request_time = $request->server->get('REQUEST_TIME');
      $expires_time = (new \Datetime)->setTimestamp($request_time + 3600);
      $response->setExpires($expires_time);
    }
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['onResponse'];
    return $events;
  }

}

```

**mymodule.services.yml**

```
services:
  mymodule.setexpires:
    class: Drupal\mymodule\EventSubscriber\SetExpiresSubscriber
    tags:
      - { name: event_subscriber }

```
> 14 votes

# Answer
Check out Added 'no\_cache' route option to mark a route's responses as uncacheable

In your routing.yml file:

```
some.route:
   path: '/some/path'
   defaults:
     _controller: '\Drupal\Some\Controller::response()'
   options:
     no_cache: TRUE

```
> 4 votes

# Answer
If you need the Internal Page Cache enabled (i.e., you can't use Varnish or another memory-based solution), and you simply want Internal Page Cache to respect the time set on at `admin/config/development/performance`, you could add your own Event Subscriber that modifies the FinishResponseSubscriber that Drupal provides. You can even use Drupal Console to generate most of the Event Subscriber for you, and then take the other bits from FinishResponseSubscriber. Your result would look something like this:

```
/**
 * Class MyModuleSubscriber.
 *
 * @package Drupal\my_module
 */
class MyModuleSubscriber implements EventSubscriberInterface {

  /**
   * Sets extra headers on successful responses.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The event to process.
   */
  public function onRespond(FilterResponseEvent $event) {
    if (!$event->isMasterRequest()) {
      return;
    }

    $request = $event->getRequest();
    $response = $event->getResponse();

    $this->setExpiresNoCache($response);

    return;

  }

  /**
   * Disable caching in ancient browsers and for HTTP/1.0 proxies and clients.
   *
   * HTTP/1.0 proxies do not support the Vary header, so prevent any caching by
   * sending an Expires date in the past. HTTP/1.1 clients ignore the Expires
   * header if a Cache-Control: max-age= directive is specified (see RFC 2616,
   * section 14.9.3).
   *
   * @param \Symfony\Component\HttpFoundation\Response $response
   *   A response object.
   */
  protected function setExpiresNoCache(Response $response) {
    $response->setExpires(REQUEST_TIME + 300);
  }

  /**
   * Registers the methods in this class that should be listeners.
   *
   * @return array
   *   An array of event listener definitions.
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = array('onRespond');
    return $events;

  }
}

```

The above hardcodes the cache lifetime at 300 seconds, but you could easily retrieve the user setting instead.
> 1 votes

# Answer
I think you need to disable the 'Internal Page Cache' module to get cache contexts working.

With 'Internal Page Cache' enabled content for anonymous users is cached by default.

If you turn off 'Internal Page Cache' you still need to tell Drupal to not cache for anonymous users

```
$variables['#cache'] = [
  'contexts' => [
    // The "current user" is used above, which depends on the request,
    // so we tell Drupal to vary by the 'user' cache context.
    'user',
  ],
];

```

does it for me - but is probably not sompletely correct.
> 0 votes

---
Tags: 8, caching
---


title: Programmatically Duplicate EntityQueues

text:
# Question
Title: Programmatically Duplicate EntityQueues
I'm attempting to create a duplicate of an entity queue that includes all the nodes inside it.

Here is my current code

```
$entityQueueId = 'hero_images';
$langcode = 'test'
$clones = [];
$subqueue = \Drupal::entityTypeManager()->getStorage('entity_subqueue')->load($entityQueueId);
$nodes = $subqueue->get('items')->referencedEntities();
    foreach ($nodes as $node) {
         $clone = $node->createDuplicate();
         $clone->title->value = $clone->title->value . ' - ' . $langcode;
         $clone->set('langcode', $langcode);
         $clone->setCreatedTime(time());
         $clone->setChangedTime(time());
         $clone->save();
         $clones[] = [
             'target_id' => $clone->id(),
         ];
    }

    $subqueue_clone = $subqueue->createDuplicate();
    $subqueue_clone->set('name', $langcode . '-' . $subqueue->id() . '-' . uniqid());
    $subqueue_clone->set('title', $langcode . '-' . $subqueue->id() . '-' . uniqid());
    $queue = $subqueue->getQueue();
    $queue_clone = $queue->createDuplicate();
    $queue_clone->set('id', $langcode . '-' . $queue->id() . '-' . uniqid());
    $queue_clone->set('title', $langcode . '-' . $queue->id() . '-' . uniqid());
    $queue_clone->save();
    $subqueue_clone->setQueue($queue_clone);
    $subqueue_clone->set('items', $clones);
    $subqueue_clone->save();

```

The queue does get created, but there are no items within it. In case there was an issue with my node duplication code as a test I just set

$subqueue\_clone-\>set('items', $subqueue-\>get('items')-\>getValue());

but that didn't work either. Is there an issue with my code? Or should I go about this in a completely different manner? What's the best way to duplicate an entityqueue while preserving or duplicating the list of the nodes inside it?

# Answer
I was able to get it to work, but I'm not entirely sure why it works. What I did was after saving the duplicated subqueue I loaded it once again then applied the items before saving for a second time.

```
    $subqueue_clone->save();
    $newsubqueue_clone = \Drupal::entityTypeManager()->getStorage('entity_subqueue')->load($clone_id);
    $newsubqueue_clone->set('items', $clones);
    $newsubqueue_clone->save();

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: How to add Vue.js validation attributes to input elements?
I've seen a tutorial about enhancing Drupal's elements using Vue.js validation component. The input markup is like this:

```
<input class="username form-text required" autocapitalize="none" type="text" id="edit-name" name="name" value="" size="60" maxlength="60" v-model="name" v-validate.initial="name" data-rules="required|alpha|min:3">
<input type="text" id="edit-mail" name="mail" value="" size="60" maxlength="254" class="form-text required" v-model="mail" v-validate.initial="email" data-rules="required|email">

```

But how do I add the Vue.js custom attributes to these input field?

# Answer
> 2 votes
I suppose you only want to add Vue specific attributes to certain form elements, not every single one of them (including admin/backend forms).

Presuming you are using Drupal 8, I'd recommend enabling Twig debugging. That will help you to identify which fields you want to alter.

Once twig debugging is enabled Drupal should expose theming details for each element. In your case you need to know about template and hook names.

The input field shown in the screenshot is using input.html.twig template file from `core/themes/classy/templates/form/input.html.twig`, and theme hook is `input__textfield`

For your specific question, I recommend adding those attributes via preprocess hooks in your theme. For example;

```
<?php
function YOURTHEME_preprocess_input__textfield(&$variables) {
  $element = $variables['element'];

  if ($element['#name'] === 'title') {
    $variables['attributes']['autocapitalize'] = 'none';
    $variables['attributes']['v-model'] = 'name';
    $variables['attributes']['v-validate.initial'] = 'name';
    $variables['attributes']['data-rules'] = 'required|alpha|min:3';
  }
}

```

My example above is NOT very specific, it only alters "textfields" with the name "title". I recommend targeting more specific form elements.

---
Tags: theming, forms
---


# Question
Title: Why doesn't skip_on_empty work when migrating from a text field?
I'm trying to migrate Drupal 7 users to Drupal 8. In Drupal 7, there's an additional text field representing the user's group. In Drupal 8, it's a taxonomy vocabulary. So I'm using the following pipeline:

```
  field_user_group:
    -
      plugin: skip_on_empty
      method: process
      source: field_directorate
    -
      plugin: extract
      index:
        - 0
        - value
    -
      plugin: entity_generate
      value_key: name
      bundle_key: vid
      bundle: groups
      entity_type: taxonomy_term
      ignore_case: true

```

`field_directorate` is the source field in D7, and `field_user_group` is the target in D8.

Records without that value set should be caught by the `skip_on_empty` plugin, and left blank, but that plugin seems to be failing (letting the process continue to the next plugin in the pipeline) as I'm getting errors from the `extract` plugin saying:

> Array index missing, extraction failed.

According to the documentation,

> The skip\_on\_empty process plugin checks to see if the current input value is empty (empty string, NULL, FALSE, 0, '0', or **an empty array**). If so, the further processing of the property or the entire row (depending on the chosen method) is skipped and will not be migrated.

How is the processing even getting to `extract` if `skip_on_empty` is supposed to skip values with an empty array?

It works fine for records with the value set.

# Answer
> 1 votes
I now believe this to be caused by Get process plugin sets multiple for empty array.

---
Tags: 8, users, migrations, plugins
---


title: Webform email twig template questions

text:
# Question
Title: Webform email twig template questions
What is the correct syntax to test if a file has been uploaded in a webform in a twig email template?

For a text area, `{% if webform_token('[webform_submission:values:question_text_area:value]', webform_submission) %}` works fine but to test if a file has been uploaded, `{% if webform_token('[webform_submission:values:join_a_file:value]', webform_submission) %}` does not work.

Also, when there's a file uploaded, I want to display in the email only the title of the file ... `{{ webform_token('[webform_submission:values:join_a_file:delta:format:value]', webform_submission) }}` works but it outputs a link to that file. Is it possible to just have the text of the file name?

Thanks!

# Answer
That is a great question.

Getting just the filename is not currently supported but you can pull the file's URL using `[webform_submission:values:join_a_file:delta:format:url]`

The current list of supported formats for uploaded files is here. I created a ticket to add machine name to element submission display formats so that this information is exposed to site builder.

If you need just the file name, please create a new ticket in the Webform module's issue queue.
> 1 votes

---
Tags: 8, webforms
---


# Question
Title: Create any number of paragraph fields in a multiple value field on node create form
I have a paragraphs field that takes a term reference.

I need to count how many terms there are for a specific vocabulary and then create that many instance of the paragraphs multiple value field for when creating a node of a certain type. Can this be done with Hook\_form\_alter ?

It is important that these fields are loaded when the node creation form is loaded rather than the user having to click add more

Any help would be greatly appreciated

I have tried this but when saving the node it doesn't save the new fields

```
function hook_form_alter(&$form, $form_state, $form_id) {

  if ($form_id == 'my_form') {

  $item = $form['field_features']['widget']['0'];

  // get taxonomy terms
  $query = \Drupal::entityQuery('taxonomy_term');
  $query->condition('vid', "my_voc");
  $tids = $query->execute();
  $terms = \Drupal\taxonomy\Entity\Term::loadMultiple($tids);

  $count = count($terms);

  $i = '1';
  foreach($terms as $term){
    $form['field_features_para']['widget'][$i] = $item;
    $form['field_features_para']['widget'][$i]['#delta'] = $i;
    $form['field_features_para']['widget'][$i]['#weight'] = $i;
    $i ++;
  }
 }
}

```

# Answer
> 6 votes
Instead of adding the multi value field items after the form is built you can try to do this on the entity before the form is built:

```
/**
 * Implements hook_ENTITY_TYPE_create() for 'node'.
 */
function mymodule_node_create(\Drupal\node\NodeInterface $node) {

  if ($node->getType() == 'my_content_type') {
    // get taxonomy terms
    $query = \Drupal::entityQuery('taxonomy_term');
    $query->condition('vid', "my_voc");
    $tids = $query->execute();
    $terms = \Drupal\taxonomy\Entity\Term::loadMultiple($tids);

    $count = count($terms);

    $i = '1';
    foreach ($terms as $term) {
      $paragraph = \Drupal::entityTypeManager()->getStorage('paragraph')->create([
        'title' => 'Paragraph ' . $i,
        'type' => 'my_paragraph_type',
         // more field data
      ]);
      $node->field_features_para[] = $paragraph;
      $i++;
    }
  }

}

```

---
Tags: forms, paragraphs
---


# Question
Title: using $_POST values in form alter to add validation
it's not the first time that i get into trouble using $\_post in a node form alter, this time i'd like some assistance.

basically, i need to pass some parameters to a form (and i should not pass the appended to the url, as query parameters). but $\_POST values don't work as expected (they work until reaching validation phase).

So.. in a page i pass as hidden value

```
<form method="post" action="/node/add/">
    <input type="hidden" name="mydesideredParameter" value="itsValue">
</form>

```

In the form\_alter function of this form, at the very beginning, i try to assign this value to $form\_state (and it works, I watchdog it later and it's correct)

```
if (array_key_exists('mydesideredParameter', $_POST)) {
    $form_state['mydesiredConsequence'] = 'dance';
}

```

Later, inside form\_alter, at the very end, i state:

```
if ($form_state['mydesiredConsequence'] === 'dance'){
    $form['#validate'][] = 'myDancingFunction';
};

```

No complains happen on form building, but when trying to submit the form, the validation funcion doesn't get called and php complains about index that doesn't exist no more

```
Notice: Undefined index mydesiredConsequence

```

Nothing similar happens when i use this step and the values are in the url(via drupal\_query\_parameters) , but trying to make this work in $\_POST seems a bit awkward. (i obviusly can imagine that the second form-rebuilding ignores $\_POST, as it was a former request; but that should be the intended purpose of assigning the value to $form\_state).

# Answer
You should use `$form_state['storage']`. This will cache your data and make it available throughout the forms lifecycle.
> 0 votes

---
Tags: 7, forms
---


# Question
Title: How to create a rule to flag users when they're approved as a Trusted Contact?
I need some help with Drupal Commons (7.x-3.46), Trusted Contacts (one of its modules), and Rules. I need to create a rule so that whenever a user is approved as a trusted contact, the user is also flagged. It turns out this is not so simple.

In my attempts so far, however, the user ends up flagging him/herself.

Also, it should not depend on the user being logged in, as they might be approved while they're not logged-in. Or flagged twice if both users are logged in at the same time! In other words the approver should flag the approved, regardless of who is logged in at the time.

The rule thus far is

```
{ "og_og_member_subscribe2" : {
    "LABEL" : "OG member subscribe2",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "og" ],
    "ON" : { "og_user_approved" : [] },
    "IF" : [
      { "data_is" : { "data" : [ "og-membership:state" ], "value" : "1" } },
      { "entity_has_field" : {
          "entity" : [ "og-membership:entity" ],
          "field" : "user_trusted_contacts"
        }
      },
      { "entity_is_of_type" : { "entity" : [ "og-membership:entity" ],
"type" : "user" } }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "fired2" } },
      { "variable_add" : {
          "USING" : { "type" : "user", "value" : [ "og-membership:entity" ]
},
          "PROVIDE" : { "variable_added" : { "user_added" : "Added variable"
} }
        }
      },
      { "drupal_message" : { "message" : "uid [user-added:uid]  trusted
contacts are [account:user-trusted-contacts]\r\n\r\n" } }
    ]
  }
}

```

When the user (= `te st`) confirms `JeffNoyes` as a trusted contact, this is the message that returns:

```
fired2
uid 3 trusted contacts are Jeff Noyes, Drew Robertson, Lisa Rex, Katelyn
Fogarty, te st
fired2
uid 1 trusted contacts are te st, Jeff Noyes
fired2
uid 3 trusted contacts are Jeff Noyes, Drew Robertson, Lisa Rex, Katelyn
Fogarty, te st

```

It's not quite clear to me why it fires 3 times.. It fires first for the approved, uid3 Jeff Noyes. Then a 2nd time for the approver, uid1, te st. And then a 3rd time, once again for uid3.. And Every user is the first user in his/her trusted contacts list, and the last in the list is the one just approved. I can't seem to fetch and limit it to the user who did the approving, or to their list of trusted contacts.

this is the Rules debug information:

```
" Reacting on event User membership has been approved.
0 ms Reacting on event User membership has been approved.
    11.459 ms Evaluating conditions of rule OG member subscribe2. [edit]
    13.223 ms The condition data_is evaluated to TRUE [edit]
    14.958 ms The condition entity_has_field evaluated to TRUE [edit]
    15.209 ms The condition entity_is_of_type evaluated to TRUE [edit]
    15.23 ms AND evaluated to TRUE.
    " Rule OG member subscribe2 fires. [edit]
    0 ms Rule OG member subscribe2 fires.
    0.201 ms Evaluating the action drupal_message. [edit]
    1.275 ms Evaluating the action variable_add. [edit]
    1.488 ms Added the provided variable user_added of type user [edit]
    109.832 ms Evaluating the action drupal_message. [edit]
    110.099 ms Rule OG member subscribe2 has fired.
    125.403 ms Finished reacting on event User membership has been approved.
    " Reacting on event User membership has been approved.
    0 ms Reacting on event User membership has been approved.
    0.687 ms Evaluating conditions of rule OG member subscribe2. [edit]
    1.389 ms The condition data_is evaluated to TRUE [edit]
    2.329 ms The condition entity_has_field evaluated to TRUE [edit]
     2.716 ms The condition entity_is_of_type evaluated to TRUE [edit]
    2.767 ms AND evaluated to TRUE.
    " Rule OG member subscribe2 fires. [edit]
    0 ms Rule OG member subscribe2 fires.
    0.356 ms Evaluating the action drupal_message. [edit]
    1.104 ms Evaluating the action variable_add. [edit]
    1.551 ms Added the provided variable user_added of type user [edit]
    15.337 ms Evaluating the action drupal_message. [edit]
     15.866 ms Rule OG member subscribe2 has fired.
    18.793 ms Finished reacting on event User membership has been approved.
    " Reacting on event User membership has been approved.
    0 ms Reacting on event User membership has been approved.
    0.309 ms Evaluating conditions of rule OG member subscribe2. [edit]
    0.628 ms The condition data_is evaluated to TRUE [edit]
    1.056 ms The condition entity_has_field evaluated to TRUE [edit]
    1.22 ms The condition entity_is_of_type evaluated to TRUE [edit]
     1.241 ms AND evaluated to TRUE.
    " Rule OG member subscribe2 fires. [edit]
    0 ms Rule OG member subscribe2 fires.
    0.146 ms Evaluating the action drupal_message. [edit]
    0.501 ms Evaluating the action variable_add. [edit]
    0.693 ms Added the provided variable user_added of type user [edit]
    6.823 ms Evaluating the action drupal_message. [edit]
    7.075 ms Rule OG member subscribe2 has fired.
    8.385 ms Finished reacting on event User membership has been approved.

```

# Answer
> 1 votes
### Understanding what is happening

Since you're using Rules Event "User membership has been approved", it appears that the rule is triggered for each of the user's trusted contacts. That seems to explain why you get that `fired2`-message 3 times.

So unless you can find another Rules Event that only gets triggered once (for all trusted contacts together), you'll have to come up with a refinement of your Rules Conditions and/or Rules Actions, so that the relevant Rules Actions are only performed for the "trusted contact" that triggered the execution of the actual rule. Read on for an attempt to make that work also ...

### Attempt to make it work as you want

Your Rules Conditions seems OK, but at a minimum you're missing a crucial Rules Action: a Rules **Loop**. If you're not familiar with such loops, then I strongly recommend to have a look at the tutorial titled "Lists and loops".

In your case, you should add a Rules Loop related to that token `account:user-trusted-contacts` that is already shown in your last Rules Action. After you do, you should iterate over each item in that list (= each user that is a contact, let's assume you name it like `current_list_item`).

For each iteration of such Rules Loop, you should then "do something", to only "flag" that user (which is processed in that iteration step), provided (= on condition) that the user matches the user for which the Rules Event is triggered.

With that, you have 2 challenges left:

* do some extra research to see which token you have available in your rule, to know what the user is for which the Rules Event is triggered. My best guess would be that something related to that `og-membership` (such as a `uid`?), let's assume its name is `some_token`.
* implement such "condition" (as an extra Rules Action!), which you can do by using the Conditional Rules module, so that you can specify Rules Conditions within Rules Actions. The actual condition should then be to check that `current_list_item` equals `some_token`.

Instead of using the Conditional Rules module, you could also rework the Rules Action to performing Rules Components (in which you add the appropriate Rules Conditions), so that you don't need this extra module. For more details on that, refer to the answer to "What's the alternative to using the Conditional Rules module?".

### Advanced debugging

Something else that will help you find the answer to your question, is to have a look at Rules **debugging** ... Within the Rules **settings**, experiment a bit with the debugging facilities that come with the Rules module. At least have a look at the "***Rules Evaluation Log***" (to check that the Rules logic being executed, actually matches what you expect that logic to be).

Depending on what the result of that type of debugging is, you may also want to (temporary) enable the Devel module, so that you can (temporary) add a Rules Action like "Display a value".

For way more details about these 2 variations, refer to **Rules debugging**, as explained in the answer to "How can I display the value of a variable inside a condition?".

### Putting it all together

After your additional edits (partially based on what I wrote in this answer above), you might get it to work if you add this additional Rules Actions:

1. Use the Conditional Rules module to add, as your very first Rules Action, a condition to check that "current user" equals token `[user-added:uid]`. And move all your existing Rules Actions inside that Condition. Doing so will limit the execution of those Rules Actions to your 2nd iteration only for the testcase you're using. Do an extra test to ensure you get this intermediate result.
2. Add an extra Rules Action (also within the Condition added in step 1) which is actually a Rules loop to iterate over each of the items contained in `[account:user-trusted-contacts]`. Inside this loop, use Conditional Rules again to check that the list item being processed is different from the "current user". If that condition is satisfied, do whatever you want to process "yet another trusted contact" of the current user.

---
Tags: 7, users, rules, flags
---


# Question
Title: drush updb fails with "the 'media_delete_action' plugin does not exist" after 8.4.6 > 8.5.1 update
We have recently updated a Drupal `8.4.6` installation via composer to Drupal `8.5.1`. After the composer update I ran

```
drush updb

```

as usual. However, the command fails at one point with the following error message:

```
Failed: Drupal\Component\Plugin\Exception\PluginNotFoundException: The "media_delete_action" plugin does not     [error]
exist. in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 52 of
…\htdocs\casali\web\core\lib\Drupal\Component\Plugin\Discovery\DiscoveryTrait.php).

```

After that, every `drush updb` wants to do the following updates, since they are never completed:

```
system module :
  Change plugin IDs of actions.
  Clear caches due to schema changes in core.entity.schema.yml.

views module :
  Update dependencies for moved bulk field plugin.
  Add additional settings to the entity link field and convert node_path usage  to entity_link.
  Add placeholder settings to string or numeric filters.
  Fix cache max age for table displays.
  Include views data table provider in views dependencies.

```

I am not quite sure what to do here. As far as I have researched, `media_delete_action` is part of the `media_entity` module. However, that module is already part of the core in Drupal 8.4.x (https://www.drupal.org/project/media\_entity).

If I run

```
drush en media_entity

```

it tells me

```
media_entity was not found.                                                                                [warning]
The following projects provide some or all of the extensions not found:                                                    [ok]
media_entity
Would you like to download them? (y/n):

```

But I don't think I should have to do that, since it's already part of the core?

# Answer
This is how we were able to solve this problem:

Temporarily install `drupal/media_entity_actions`:

```
composer require drupal/media_entity_actions:^1.0
drush en media_entity_actions

```

Run the database update:

```
drush updb

```

This time it will work:

```
system module :
  Change plugin IDs of actions.
  Clear caches due to schema changes in core.entity.schema.yml.

views module :
  Update dependencies for moved bulk field plugin.
  Add additional settings to the entity link field and convert node_path usage  to entity_link.
  Add placeholder settings to string or numeric filters.
  Fix cache max age for table displays.
  Include views data table provider in views dependencies.

Do you wish to run all pending updates? (y/n): y
Post updating system                                                                                [ok]
Post updating system                                                                                [ok]
Post updating views                                                                                [ok]
Post updating views                                                                                [ok]
Post updating views                                                                                [ok]
Post updating views                                                                                [ok]
Post updating views                                                                                [ok]
Post updating views                                                                                [ok]
Post updating views                                                                                [ok]
Cache rebuild complete.                                                                                [ok]
Finished performing updates.                                                                                [ok]

```

Then the module can be uninstalled safely:

```
drush pm-uninstall media_entity_actions
composer remove drupal/media_entity_actions

```
> 3 votes

---
Tags: 8, updating, media
---


# Question
Title: geolocation_views: show combined data in tooltip
I have two content types that work together:

* "place": a place on a map (via a geolocation field)
* "object": an object that is in a specific "place" (referenced via an entityreference field)

Several "objects" can be stored in the same "place".

Now I want to display a map showing the location of each object (via geolocation\_views).

My problem:

* either the view shows OBJECTS, but then if there are several objects in the same place, several "pins" will appear on the exact same spot on the map, which doesn't work well (you can only click on the topmost pin)
* or the view shows PLACES, but then the information about what object is stored in that place is absent.

For now, I have the following:

1. the main view is the map and shows places
2. and then I added a second view, as an attachment next to the map; this view lists (textually) all objects, grouped by places.

This works, but it means that the map is pretty much useless: you can click on a place, see its name, but you have no information about the objects and so you have to search the name of this place in the second view and then you will see the objects. Since there are several dozen of places, it's really cumbersome.

Ideally, I'd like that when the user clicks on a "place" on the map, the tooltip shows not only the name and address of the place (it's already the case), but also the list of objects stored in that place.

How can I achieve that?

# Answer
> 0 votes
You're incredibly close. What you need to do is incorporate the objects related to the place into the place view itself.

You do this by means of a Relationship. You can find that, when you're editing the view, in the right-hand Advanced column. When you click Add, you'll see something like Entity Reference: Referenced Entity, A bridge to the Content entity that is referenced via *your relate field*.

This puts the JOIN in the FROM clause of the underlying SQL query.

---
Tags: 7, views, location
---


# Question
Title: Permissions for adding bundles to custom entities
I've made some custom entities using the Entity API and I would like to give some users the ability to add bundles to them.

However it seems that in order to add bundles they have to have the "Administer site configuration" permission. I am a bit concerned about giving users that, especially as we might be doing a multisite system where different organisations will own different sites. I'm worried that they might be able configure directories and file paths and end up getting access to things on the other sites.

There is a special permission for creating content types, so I wonder whether there could also be one for creating bundles of other kinds of entities. It seems an oversight that there is not.

# Answer
Writing in here, since its a faux paux to link to blog articles.

In your permissions.yml file of your module, you can define a permissions callback like so:

```
permission_callbacks:
  - Drupal\mymodule\MyModulePermissions::permissions

```

Then in your `MyModulePermissions` class:

```
namespace Drupal\mymodule;

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

class MyModulePermissions implements ContainerInjectionInterface {

  use StringTranslationTrait;

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

  /**
   * Constructor for MyModulePermissions.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
  }

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

  /**
   * Get permissions for MyModule.
   *
   * @return array
   *   Permissions array.
   */
  public function permissions() {
    $permissions = [];

    foreach ($this->entityTypeManager->getStorage('myentity')->loadMultiple() as $type) {
      $permissions += [
        'create ... ' . $type->bundle() => [
          'title' => $this->t('Allow creation of %type', array('%type' => $type->label())),
        ]
      ];

      $permissions += [
        'update ... ' . $type->bundle() => [
          'title' => $this->t('Allow update of %type', array('%type' => $type->label())),
        ]
      ];

      $permissions += [
        'delete ... ' . $type->bundle() => [
          'title' => $this->t('Allow deletion of %type', array('%type' => $type->label())),
        ]
      ];
    }

    return $permissions;
  }
}

```

Something like that. Code is untested. This will loop through and create CRUD permissions for each bundle.
> 3 votes

---
Tags: 8, entities
---


# Question
Title: Views not showing date field in proper time zone
I created a node type with a date field (from the date module). I list nodes of this type in a view. The problem I have is that the date values being shown by the view are in UTC (ie as they are stored in the db) not in the user's local timezone. I have tried the following to no avail:

1) Unchecked "Administration » Configuration » Regional and language » Users may set their own time zone". I then logged out and cleared the cache.

2) Verified that if I view the node outside of the view (ex: going to http://mysite.local/node/123), the time appears in the proper timezone. The proper dates are also shown when editing the node.

3) Tried to format the date using this code:

```
format_date($date, 'custom', 'D d/m/Y - g:ia', date_default_timezone_get())

```

`$date` is a timestamp and `date_default_timezone_get()` returns the proper timezone.

4) Tried this with the date\_views modules enabled and disabled.

For some reason the view pulls the date field value straight from the db without converting it to the proper timezone. Unfortunately, I don't know how to either 1) tell views how to convert it properly, or 2) convert it manually in a template.

Note: I refuse to hard-code my timezone into my template. This is a terrible option I've seen when searching for an answer to this.

# Answer
> 0 votes
You can use Global PHP filed to convert the date in user's proper timezone using code. Your date field value will be the input here. If it works then use this field instead and set the original date field to 'exclude from display' in your view.

# Answer
> 0 votes
I just ran into this problem recently and saw this post without a real solution. For me editing the Date field in the content type and setting the "Time zone handling" to "No time zone conversion" than re-saving the nodes solved the problem.

---
Tags: 7, views, datetime
---


# Question
Title: Entity form presents all taxonomy terms instead of vocabulary
I create entity form and add entity reference taxonomy field, set it as *select* and specify *options*, but i get **all** terms instead of **one** vocabulary terms.

Any idea how to make it works?

here some code.

```
$taxonomyStorage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
$voc             = $taxonomyStorage->loadTree("my_vocabulary");

$array = [];

foreach ($terms as $term) {
    $array[] = [
        'tid' => $term->tid,
        'name' => $term->name
    ];
}

$fields['voc_type'] = BaseFieldDefinition::create('entity_reference')
        ->setLabel(t('Voc Type'))
        ->setDescription(t('Voc tag'))
        ->setSetting('target_type', 'taxonomy_term')
        ->setDisplayOptions('form', [
            'type'    => 'select',
            'options' => $array,
            'weight'  => -6,
        ])
        ->setDisplayConfigurable('form', true);

```

# Answer
```
$fields['voc_type'] = BaseFieldDefinition::create('entity_reference')
    ->setLabel(t('Voc Type'))
    ->setDescription(t('Voc tag'))
    ->setSetting('target_type', 'taxonomy_term')
    ->setDisplayOptions('form', [
        'type'    => 'select',
        'options' => $array,
        'weight'  => -6,
    ])
    ->setDisplayConfigurable('form', true)

    // I think you're missing this:
    ->setSetting('handler', 'default:taxonomy_term')
    ->setSetting('handler_settings', [
      'target_bundles' => [
        'my_vocabulary' => 'my_vocabulary'
      ]
    ]);

```

I don't think you need to manually gather the `options` and set them like that. The target\_bundles setting should take care of that.
> 1 votes

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


# Question
Title: Change routing behaviour for non-existent entities
For my custom entity type called `item`, I would like to set up routes such that the path:

```
/item/{item}

```
1. views the entity as normal, if it exists
2. if it doesn't exists, redirects to the create form

The default Entity controllers create a 404 response. How can I change that behaviour?

Currently, the routes are generated through the entity's annotation (via DefaultHtmlRouteProvider):

```
* links = {
*   "canonical" = "/item/{item}"
*   ...
* }

```

# Answer
Yes, routing is one way to do this. Extend the entity view controller, where you call (1) the parent method to view the entity or (2) redirect to the create form. Change the route so that it points to the new controller and remove the options for type casting and converting the entity parameter. You have then to load the entity in the controller by hand, because the controller gets only the raw parameter (the entity id), but you need to check if the entity exists anyway to decide if you need to redirect. You can change the route by extending DefaultHtmlRouteProvider or in a RouteSubscriber. You might also need to move the access check from the route to the controller after the entity is loaded.

There are more ways to do this, you could redirect in a request subscriber where you check if the entity exists before routing or you could redirect in an exception subscriber after a 404 is raised.

The last option is possibly easier to implement, because then you don't need to think about routing and access checking and simply react on a 404 caused by your specific entity route.
> 3 votes

---
Tags: 8, entities, routes
---


# Question
Title: D8: Best way to implement terms of use acceptance requirement AFTER log in, and gate content if they don't accept?
Currently I have a Drupal 8 site utilizing saml authentication to create user accounts and log in. I've seen some modules that have required terms of use acceptance during registration, but that's a non-starter for my implementation.

I'm looking for recommendations on how to:

1. Present Terms of Use & Acceptance input to newly logged in users
2. Gate content behind this acceptance

Thank you for any recommendations.

# Answer
Specifically, the issue here is that the common Terms of Use modules out there happen during registration rather than after first log in. The problem scenario can arise if you are using a SSO implementation with your Drupal install.

My solution involved creating a module that, as a kernel event, redirected users that had not accepted the terms of use to the terms of use page until they had done so. Once they accepted the terms of use, I gave them a role - "Accepted Terms" - that let me know they were free to go.
> 0 votes

---
Tags: hooks
---


title: Language name of translated node

text:
# Question
Title: Language name of translated node
For a teaser view mode I want to display the language of the content. I can get the langcode in twig with: `{{ node.langcode.value }}` But how can I display the language name? In the field display I get only the string with "Language English", but I want only the name without any other thinks like "Language ...".

One way is to use preprocess node:

```
function mytheme_preprocess_node(&$variables) {
  $variables['lang_name'] = $variables['node']->language()->getName()
}

```

in the template file:

```
{{ lang_name }}

```

Is there a pure twig solution possible?

# Answer
If you want to use the method `language()` in Twig

```
{{ node.language.name }}

```

you have to add it to the whitelist of the Twig sandbox policy in settings.php:

```
$settings['twig_sandbox_whitelisted_methods'] = [
  'id',
  'label',
  'bundle',
  'get',
  '__toString',
  'toString',
  'language',
];

```
> 6 votes

# Answer
Use `{{ node.language().getName() }}` or `{{ node.language().name }}` (might not work).

With any object, like a node, you can call methods / get properties in twig by just using a '.' as the PhP -\>. Generally, getXXX() can be shortened to XXX. Occationally, you may need to add a .value or .toString() on the end to convert from the format returned to string.

Here's the formal twig reference for this. The implementation notes give some guidance on how short names work.
> 0 votes

---
Tags: 8, theming
---