title: Drupal 8 password retention

text:
# Question
Title: Drupal 8 password retention
I am currently reviewing Drupal 8's security features and was wondering about how Drupal stores user passwords. I know Drupal uses salted hashes to store the password in the database, but does Drupal also store a user's previously used passwords so that they can't reuse them again? If it does, does that list have a hard limit to it (i.e. does it only store the last twenty used passwords before recycling the list)?

I am only interested in the out of the box experience with Drupal 8. I know there are modules that you can use to add extra functionality/security to user passwords but that isn't part of this question.

Thanks.

# Answer
Out of the box, Drupal only stores the salted hash for the current password. No previous passwords are stored without the help of a contrib module such as Password Policy.
> 3 votes

# Answer
Take a look a the Guardr distribution it has all of the security modules already integrated and configured.

Even if you don't use it, they do a good job of pointing out the security modules available.
> 0 votes

---
Tags: 8, security
---


title: Set view plugin submit handler

text:
# Question
Title: Set view plugin submit handler
I'm trying to create my own AreaPlugin. But there's submit handler doesn't work.

Here is a part of my code.

```
class MyAreaPlugin extends AreaPluginBase {

  /**
   * {@inheritdoc}
   */
  public function render($empty = FALSE) {
    $result['my_plugin_form'] = [
      '#type' => 'form',
      '#form_id' => 'my_plugin_form_id',
    ];
    $result['my_plugin_form']['actions'] = ['#type' => 'actions'];
    // There will be more actions.
    $result['my_plugin_form']['actions']['button_id'] = [
      '#type' => 'submit',
      '#value' => 'Button text',
      '#name' => 'button_name',
      '#submit' => [[$this, 'buttonClickHandler']],
    ];
    return $result;
  }

  /**
   * Button click handler.
   *
   * @param array $form
   *   This form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   This form state.
   */
  public function buttonClickHandler(array &$form, FormStateInterface $form_state) {
    drupal_set_message('exportData');
  }
}

```

How it can be done correct way?

# Answer
Submit handlers only work in a form. If you want to put some kind of an action in render(), then use a normal link to an export display of the view or to a batch which uses an embedded view.
> 0 votes

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


# Question
Title: Simple string replacement in views output?
In Drupal 7, for a view where I wanted to replace every instance of 'am' with 'a.m.' (with a similar replacement for pm/p.m.) in the output, I did this:

```
function mymodule_views_post_render(&$view, &$output, &$cache) {
  if ($view->name == 'target_view') {
    $replace_pairs = array(
      ' am ' => ' a.m. ',
      ' pm ' => ' p.m. ',
    );
    $output = strtr($output, $replace_pairs);
  }
}

```

How do I achieve the same result in Drupal 8? The documentation for the D8 version of hook\_views\_post\_render() is broken/incomplete, but it does mention strtr(), so I imagine something similar should work.

I've already figured out that my if statement will need to test against $view-storage-\>id() instead, and I've noticed that $output is an array (rather than a string) in D8, but I'm not seeing anything appropriate to target in that array. I am new to D8; can someone show me the way?

# Answer
In your custom module, create module\_name.views.inc file and add following code.

```
<?php
use \Drupal\views\ViewExecutable;
use \Drupal\views\Plugin\views\cache\CachePluginBase;

function custom_module_views_post_render(ViewExecutable $view, &$output, CachePluginBase $cache) {
  if ($view->id() == 'VIEW_NAME') {
    $html = \Drupal::service('renderer')->renderRoot($output['#rows']);
    $replace_pairs = array(
      ' am ' => ' a.m. ',
      ' pm ' => ' p.m. ',
    );
    $html =  strtr($html, $replace_pairs);

    $output['#rows'] = $html;
  }
}

```

Replace VIEW\_NAME with your view name and clear drupal cache.
> 3 votes

---
Tags: views, 8
---


# Question
Title: Search results showing nodes which are already under NODE_ACCESS_DENY
In Drupal 7, I have some nodes that are restricted access for anonymous user. I implemented this using `hook_node_access` where if the `user_is_anonymous` and if the operation is `View`, I am giving `NODE_ACCESS_DENY`.

Now, how can I restrict these pages from showing in search results page for anonymous user?

# Answer
You must flush the search cache after you have changed node access records.
> 0 votes

---
Tags: 7, nodes, users, search
---


# Question
Title: How to on Multisite manage users over 1 site
My client need 13 Pages with different domains, so we decided to make different DBs with same codebase. Now, he want to manage the users (admin, editors) over 1 site, so he can select which user has access to which site.

We tested CAS which works so far but i'm not able to define which user has access to which site.

How can I do that?

# Answer
> 1 votes
LDAP, you should define in an external directory (openldap, AD or whatever) which website a user can access or not and define rules inside each website (mapping rôles/sites/ldap properties, more infos here). From there, you can add SSO like CAS.

---
Tags: 8, users, multi-sites
---


# Question
Title: how to add translation feature in custom module (hook_node_view) using google translation api key?
I want to write a code to translate any node (content type: blog) into any other language using a button to translate. I purchased google translate api key but I do not understand how to implement it using hook\_node\_view with a button.

# Answer
> 0 votes
Hope, this module helps you GTranslate

---
Tags: hooks
---


# Question
Title: how to reset taxonomy term ids after deleting all term from all vocabularies
after deleting all terms from all vocabularies we are still left with the next available ID of last created term

is there any module that does such a thing ? or one has to go manually and set the auto increment ? are there are any side effects with using manual way?

# Answer
> 3 votes
Open up phpmyadmin and do a query

```
ALTER TABLE `taxonomy_term_data` auto_increment = 1

```

or using drush

```
drush sql-query "ALTER TABLE taxonomy_term_data auto_increment = 1"

```

But not sure that this is recommended.

NOTE: I am assuming that all terms have been deleted from within the UI

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


# Question
Title: How do I put a div around table with class = table-responsive?
I want to put a div around tables in general and give them the class table-responsible. Therefore I changed the table.html.twig in my theme like this:

```
<div {{attributes.addClass('table-responsive') }}>
  <table{{ attributes.addClass('table') }}>
    ...
  </table>
</div>

```

But if I create a table in CKEditor nothing happend. It's only an ordinary table and nothing changed.

What did I do wrong?

# Answer
CKEditor generates the table on its own. You can see this, if you switch to source. So the changes in twig will have no effekt, because the theme layer doesn't touch the source code that is coming out of the ckeditor. Only the filter layer is checking the source. More for security reasons. But it would be possible to change the table here, if you want to do it in drupal. Or you can modify the configuration of ckeditor itself.
> 3 votes

# Answer
To solve this you can implement a custom filter to surround the table with the needed div.

In Drupal 8 you can write a filter this way: https://www.lullabot.com/articles/creating-a-custom-filter-in-drupal-8

Or use hook\_filter\_info() for Drupal 7: https://api.drupal.org/api/drupal/modules%21filter%21filter.api.php/function/hook\_filter\_info/7.x
> 0 votes

---
Tags: theming, 8
---


# Question
Title: How to really remove the node title of an embedded node?
I want to have easily reusable pieces of content inside my nodes. I did something with Node Embed and Exclude Node Title.

But then I found out that Exclude Node Title is really dirty and simply makes the string itself empty, but there's still HTML, so I have `<h2><a href="the-piece-of-reusable-content"></a></h2>`, which sucks for design (can be hacked around with CSS) but even more for SEO: I don't want my piece of reusable content to be indexed in Google, I don't want Google to start thinking I'm playing them by having an empty `<a>`.

Is there a good fix for this? Or maybe there's a better way to do this, e.g. by embedding blocks inside the content?

# Answer
node\_embed uses `node_view()` and `drupal_render()` to display a node.

With the default `node.tpl.php`, the title is always displayed unless the node is rendered as a "page". The "page" variable is determined in an obscure way in `template_preprocess_node()`, and is typically false with embedded nodes. So the title will be rendered.

```
  <?php print render($title_prefix); ?>
  <?php if (!$page): ?>
    <h2<?php print $title_attributes; ?>><a href="<?php print $node_url; ?>"><?php print $title; ?></a></h2>
  <?php endif; ?>
  <?php print render($title_suffix); ?>

```

I see two ways to prevent this:

* A custom node template for the view mode that is used by node\_embed, in your theme.
* Use a display suite layout for the given view mode. With display suite, the usual node template is ignored, and the title is just one among other visual elements to be positioned in the display. I prefer this solution, because I like display suite :)

node\_embed ships with a dedicated view mode 'node\_embed', which is used by default for embedded nodes. So this is the one you need to configure or target with a template.

BTW, at the time of this writing, the module page of Node embed says it is no longer supported. There is another module, Entity embed, which seems not to have this problem.
> 1 votes

---
Tags: 7
---


title: Custom Taxonomy Term Template

text:
# Question
Title: Custom Taxonomy Term Template
I would like to use a custom template for my taxonomy term pages. I attempted doing so by creating a hook in template.php like so

```
function mythemename_preprocess_page(&$variables){
    if($hook == 'node'){
        if(arg(0) == 'taxonomy'){
            $vars['template_file'] == 'node-taxonomy';
        }
    }
}

```

And then creating a custom template called node-taxonomy.tpl.php

However the page does not change.

I understand that I can achieve something similar using views, but since other sites are using different themes on our drupal instance I'd prefer not to change anything that relies on those views.

# Answer
Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds:

* taxonomy-term--tid.tpl.php
* taxonomy-term--vocabulary-machine-name.tpl.php
* taxonomy-term.tpl.php

Note that underscores in a vocabulary's machine name are replaced by hyphens.
> 1 votes

# Answer
In addition and for those who need, you can provide template suggestions for taxonomy terms that way :

```
function hook_theme_suggestions_taxonomy_term_alter(&$suggestions, $vars, $hook) {
  $term = $vars['elements']['#taxonomy_term'];
  $sanitized_view_mode = strtr($vars['elements']['#view_mode'], '.', '_');
  $suggestions[] = 'taxonomy_term__' . $term->bundle() . '__' . $sanitized_view_mode;
  $suggestions[] = 'taxonomy_term__' . $term->id() . '__' . $sanitized_view_mode;
  $suggestions[] = 'taxonomy_term__' . $sanitized_view_mode;

  return $suggestions;
}

```

It will provide, e.g. :

```
"taxonomy_term__vocabularyname__teaser"
"taxonomy_term__257__teaser"
"taxonomy_term__teaser"

```
> 1 votes

---
Tags: theming, taxonomy-terms
---


# Question
Title: View with two filter groups using "OR" not aggregating correctly
I have a view that I need to count the number of items currently unread. It is a list that combines slightly different entities on slightly different conditions, so I have two filter groups(using OR) on my view to select all content appropriately. This works well except for the aggregation of the results. When I set the view to aggregate by counting a nid field, it doesn't aggregate the results. Instead, it simply converts each nid result to display as "1".

Where is my attempt to aggregate this view going wrong?

My filters:  My Results:

# Answer
> 0 votes
The answer to this was actually quite simple, and the source of error was misunderstood.

The filter groups were NOT the issue at all, but rather that there were excluded fields in the view which were not set to "count" under their aggregation settings. This broke the count. If you are having this issue, make sure all fields in your aggregation view are set to "count".

---
Tags: 7, views
---


# Question
Title: Load node entity from external script with image URI
I'm attempting to grab a node from a node ID in an external php script. With Drupal 7 I used the bootstrap.inc but with Drupal 8 this are a bit different.

I've called Drupal with:

```
define('DRUPAL_DIR', $webroot);

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
use Drupal\file\Plugin\Field\FieldType;

$autoloader = require_once DRUPAL_DIR . '/autoload.php';
$request = Request::createFromGlobals();
$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->boot();

require_once DRUPAL_DIR . '/core/includes/database.inc';
require_once DRUPAL_DIR . '/core/includes/schema.inc';

```

I'm then successfully loading the node with:

```
$node = \Drupal\node\Entity\Node::load($nid);

```

I'm able to grab values with:

```
$node->get('field_test_field')->value

```

but I'm unable to get a uri for images. If I try and get the target\_id with:

```
$node->get('field_image_field')->value

```

I get an error and the following in the error log:

```
Error: Call to undefined function Drupal\\file\\Plugin\\Field\\FieldType\\file_default_scheme() in /var/www/vhosts/rootpath/webroot/core/modules/file/src/Plugin/Field/FieldType/FileItem.php on line 39

```

Any idea how I get get the image path? The returned node object includes:

```
[field_image_field] => Array
            (
                [x-default] => Array
                    (
                        [0] => Array
                            (
                                [target_id] => 44595
                                [alt] =>
                                [title] =>
                                [width] => 250
                                [height] => 89
                            )

                    )

            )

```

Not sure what I missing, perhaps I need to include a namespace or something? Thanks in advance!

# Answer
> 1 votes
I had the exact same problem with an external script, but with the field\_files field.

I can see it in when doing a print\_r on the node object:

```
        [field_files] => Array
            (
                [x-default] => Array
                    (
                        [0] => Array
                            (
                                [target_id] => 2
                                [display] => 1
                                [description] =>
                            )

                    )

            )

```

But trying to access it via $node-\>field\_files-\>value gives:

```
Fatal error: Call to undefined function Drupal\file\Plugin\Field\FieldType\file_default_scheme() in /[redacted]/core/modules/file/src/Plugin/Field/FieldType/FileItem.php on line 39

```

I can access other fields in this manner just fine. Also, doing a $node-\>getFields() should return an array of all the fields, but this throws the same error.

**I solved the problem by including a file:**

```
require_once DRUPAL_DIR . '/core/includes/file.inc';

```

And then I can access the file id with:

```
$node->field_files->target_id;

```

So I am able to get the uri of file attached to the node with:

```
$fid = $node->field_files->target_id;
$file = \Drupal::entityManager()->getStorage('file')->load($fid);
$uri = $file->uri->value;

```

It might be a little different for your image field, but including that file should stop that error.

# Answer
> 1 votes
you can try:

```
$image_uri  = $node->field_image_field->entity->getFileUri();

echo $image_uri;

$image_url= file_create_url($image_uri);

echo $image_url;

```

in the variable "**$ image\_uri**" contains the uri of the image.

in the variable "**$ image\_url**" contains the complete url of the image.

Note: please, change **field\_image\_field** for your machine name field

---
Tags: nodes, external-scripts
---


title: How to mark a node as read per user?

text:
# Question
Title: How to mark a node as read per user?
I'm wondering what the best solution is to mark a node as read per user.

The below scenario is what I am trying to achieve:

1. Admin creates a node which requires to be read and confirmed and flags user `a+b`.
2. User `a+b` receives an email staying there is a new content that requires them to read it.
3. User `a` goes to the page and reads the content and clicks "I confirm I have read this" which cannot be reversed by user `a`.
4. When admin views the page they can see that user `a` has confirmed read but user `b` hasn't.

My first initial thoughts was to use a combination of Flag, Views and Rules.

Any suggestions?

# Answer
Using the Flag, Views and Rules modules (as in your question) is indeed a way to get this to work. But assuming you have way more then just 2 (= a+b) users, you probably also want to add the Views Bulk Operations (VBO) module to this. Read on for more details ...

> 1. Admin creates a node which requires to be read and confirmed and flags user `a+b`

Use Flag to create a (1st) flag to flag your nodes, and which at first will be used by the admin to set the flag for "*user `a+b`*" (as in your question), as further detailed below. The labels for this flag could be something like this:

* to flag: "*Confirmation outstanding*".
* to unflag: "*Confirmed*".

To actually set the flag for user `a+b` (imagine you have dozens ...), you should create an appropriate view (using Views) to create a list of such user `a+b`. And use Views Bulk Operations (VBO) to transform that view, so that the "operation" to be performed by that VBO-list is to execute a Rules Component (created with Rules).

If you're not familiar with how to do so, have a look at the video about Using Rules components with VBO". You may also want to watch the subsequent "Using Rules components with more than one parameter" video.

The actual Rules Component to be used by this VBO list, is simply a rule to flag a node by a single user. The trick here is the value to use as flagging user: it should use the `uid` as contained in the VBO list row being processed (so not the current uid, which would be the admin using the VBO list).

> 2. User `a+b` receives an email staying there is a new content that requires them to read it.

Just enhance (extend) the Rules Component from the previous step to add an additional action, which is to also send an eMail to each user being processed. Tune the subject and body of the eMail to fit your needs.

> 3. User `a` goes to the page and reads the content and clicks "I confirm I have read this" which cannot be reversed by user `a`

Use Flag to create a (2nd) flag with labels for this flag that could be something like so:

* to flag: "I confirm I have read this".
* to unflag: "I already confirmed to have read this".

When user `a` visits this page, all that's needed is that user `a` clicks the link which says "*I confirm I have read this*". After user `a` flagged it like so, the (1st) flag set for the node by user `a` needs to be removed (= unflagged). That's something you can do with a 2nd rule, which looks like so:

* Rules Event = after flagging (with 2nd flag).
* Rules Action = unflag (with 1st flag)).

However, after user `a` flagged the node (with the 2nd flag), the link to unflag it again will be shown. But you don't want user `a` to be able anymore to unflag it again. To prevent that to happen, a possible solution is to create a 3rd rule to either disallow such attempt to unflag, or to capture such attempt and automatically flag it again. Another approach could be via a custom template, which will simply hide the unflag link.

> 4. When admin views the page they can see that user `a` has confirmed read but user `b` hasn't.

Create a Views block to list all users who have **not flagged** the node **anymore** with the 1st flag (these would be your users like `a`). And a similar block to list all users who have **still flagged** the node with the 1st flag (these would be your users like `b`).

**Note**: the above approach is entirely entity based, and may be considered as a possible alternative to some of the facilities provided by the Legal module (your question might be about similar functionality).
> 3 votes

# Answer
Here's an alternate, though useful more if all content of a specific content type will need to have folks mark all new content as read.

If you use the Webform module, you can use Webform Default Fields to assign a default form to all instances of that content type. Each node then becomes a unique webform (taking on the node title). This would allow you to additionally indicate a single submission per form, or per time period, or per session; also make for an easy download of user info. Utilizing AJAX, the form disappears once submitted if the user is limited to a single submission.

If the content gets modified and you need folks to read and mark it again (where it has been set to a single submission per user), simply clear the submission table and the form is back.
> 0 votes

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


title: Protect page from guest users

text:
# Question
Title: Protect page from guest users
I am using drupal for one of my portals. Logged in users can see the "documentation link" button in the application which is pointed to an html page. My concern is that, that link is accessible even if someone bookmark the link and open it without logging in to drupal portal. Is there some option/module in drupal available so that if someone access our documentation link directly, it should redirect to login page and load the html page if he is already logged in.

# Answer
Assuming that documentation link is a landing page either resulting from a content type or View Page, you can easily restrict the access to that page via permissions. The concept can be found using Node View Permissions. Although the module is overkill, it will provide ways on how to use it. The recommendations would be to do this through standard permissions first and then use modules or write your own custom module to do this for you.

Additionally you could write a hook that checks to see if user is an anonymous user, if so then let them through otherwise redirect them to a login page. In D7, you can write a hook to check the user\_is\_logged\_in variable. In D8 this answer to check for logged in users.

Other module:

1. Content Access

Also when you add questions, please indicate if it's for D7 or D8.
> 0 votes

---
Tags: navigation
---


# Question
Title: How to find all inputs that make use of the php input filter to fully disable the php filter module?
I want to disable the PHP Filter module on a large website, but going through all nodes, blocks and other fields where you could make possible use of the php filter would take eons.

Is there a simple way or method maybe by running SQL queries to find out where the php filter is used throughout my website?

# Answer
Rather than re-inventing the wheel, just install the Security Review module, which has the following check:

> PHP or Javascript in content (nodes and comments and fields in Drupal 7)

For blocks you can check the format column in the block\_custom table.

The difficult one is Views - I've yet to find a reliable way to locate rogue PHP in Views programmatically.
> 9 votes

# Answer
You can able to find all views which have php enabled by running below command in MySQL...

```
SELECT vv.name , vd.display_options
FROM views_display AS vd
LEFT JOIN views_view AS vv ON vv.vid = vd.vid
WHERE vd.display_options REGEXP '.s:[3]+:"php".*'

```

views\_display table stores this information in serialized format.... I have tested above query works as expected.. Hope it helps to solve the views PHP riddle :-)
> 7 votes

# Answer
Old question, but was first on my Google search.

There's a Contrib Module that is supposed to find all PHP entries:

PHP Finder

> 'PHP Finder' module is used to find where the PHP filter format is used, whether in the node, block or views.
> 1 votes

# Answer
The code from Anil Sagar above only works if the view is saved in the database. If the view is only in code it won't work. So, I wrote a little snippet that I run to save all the views to the db. Then I can use the MySQL snippet to surface php.

```
  $views = views_get_all_views();
  foreach ($views as $view) {
    if (empty($view->disabled)) {
      $view->save();
      drupal_set_message('view saved: ' . check_plain($view->name));
    }
  }

```
> 0 votes

---
Tags: input-formats
---


# Question
Title: How to filter a View by Year and Month with Summaries for each one
or *How to remove the exception parameter of a View's contextual filter*

Hi,

In Drupal 7 I have a View with two contextual filters (date field):

/view-url/YEAR/MONTH

When YEAR is the first argument and if there is none I make a Summary of the view, so the result can be something like:

```
* 2017
* 2016
* 2015

```

And MONTH is the second parameter, that if it's not present, the view also makes a Summary:

```
* January
* February
* ...

```

I think that I'm stuck replicating the same View in Drupal 8, because the first Summary has a default parameter "all" wich is the exception of the second parameter.

1. Is there a way to remove that default exception parameter from the url of the first summary? (I'm getting view-url/YEAR/all for each year of the list as its url).
2. Can I expose YEAR and MONTH so people can easily navigate trough the view?

Also if there is a better way to built that kind of view (like better performance) I'll apreciate the advice.

# Answer
> 0 votes
You can override the parameters in each individual display. I'm not sure about D8, but in D7, the "display order" of the displays was important as well, such that you'd get the behavior of the higher priority display (lower display order) as desired. In D7, I had to go into the database itself, and change the "position" of these pages in the "views\_display" table. (I know of no way to do this in the UI.)

---
Tags: 8, views
---


# Question
Title: Create View and show tax terms that use the same term as the content
everyone,

I am currently trying to create a view, but unfortunately I can't get a result.

Initial situation:

ContentType A uses a term from Tax B Tax C uses a term from Tax B

Now I would like to have all terms of C listed on the page of A, which have the same tax term of B as A.

Example: A= content of the topic "software"

Tax B = various industries (software, consulting, finance, construction, medicine....)

A has the term "software" from Tax B

Tax C = Various companies

C also has a term from Tax B, e. g. Microsoft is assigned to "software".

Now I would like to list beside the article about software all companies, which have also assigned the term "software".

What I've done so far: 1) View created as a block, output of taxonomy terms of vocabulary C (company) 2.) Taxonomy Term field: Name added to output 3.) Context filter taxonomy term: (B) added If the filter value is NOT available: Provide default value: Taxonomy term ID from URL \[x\] Load standard filter of the term page \[x\] Load default filter of the node page (good for related vocabulary blocks). ------\[x\]Industry

If I test the view in the preview with a TID from Tax B, then it works, too. But unfortunately not on the website.

Can you help me with that? I would appreciate a helpful answer!

Greetings, Alex

# Answer
It works in your test because you're giving it a TID, but in actual practice, that won't be in the URL when you're viewing the content. Therefore, your contextual filter shouldn't be a taxonomy term, but the content ID from the URL, use that to get the node's taxonomy terms (B), and then you might be able to directly get other items, filtered as taxonomy terms (C) that share those, or else you might need to use relationships.
> 0 votes

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


# Question
Title: How to modify the image output for just one content type?
We are using a field\_image field across multiple content types. For the basic content type (only) we want to lazy load the images as such it requires the following format. How can this be done for just basic content type?

Current output:

```
<img src="some-url">

```

Desired output:

```
<img data-src="some-url">

```

# Answer
You can do this by defining a "lazy load" image style and using it as the image display. This style does not have to do any resizing. It would just be a placeholder flag for a preprocess function like:

```
function my_theme_preprocess_image(&$variables) {
  if ( $variables['style_name'] == 'lazy_load') {
    $variables['attributes']['data-src'] = $variables['attributes']['src'];
    unset($variables['attributes']['src']);
  }
}

```

Nice thing is that you can use this style anywhere to get lazy loading images.
> 3 votes

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


# Question
Title: How to optimize already uploaded images?
Is it possible to compress or optimize images that are already uploaded to the server? What about a method to optimize the images on upload?

Goal:

1. Take all existing images, compress them, and then save them with the same file name and directory so that the image URLs are not broken.
2. On upload of an image, optimize it so we don't have to repeat #1 above.

# Answer
> 3 votes
The common approach is not to modify the uploaded original image, but to calculate additional image variations and serve those to your visitors. All image styles created in `/admin/config/media/image-styles` are automatically compressed, using the settings form `/admin/config/media/image-toolkit`

# Answer
> 1 votes
You're looking for https://www.drupal.org/project/imageapi\_optimize. It uses image styles.

# Answer
> 0 votes
You could use something like imageMagick

Or depending on what kind of compression or optimisation you want to do you could go for a server side shell script or tools that handle the image processing. Run it as a cron job or something late at night.

You will likely need to install something like imageMagick on the server in any case.

---
Tags: 8, media, caching
---


# Question
Title: Drupal 8 Link Autocomplete Filter by Bundle
Does anyone know how to limit the autocomplete suggestions of Link Fields to only certain bundles -- not globally, but per Link Field instance? I nearly found a solution in customizing https://github.com/minnur/Alter-Entity-Autocomplete , but this is global for all autocompletes, and I need to get the calling Link Field instance somehow.

# Answer
You can now use the following contributed module to solve the issue:

Link Field Autocomplete Filter

> This module adds a Link Field configuration for filtering the allowed content types in the autocomplete field.
> 1 votes

# Answer
This is possible with hook form alter:

```
function hook_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // if $form_id ==  'xyz'
  $form['field_mylink']['widget'][0]['uri']['#selection_handler']="default:node";
  $form['field_mylink']['widget'][0]['uri']['#selection_settings']=[
    'target_bundles'=>['article'=>'article', 'page'=>'page'], //etc
  ];

}

```
> 0 votes

---
Tags: navigation
---


title: Help link doesn't appear in module page

text:
# Question
Title: Help link doesn't appear in module page
What do I have to do to show help link in module menu?

My code looks like:

```
/**
 * Implements hook_help().
 */
function mymodule_help($path, $arg) {
  if ($path == 'admin/help#mymodule') {
    $output = '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t('descripton.') . '</p>';
    return $output;
  }
}

```

# Answer
> 0 votes
In order to the help link appear on the module page (`admin/modules`), you should have both the core Help module and your module enabled.

# Answer
> 0 votes
It is advised to clear cache after implementation of any hook. Just clear your cache and it will show up.

You can also clear cache by drush command "drush cc all".

# Answer
> 0 votes
/\** * Implements hook\_help(). \*/

function mymodule\_help($path, $arg) {

switch ($path) {

```
case 'admin/help#mymodule':
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('descripton.') . '</p>';
return $output;

```

}

}

Hope this will resolve your problem.

---
Tags: hooks
---


title: Files inside styles gives a 403 error

text:
# Question
Title: Files inside styles gives a 403 error
I accidentally changed the permissions of sites/default/files folder to 777, but later I changed back to 755. From that moment images in the articles are not showing. It's giving 403 forbidden error. Please guide me.

# Answer
> 1 votes
Well, the question and description of the situation leaves some questions open but from a first glimpse I would assume, that you maybe missed to change also the ***nested folder and file permissions correctly recursively***. Therefore read this Drupal guide and make sure that you also have a working temporary path set up in Drupal configuration to make Drupal able to rebuild its file system. Also make sure that you have cleared all the Drupal caches and Image style caches to force Drupal to rebuild the image styles and implementations.

BTW: theming is the wrong tag here. This is not a theming specific question.

---
Tags: files
---


title: Migrate process plugin to skip values

text:
# Question
Title: Migrate process plugin to skip values
I'm working with Migrate. On my json source file I've the alias of the node to import. There are nodes that does not have an alias, so in the json I've things like "/node/1234". So I want to skip this alias (not the entire node).

Is there a way to do this?

I'm already using custom process but I don't know how to skip a single value.

# Answer
> 3 votes
Use `skip_on_value` plugin in Migrate Plus module.

Sample code:

```
id: custom_menu
label: Menu
migration_group: custom
migration_tags:
  - Drupal 7
source:
  plugin: menu
process:
  id:
    -
      plugin: skip_on_value
      equals: true
      source: menu_name
      method: row
      value:
        - devel
        - features
    -
      plugin: static_map
      bypass: true
      source: menu_name
      map:
        main-menu: main
        management: admin
        navigation: tools
        user-menu: account
  label: title
  description: description
destination:
  plugin: entity:menu

```

---
Tags: 8, migrations
---


# Question
Title: How do I disable modules via admin interface or via Drush?
In Drupal 7 it was possible to disable modules via admin interface or via Drush `drush pm-disable`. In Drupal 8 the checkboxes are greyed out in the admin interface and Drush is not able to disable them via pm-disable? How do I disable modules in Drupal 8 with Drush or via admin UI? Or do I need Drupal console for such tasks?

*(Sorry for the confusion caused by using the word "programmatically" mistakenly, it was referring to the meaning of "via command line")*

# Answer
> 3 votes
You can also use drupal console https://drupalconsole.com/ and simply use the command

```
drupal module:uninstall token

```

And for install

```
drupal module:install token

```

# Answer
> 10 votes
Like the **admin interface** in **Drupal 8** states in the message area, the paradigm and concept of **how modules get installed and disabled** has *changed* in Drupal 8, since there were many problems involved in the way how it was before, because of Database left-overs and data inconsistencies while disabling and enabling modules, etc.

Therefore users are encouraged to rather **uninstall modules than disabling them** now in D8. This doesn't mean the modules are gone or removed from the Drupal root, but they are completely removed from the database including their configuration.

Try `drush pm-uninstall module-name` instead and you will see the desired effect you are after.

The checkboxes are greyed out to be still able to enable and install inactive modules the way known from D7. But you can't disable them this way no more. And uninstalling should not be provided by checkboxes, since this would be to dangerous.

Look twice in the admin interface: You will find a new tab for uninstalling modules too.

# Answer
> 3 votes
As the question asks for *programmatically* and that's why I came here in the first place I'll add a working code snippet to be placed inside `MYMODULE.install`:

```
/**
 * Uninstall Field UI.
 */
function MYMODULE_update_8001(&$sandbox) {

  \Drupal::service('module_installer')->uninstall(['field_ui']);

}

```

---
Tags: 8, drush
---


# Question
Title: how to add form action twig template form
I have created a module in which I create a form and then rendered it in twig template I want to know how to give form action in a twig template i.e how to pass form action attribute in twig form.

any help will be greatly appreciated .

**mymodulename-form.html.twig** file

```
<form>
  <div class="form-group">
   <label for="name">{{form.first_name['#title']}}</label>
    <div class="input-group">
        {{form.first_name}}
        <span class="input-group-addon danger"><span class="glyphicon icon-remove"></span></span>
    </div>
  </div>

```

# Answer
> 1 votes
I am assuming you are building this form with Form API and not plain HTML (don't do that). You need to add the `attributes` to ensure you get everything you need.

```
<form{{ attributes }}>

```

See the main `form.html.twig` template: https://api.drupal.org/api/drupal/core%21modules%21system%21templates%21form.html.twig/8.4.x

In general, I advise you to theme the form elements themselves instead of stitch the form together like this, because you will likely be missing the things in the form Drupal adds behind the scenes to a rendered form.

---
Tags: 8, forms
---


# Question
Title: How can i use DB Connection of another site of my multisite?
Following situation: I have a multisite with several sites. The codebase is the same but every site has his own database. Now i'm creating a module where i want to make adjustments in the databases for all sites at the same time. So i have to be able to make database connections to the other sites.

I already was able to get the settings from the other sites with that:

<pre><code>$sites = glob(DRUPAL_ROOT . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);

foreach ($sites as $site) {
  $site_path = str_replace(DRUPAL_ROOT, '', $site);
  $siteName = str_replace('/sites/', '', $site_path);

  if (is_readable($site . '/settings.php')) {
    $siteConfigs[$siteName] = [];
    $settings = [];
    $databases = [];
    $app_root = DRUPAL_ROOT;

    require $site . '/settings.php';
    $siteConfigs[$siteName]['settings'] = new Settings($settings);
    $siteConfigs[$siteName]['databases'] = $databases;
  }
} ```
</code></pre>

How can i use DB Connection of another site on my multisite installation? I tried different things like:

```
foreach ($siteConfigs as $siteConfig) {
  Database::addConnectionInfo('default', 'default', $siteConfig['databases']['default']['default']);
  $db = Database::getConnectionInfo();
  var_dump($db);

}

```

But it always returns just the current site.

Thanks for any advice!

# Answer
You can initialize multiple database connections like this in your settings.php file:

```
<?php
$databases['default']['default'] = array(
    'database' => 'sitedb1',
    'username' => 'admin',
    'password' => 'admin',
    'prefix' => '',
    'host' => 'localhost',
    'port' => '3306',
    'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
    'driver' => 'mysql',
);

$databases['yellow-site']['default'] = array(
    'database' => 'sitedb2',
    'username' => 'admin',
    'password' => 'admin',
    'prefix' => '',
    'host' => 'localhost',
    'port' => '3306',
    'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
    'driver' => 'mysql',
);

$databases['green-site']['default'] = array(
    'database' => 'sitedb3',
    'username' => 'admin',
    'password' => 'admin',
    'prefix' => '',
    'host' => 'localhost',
    'port' => '3306',
    'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
    'driver' => 'mysql',
);

```

Then you can get the connections with your module etc.:

```
<?php
$greenSiteDatabase = Database::getConnection('default', 'green-site');
$yellowSiteDatabase = Database::getConnection('default', 'yellow-site');
$defaultDatabase = Database::getConnection('default', 'default');

```

You can query a database like so:

```
$banana = $yellowSiteDatabase->select('SomeTable', 'st')
  ->fields('st', ['fruit'])
  ->condition('fruit', $someCode)
  ->execute()
  ->fetchObject();

```
> 1 votes

---
Tags: 8, database, multi-sites
---


# Question
Title: View content based on if a new session is created
I am running a Drupal 7 website using the Ubercart module. I am trying to show some HTML content when users get on the site, and not keep viewing it when they click on a certain button. I need this piece of content to appear at the top of the website so I tried putting it in the HTML in the page.tpl.php file, which works, but then it keeps appearing every time the user goes to a different page or reloads the page. The way I am thinking of approaching this is as follows:

1) A new session is created when a user lands on the site.

2) If a new session is created, I will copy that session's value into another variable (`$variable = session_id();`), and execute some code when the content of `$variable` is equal to the value returned from `session_id()`.

3) I will have that piece of content as a `<form method="POST">`. When the user clicks on the close button, that will `$variable = $variable + 1;`.

4) This way the `if` statement will be `FALSE` for this session and the content won't appear anymore.

my problem is with knowing if a NEW session has been created or not. I have tried using `if (drupal_session_started()) { echo "s";} ?>` but that doesn't print anything which means I still can not check for new sessions started. Shortly, I need a way to know if a new session has been started on the site, so I can do the mentioned steps. Bonus if you tell me what you think about how I'm going about doing this, because I'm a Drupal newbie and there might be easier solutions.

# Answer
> 0 votes
There are some modules that do this:

Popup message (D7+D8)

> Display popup message for users once per browser session.

Even if you don't like the way this module handles things, you can look at the code to see how it limits the message to once per session.

Splashify (D7+D8)

> Display a splash page anywhere on your site by redirecting the user, showing a lightbox, or displaying a popup. This module is designed to be search engine friendly, mobile device friendly and offers multiple configuration options.

# Answer
> 1 votes
On Drupal, when a new user logs in, a new session is started; when the session expires, the user must log in again. You just need to use the hook that Drupal uses when a user logs in, which is `hook_user_login()`. Take `system_user_login()` as code example.

```
function system_user_login(&$edit, $account) {
  // If the user has a NULL time zone, notify them to set a time zone.
  if (!$account->timezone && variable_get('configurable_timezones', 1) && variable_get('empty_timezone_message', 0)) {
    drupal_set_message(t('Configure your <a href="@user-edit">account time zone setting</a>.', array('@user-edit' => url("user/$account->uid/edit", array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone')))));
  }
}

```

Keep in mind that PHP variables don't persist between sessions. If, for example, you need to show the content only once for users, you need to use code similar to the following one.

```
function mymodule_user_login(&$edit, $account) {
  if (variable_get("mymodule_show_message_{$account->uid}", 1)) {
    // Show the message.
    variable_set("mymodule_show_message_{$account->uid}", 0);
  }
}

```

For anonymous users, you cannot count on the session being saved between two different page requests. Drupal, at the end of a page request, destroys the session for anonymous users, if it is empty. See `drupal_session_commit()`.

```
  if (empty($user->uid) && empty($_SESSION)) {
    // There is no session data to store, destroy the session if it was
    // previously started.
    if (drupal_session_started()) {
      session_destroy();
    }
  }

```

For a solution that works for both the anonymous users and authenticated users, I would rather implement `hook_page_build()`, although this has the side effect of always creating the session for anonymous users, with all the consequences.

```
function mymodule_page_build(&$page) {
  if (empty($_SESSION['mymodule_page_disclaimer_shown'])) {
    // This is a new session. Show the disclaimer.
    $page['page_top']['disclaimer'] = array(
      '#markup' => t('Acme, Inc. is not responsible for the contents of this sample code.'),
      '#weight' => 0,
    );
    $_SESSION['mymodule_page_disclaimer_shown'] = TRUE;
  }
}

```

In this way, since the session is not empty, it won't be destroyed from Drupal after serving the page. The second time the anonymous users visit the site using the same computer/browser, the disclaimer will not be shown.

---
Tags: 7, sessions
---


# Question
Title: How to update users table including relation tables with entity?
I'm currently creating a module which should help me manage users from 1 instance for my other multisite instances. So there will only be admins/editors and no other user logins. My goal is now to hook the user create / update function and save same datas on all other databases.

But i'm not able to bring it work.

I started with the update hook because i think it's easier. Here is module function and one of my try:

```
/**
 * Implement hook_entity_update.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity object.
 */
function my_module_entity_update($entity) {

  if($entity->getEntityTypeId() === 'user') {
    $sites = glob(DRUPAL_ROOT . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);

    foreach ($sites as $site) {
      $siteName = str_replace(DRUPAL_ROOT . '/sites/', '', $site);
      if ($siteName !== 'default') {
        Database::getConnection($siteName)
          ->update('users')
          ->fields($entity->getFields())
          ->condition('type', $entity->getEntityTypeId())
          ->condition('id', $entity->id())
          ->execute();
      }
    }
  }

}

```

But here i get the error because the `$entity->getFields()` returns an object instead of an array.

How can i save the whole user entity at once including the roles and other related tables?

Do i really need to assign every single field? Or is there a hopefully easier way?

# Answer
> 4 votes
Long answer short: You can't save them at once and have to synchronize the user fields manually.

Users are fieldable entities and field data is stored in different tables. So in your case you'd have to create all fields you like to synchronize in all your sites and you need to read them from your base site's user entity field by field and write them to the according tables of your target sites.

A very error prone approach on database level (not mentioning the complexity with a growing number of attributes/client sites).

I strongly suggest a less low-level solution. E.g. by utilizing Drupal's REST services, considering OAuth2/OpenID server/client, LDAP or SAML for user authentication. (Just some keywords to use Google with; there are some contrib D8 modules in heavy development for all of these approaches.)

---
Tags: 8, entities, database
---


# Question
Title: REST API POST: User is not authorized despite being admin
I'm working on a quick script as a proof of concept to POST content to my Drupal instance using the REST API.

The user I'm trying to post as *is an Administrator*, but I get an error that they don't have permission to create the Content.

Here's the simple script I'm using so far (removed a lot of debug and extra code for brevity). It gets a CSRF token, constructs the JSON body and POST's the request to the REST endpoint to create a piece of content of the `game` type.

```
<?php

$autoloader = require_once __DIR__ . '/../../vendor/autoload.php';
use GuzzleHttp\Client;

$client = new Client([ 'base_uri' => $url ]);

$csrfResponse = $client->request('GET', '/rest/session/token');
$csrfToken = trim($csrfResponse->getBody());

$jsonPayload = [
    'type' => 'game',
    'title' => [[ 'value' => 'Test Game ' . strtotime('now') ]],
];

$postResponse = $client->request('POST', '/entity/node?_format=json', [
    'auth' => [$user, $password],
    'body' => json_encode($jsonPayload),
    'headers' => [
        'Content-Type' => 'application/json',
        'X-CSRF-Token' => $csrfToken
    ]
]);

debug("Status Code: " . $postResponse->getStatusCode());
debug($postResponse->getBody());

```

**Problem:** I get `403 Forbidden` response telling me:

```
{"message":"You are not authorized to create this node entity of bundle game."}

```

This despite the fact that the user is an Admin (and I even tried giving them explicit permission to Create and Review contents of the Game type). I get the same error if I put in a bogus username and password as well.

The answers suggested in the related question about "403 Forbidden when creating a page with RESTful API" did not work for me.

# Answer
My problem was that the Basic Auth module was not enabled. I only found that out by chance as I was scrolling through the enabled modules, as the error message above didn't indicate how authentication was being done.
> 1 votes

---
Tags: users, 8
---


# Question
Title: Computed field: sum fields from different content type
I use the module "computed field".

How can I calculate (sum) the value from one field in one content type and a field from other content type? Is it possible?

Sorry for my English.

# Answer
You could do that by querying database :

```
<?php
$database = \Drupal::service('database');

$database->select('node_<FIELD>', 'n');
$database->fields('n', ['bundle']);
$database->addExpression('SUM(n.<FIELD>_value)', 'sum');
$database->groupBy('n.bundle');
$results = $database->execute();

foreach($results->fetchAll() as $result){
    print $result->bundle.' : '.$result->sum;
}

```

This example is for node, but quiet similar with taxonomy or other entity type.
> 0 votes

# Answer
You can create one view and add your fields. Then review the following response: Or the following response
> 0 votes

---
Tags: entities
---


# Question
Title: How do I access a view's results with a custom module?
I'm creating a module that will expose a feed of content (under certain rules) as a JSON response. I want to use a Drupal 8 view to construct a query for that set of content, since it is a complicated set of rules.

Is there a way to query a Drupal 8 view in a custom module and iterate over the results?

Note that I am not trying to modify the output of the View with PHP; I just read the results and package them into a JSON response in my custom module.

I'm looking for something similar to `entityQuery` where I can instantiate a view object, execute it, and then iterate over the nodes that are in the result set.

Most of the searching I've done here and on Google points to Drupal 7 answers (which might not be relevant to Drupal 8 code), or otherwise generic Drupal query examples (when I am specifically looking for the Views module).

As an example, I'm looking to be able to do something like this (pseudocode):

```
class MyCustomModuleController {

  public function getFeed() {
    $view = View::get('my_view_name');
    $nodes = $view->execute();
    $response = [];
    foreach ($nodes as $node) {
      $response[] = $node->getSomeField();
    }
    return $response;
  }

}

```

# Answer
```
$view = \Drupal\views\Views::getView('my_view_name');
$view->execute();

foreach ($view->result as $row) {
    //dont remeber if $node is fully loaded
    $node = $row->_entity;
    // if not, add this
    $node = Node:load($row->_entity->id());
    $response[] = $node->[FIELD]->view('full'); // full display
}
return $response;

```
> 4 votes

---
Tags: views
---


# Question
Title: How do I get machine name by entity type and its ID?
How do I get machine name by entity type and its ID?

The code I am using is the following.

```
$block = \Drupal\block_content\Entity\BlockContent::load(2);
$render = \Drupal::entityTypeManager()->
getViewBuilder('block_content')->view($block);

```

# Answer
> 3 votes
To get the type and id of a given entity, you can do:

```
$type = $entity->bundle();
$id = $entity->id();

```

Some entities, like Node, provide wrapper methods to return the bundle:

`$type = $node->getType();`

But Block doesn't. So if it is Block that you are after:

```
$block = \Drupal\block_content\Entity\BlockContent::load(2);
$type = $block->bundle();
$id = $block->id();

```

---
Tags: 8, entities
---


# Question
Title: How to add condition for 1st Iteration in views-view-fields.html.twig file
I am trying to implement a carousel , inside my **views-view-fields--block\_1.html.twig** , I want to add **active** class inside the div for the first Iteration . I have added the code in twig file but every time it is adding active class for all the iteration.

**code snippet:**

```
{% if fields.counter.content == 1 %}
{% set tag = "active" %}
{% else %}
{% set tag = "" %}
{% endif %}

```

In my view title,body,image and result counter fields are there . From result counter i am getting the value and comparing inside the above twig file. Can anyone give suggestion, how to achieve this.

Thanks,

# Answer
If your code snippet is within a for loop, you could use either `loop.first` or `loop.index` in your if statement to target the first iteration. Refer to https://twig.symfony.com/doc/2.x/tags/for.html#the-loop-variable

Thus your twig template would probably resemble:

```
{% for item in items %}
  {% if loop.first 1 %}
    {% set tag = "active" %}
  {% else %}
    {% set tag = "" %}
  {% endif %}

... render row/field with class in template ...
{% endfor %}

```
> 1 votes

---
Tags: theming
---


# Question
Title: Display image/media entities view from node to twig template
Would like to ask how I can output or display the image entities from my entity browser/entity view to the twig template. I'm using the `media entity module` on drupal and then using views to select and display the images that are selected.

Apologies if my explanation is bit sloppy since I'm still new to drupal.

**Setup Media Bundle**

**Setup Entity Browser using View**

**Set View as a Widget for entity browser**

**Select Images**

In this screenshot I've selected two images to be displayed. I'm using the code the below to try and display the entities but it seems incorrect

```
{% for image in node.field_slider_image  %}

            <img src="{{ file_url(image.entity.uri.value) }}">

{% endfor %}

```

# Answer
> 3 votes
For an image in a media entity you need one step more. Something like this should work:

```
{% for media in node.field_slider_image  %}

  <img src="{{ file_url(media.entity.field_image.entity.uri.value) }}">

{% endfor %}

```

But without debugging tools this is hard to find out. You have three nested entities and their field values, the node with the media field, containing media entities with the image field, containing file entities, where you finally find the uri field.

An easier options might be to let Drupal do the rendering by configuring this in UI and theme the field, not the node.

---
Tags: media
---


# Question
Title: how to make cron run once at specific time per day?
I want the cron run only once at say 01:00 hours after midnight, just to save shared hosting resources as cron empties the caches. My new site is using too much of resources and I'm trying my best to stick with shared hosting. I want to set cron run once in a day. It should run at midnight so that some cache is built before day time, when traffic is high.

I've only two somewhat related threads: make sure hook cron is only run once a day setting and How to run cron more often than every hour?

But for such simple thing it don't want to use Elysia module.

From this post: How do I get the (date)timestamp since last cron run? I understand if we manually set cron\_last variable then may be next cron time will be calculated with respect to this.

Another way I can do is to run drush cron from a script from crontab which will run it at a particular time. Similarly we can call cron from crontab ( as in here).

I'd want it to be done from within a module etc so that whenever I move my site, it'll work at any new setup without doing any configuration.

Any suggestions?

# Answer
> 4 votes
I think you've covered the options well in your question. However, your combinaton of requirements - i.e.:

1. no poking of `cron.php` from crontab;
2. settings kept in database to be migrated along with the site ("done from within a module");
3. the management module must not be Elysia.

is a problem. This combination excludes *all* the possible answers. There is no solution that will satisfy all three requirements.

If you want to use a module, that module is Elysia cron.

You seem to think Elysia cron is overkill for this. I happen to agree. Besides, Elysia does not work too well when triggered by the built-in default poorman's cron. You really want to use an external crontab poke *together with* Elysia to get the type of fine-grained control you seem to be after, with Elysia.

So while your first requirement rules out poking of `cron.php` from crontab, that is my suggested solution.

Actually, since the crontab entries for *all* your sites can be kept in a single file on a single server, I do not see how this set-up should be considered too difficult to maintain.

# Answer
> 3 votes
This is an old question, but I recently had to implement a similar feature in Drupal 8, so this might be helpful to others.

**Guarantee that a cron task runs exactly once per day, as close to a specified time of day as possible, without any control over when the cron itself runs.**

The basic idea is to keep the time of the last execution in a state variable, then check whether the scheduled time of day has passed by between then and now. For example, if the scheduled time is at 23:30, the last run was Jan 1 00:06, and now it is Jan 1 23:29, it shouldn't run - but if it is Jan 1 23:40, it should.

This ensures that the runs will be (on average) 24 hours apart, and the task happens on the first cron execution after the scheduled time. (The more frequently Drupal cron is run, the closer it will be.)

Rough structure of the service:

```
class MyModuleCron {

  public function cron() {
    $now = \Drupal::time()->getRequestTime();
    if ($this->shouldRun($now)) {
      $this->queueTasks();
      $this->state->set('mymodule.last_cron', $now);
    }
  }

  public function shouldRun($now) {
    // Get these from config or something:
    $scheduled = '07:30';
    $timezone = new \DateTimeZone('Region/City');

    $timestamp_last = $this->state->get('mymodule.last_cron') ?? 0;
    $last = \DateTime::createFromFormat('U', $timestamp_last)
      ->setTimezone($timezone);
    $next = clone $last;

    $next->setTime(...explode(':', $scheduled));
    // If the cron ran on the same calendar day it should have, add one day.
    if ($next->getTimestamp() <= $last->getTimestamp()) {
      $next->modify('+1 day');
    }

    return $next->getTimestamp() <= $now;
  }

  public function queueTasks() { }
}

```

And the hook\_cron:

```
function mymodule_cron() {
  \Drupal::service('mymodule.cron')->cron();
}

```

---
Tags: cron
---


title: Get block programmatically

text:
# Question
Title: Get block programmatically
It is possible get parent `entity` `block` by entity `block_content`? I don't know the `block`'s machine name but I have a uuid of `block_content`

# Answer
> 3 votes
Use BlockContent::getInstances

```
$blocks = $block_content->getInstances();

```

or the code of this method directly:

```
$blocks = \Drupal::entityTypeManager()->getStorage('block')->loadByProperties([
  'plugin' => 'block_content:' . $uuid,
]);

```

---
Tags: 8, blocks
---


title: Saving File Space with Drupal 8

text:
# Question
Title: Saving File Space with Drupal 8
I have a hosting account which has a maximum of 250 MB total space. I have installed Drupal 8 and I'm using the bootstrap theme and already my host has warned me that I am nearing my limit for file space. This is only going to be a small site, so it really shouldn't need that much space. Is there any way I can clear up space by deleting unused files in the Drupal 8 system?

For instance, is it possible for me to disable themes and then delete those folders? And also to uninstall core modules that I'm not using and delete those folders as well? Or are there any other ways I can clear up space?

If it is not possible then I will probably switch to using Drupal 7, which would be my 2nd option.

# Answer
> 0 votes
While you could uninstall and delete core modules, I wouldn't recommend it. They will be restored during updates and you'll have to constantly be vigilant to not go over your space limit.

Over time, the size of the site will probably grow slightly due to additional updates, and you may add files of your own (images, etc.) that also increase the site's size.

Drupal 8 requires significantly more space than Drupal 7 and is a very tight squeeze if you only have 250 MB. Hosting recommendations are off topic for this site, but there are many hosts that offer more file space (say, 1 GB) at a reasonable rate. If Drupal 8 otherwise fits your needs, I would pay more to increase the disk space, but if that's not an option, go with Drupal 7 since it's smaller, even with a fair number of contrib modules.

---
Tags: 8, files
---


# Question
Title: order at will paragraph items of different paragraph type
On the module description it says :

> They \[the end-users\] can then add as many Paragraph items as you allowed them to and reorder them at will.

I have created two paragraph types and created 2 corresponding paragraph fields.

I dont see how the end-users can re-order one to another in /node/nid/edit?

https://screenshots.firefox.com/ZUCvIvfQ5iHDqW0R/d7-mathieu.univ-amu.fr

Is there a way to allow end-users to create as many paragraphs as they want and reorder them at will , even between different paragraph-type.

For example being able to create one page with:

> -paragraph-item-type1
>
> -paragraph-item-type2
>
> -paragraph-item-type1
>
> -paragraph-item-type1
>
> -paragraph-item-type2

And another page with

> -paragraph-item-type2
>
> -paragraph-item-type2
>
> -paragraph-item-type2
>
> -paragraph-item-type1

# Answer
For your use case, you have to create only one paragraph field on the node, and allow both paragraph types for that specific field (default setting is allow all paragraph types anyways). Then editors can rearrange all paragraphs within that field at will.
> 1 votes

---
Tags: paragraphs
---


title: Translation for error message

text:
# Question
Title: Translation for error message
I created a feedback form using the Webform module and the Internationalization module for the English and the Japan version.

*Feedback is required.* is translated as *「ご意見・ご感想」は必須項目です。* where the translation for *Feedback* is *ご意見・ご感想*. I need to show *「本文メッセージ」は必須項目です。* as error message.

How can I do this?

# Answer
By default, Drupal (and Webform) show the error message as `Field_name is required`, so if you want to show an error message that uses something other than `field_name`, you will have to override/write your own validation function.

The Webform Validation module may be of assistance here, particularly the code examples for custom validation hooks.

P.S. "本文メッセージ" is probably a mistranslation; it most likely should be flipped ("メッセージ本文", "message body").
> 1 votes

---
Tags: i18n-l10n
---


# Question
Title: Disabling auto-translation from English to another language?
I've installed Drupal 8 and setted the site to be in Hebrew. It was changed to Hebrew, but from some reason, all the management system area\navigation\menues themselves were also translated to Hebrew. Such a thing never happened to me In Drupal 7.

In Drupal 7 when I was installing sites and setting the language to Hebrew, I would only have everything moving to the right (Hebrew is an RTL language) and the usage in the language became available, but I never, ever, had all the site translated automatically.

Is there a way to allow Hebrew **without** translating every part of the site to Hebrew?

# Answer
Here is what I did to solve it:

1. I've deleted the Hebrew language setting to re-create it later.
2. I've **un-installed** the module "Configuration translation" and than the module "Interface translation".
3. I Re added the Hebrew language as supported, and setted it as default.

Now the site was supporting Hebrew but no longer translated everything to it automatically.
> 2 votes

# Answer
You can configure the administration language seperate to the content language by setting:

```
/admin/config/regional/language/detection:
Account administration pages: enabled

```

If you want to force this, set this setting at the top of the list.

Then there is in the user configuration of admin's the option to set a different language for the site and the administration pages language.

For other roles, just set the permission "Use the administration pages and help" to allow this setting to appear on the user page.
> 4 votes

# Answer
If you choose a language at Drupal 8 install, then the interface will be translated by default. Useful for users who do not speak English. The translations are automatically imported from localize.drupal.org.

If you do not want the interface to be translated just uninstall the "Interface translation" module.

If you want Interface translation, but do not want to import translations from localize.drupal.org, then restrict the Translation source. Translation files with translated interface text are imported automatically when languages are added or when modules or themes are enabled. On the "Interface translation settings" page (/admin/config/regional/translate/settings), the "Translation source" can be restricted to local files only.
> 1 votes

# Answer
My solution was to remove the second language (in my case Turkish). Then I added a custom language with code for example "mytr". The only downside is your translated pages are now accessible from www.example/com/mytr/... instead of www.example.com/tr/...
> 0 votes

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


# Question
Title: How to create a node with submissions of a webform?
I'm using Drupal 7 and created a content type 'NewArticle' with the fields 'Title', 'Text' and 'Image'. Users have the permission to create a 'NewArticle', but I don't like the way of displaying the administration bar in order to let them create a 'NewArticle'.

Instead, I'd like to work with Webforms. My goal is to create a Webform with exactly the same fields as the content type 'NewArticle'. So what I want is: when users filled in the form and submit it, a new node 'NewArticle' is created with the submitted information.

How can I do this? Are there modules that make this possible? I can't find any...

# Answer
> 7 votes
Instead of using the Webforms module to create new nodes, it's better to let the users create them directly at `MY-SITE/node/add/CONTENT-TYPE`. Trying to hack data out of a Webform only makes things unnecessarily more complicated. Hide the toolbar for other users and give them permission to add new content. Lastly, adapt the node form to your needs with a template file and style it with CSS.

# Answer
> 3 votes
Webform Default Fields With this module you can easily create much of nodes with same webform fields. It can be applicable in case of job vacancies with reply form, kind of quality feedback control or whatever your mind suggests you.

Because you can create more than one webform-enabled content types, you respectively can attach different default fields for each of them.

***(or)***

Webform report module create a new node on each webform submit. You can retrieve the data using views, customize it to your requirement.

> This module allows users to create simple, dynamic reports based on data collected by the webform module. It adds a new node type that contains the report criteria, and the data displayed is updated automatically as webforms are submitted. The data can be sorted according to the viewer's preference without altering the report criteria.

# Answer
> 0 votes
You may also migrate nodes to webform submissions using the Migrate Node-to-Webform module. Here is a quote about it (from the module's project page):

> Migrates nodes (Drupal 6) to webform submissions (Drupal 7). e.g. Retrieves all nodes of type 'article' and fills up a webform by creating one submission for each node.

# Answer
> 0 votes
Sorry i couldn't comment as I just joined.

But in addition to Jeroen's answer, this works quite well, until you want to track submissions and get detailed reporting, which is something that webforms does quite well!

but if you are wanting to use this method, may I also suggest Advanced Form Block which allows you to also put the node add form into a block and just insert that on one page and this negates the need to link directly to a node add form and it also allows you to keep all your site styling :)

If anyone can please figure this out please step up!

# Answer
> 0 votes
> Are there modules that make this possible?

Yes there is: you can use the Rules module for this. As an example, consider this rule (in Rules export format), which does what you're asking for:

```
{ "rules_create_a_node_from_webform_data" : {
    "LABEL" : "Create a node from webform data",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "webform_rules", "rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "IF" : [
      { "webform_has_id" : {
          "form_id" : [ "form_id" ],
          "selected_webform" : { "value" : { "webform-client-form-191" : "webform-client-form-191" } }
        }
      }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "The webform submitted contains these fields:\r\n\u003C\/ul\u003E\r\n\u003Cli\u003Ethe field labeled \u0022[data:demoform_title-title]\u0022 which has value \u0022[data:demoform_title-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_text-title]\u0022 which has value \u0022[data:demoform_text-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_number-title]\u0022 which has value \u0022[data:demoform_number-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_option-title]\u0022 which has value \u0022[data:demoform_option-value-raw]\u0022.\u003C\/li\u003E\r\n\u003C\/ul\u003E" } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_text-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_text" : "Form variable text" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_number-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_number_text" : "Form variable number text" } }
        }
      },
      { "data_convert" : {
          "USING" : { "type" : "integer", "value" : [ "var-demoform-number-text" ] },
          "PROVIDE" : { "conversion_result" : { "var_demoformvar_number" : "Form variable number" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_option-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_option" : " Form variable option" } }
        }
      },
      { "entity_create" : {
          "USING" : {
            "type" : "node",
            "param_type" : "article",
            "param_title" : "[data:demoform_title-value-raw]",
            "param_author" : [ "user" ]
          },
          "PROVIDE" : { "entity_created" : { "article_created" : "Created article" } }
        }
      },
      { "data_set" : {
          "data" : [ "article-created:body:value" ],
          "value" : [ "var-demoform-text" ]
        }
      },
      { "data_set" : {
          "data" : [ "article-created:field-free-format-nr" ],
          "value" : [ "var-demoformvar-number" ]
        }
      },
      { "data_set" : {
          "data" : [ "article-created:field-optionlist" ],
          "value" : [ "var-demoform-option" ]
        }
      },
      { "data_set" : { "data" : [ "article-created:comment" ], "value" : "0" } },
      { "entity_save" : { "data" : [ "article-created" ], "immediate" : "1" } },
      { "drupal_message" : { "message" : "A new article got created, with nid=[article-created:nid] and url=[article-created:url]" } }
    ]
  }
}

```

Anybody a bit familiar with Rules and Webform, while know that it's often a struggle to get access to the data contained in a submitted Webform. Mostly because they are not available to select them when building Rules Actions.

However by introducing those `var-demoformvar-...` variables (as in the above rule), you can make the typical Rules magic happen. Refer to my answer to "How to create a node from a Webform using rules?" for more details about all this.

---
Tags: nodes, webforms
---


# Question
Title: mysql query to get the numeric part of a field
I have a column in a table that has numbers and letters (not in any particular order) and i need to use an SQL query within a drupal module to get only the numeric part . How can I do this? the problem is there is no telling where the number starts or ends and where the letters start or end. Is there a regex command ? How can I do this in the query format that drupal requires?

# Answer
MySQL has a REGEXP command (most if not all DBMSs have an equivalent), but Drupal doesn't have any special methods to use it per se.

The only difference is instead of using fields/field, you'll use addExpression to add it to the selected fields for the query, e.g.

```
$alias = $query->addExpression("col REGEXP '[0-9]+'");

```
> 2 votes

---
Tags: database
---


title: Import nodes with images

text:
# Question
Title: Import nodes with images
Im trying to create nodes from CSV also with image in one image field. I'm using Migrate modul in Drupal 8 and Migrate from CSV. Data to node works fine, image download and copy works fine but in node i dont have that image, the image has also record in database but isn't connected with the node. There is my code, does anyone knows where can be the problem? Thanks a lot for advices. The image field is called - **field\_uvodni\_obrazek** and im using last Drupal 8.4.2

**product\_data.YML - node import**

```
 dependencies:
      module:
        - migrate_source_csv
    id: product_data
    migration_group: product_migration
    migration_tags:
      - product
      - node
    label: Profile
    source:
      plugin: csv
      # Full path to the file.
      path: 'C:\Users\Hans\Documents\import.csv'
      # Column delimiter. Comma (,) by default.
      delimiter: '|'
      # Field enclosure. Double quotation marks (") by default.
      enclosure: '"'
      # The number of rows at the beginning which are not data.
      header_row_count: 1
      keys:
        - id
      column_names:
        0:
          id: 'id'
        1:
          kod: 'Kod zbozi'
        2:
          title: 'Nazev produktu'
        3:
          refstruct: 'Referenční struktura'
        4:
          kategorie: 'Kategorie produktu'
        5:
          objednani: 'Objednaci název'
        6:
          obrazek: 'Obrazek'
        7:
          popis: 'Krátky popis'
        8:
          rozsireny_popis: 'Rozsireny popis produktu'
    process:
      title: title
      field_produktove_cislo: kod
      field_objednaci_nazev: objednani
      field_refstruct: refstruct
      body/value: rozsireny_popis
      body/summary: popis
      field_kategorie_produktu:
        -
          plugin: explode
          delimiter: '/'
          source: kategorie
      field_uvodni_obrazek/target_id:
            plugin: migration_lookup
            migration: product_image
            source: obrazek
            no_stub: true
      field_uvodni_obrazek/alt:
         plugin: default_value
         default_value: title
      field_uvodni_obrazek/title:
        plugin: default_value
        default_value: title
      uid:
          plugin: default_value
          default_value: 1
      langcode:
               plugin: default_value
               default_value: 'cs'
      type:
        plugin: default_value
        default_value: produkt

    destination:
      plugin: 'entity:node'
      default_bundle: produkt
    migration_dependencies:
      optional:
        - product_image

```

**product\_image.YML - image import**

```
id: product_image
label: Import all product images.
migration_group: product_migration
migration_tags:
  - product
  - file
  - image
source:
  plugin: csv
  path: 'C:\Users\Hans\Documents\import.csv'
  delimiter: '|'
  enclosure: '"'
  header_row_count: 1
  keys:
    - id
  column_names:
    0:
      id: 'id'
    6:
      filename: 'obrazek'
  constants:
    file_source_uri: public://import
    file_dest_uri: 'public://produkty/uvodni'
process:
  file_source:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/file_source_uri
        - filename
    -
      plugin: urlencode
  file_dest:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/file_dest_uri
        - filename
    -
      plugin: urlencode
  uid:
        plugin: default_value
        default_value: 1
  uri:
    plugin: file_copy
    source:
      - '@file_source'
      - '@file_dest'
  filename: filename
destination:
  plugin: 'entity:file'

```

# Answer
> 1 votes
You need to create a connection between image and node, a reference. You should set the fid. Have a look at this example. Also, in my case it was really helpful this post

---
Tags: 8, nodes, media, migrations, importing-exporting
---


title: How to get language prefix in Drupal 8

text:
# Question
Title: How to get language prefix in Drupal 8
I am building internal in my custom module that I am porting to Drupal 8: https://www.drupal.org/project/taxonomy\_facets

I need to get a current language prefix so I can prepend it to the link. I Drupal 7 it was as simple as:

```
global $language;
$prefix = $language->prefix;
$mylink = $prefix . '/example/something';

```

How can do this in Drupal 8?

EDIT: My issue specifically is that I have a language prefix set to `NONE` for the default language at `Home >> Administration >> Configuration >> Regional and language >> Languages >> Detection and selection`. (admin/config/regional/language/detection/url)

For the default language, I want the code to return the real prefix, i. e. `NONE`, not `en` (the code for the default language, English).

# Answer
> 8 votes
In Drupal 8, you use the languageManager class to get the language code:

```
$languagecode = \Drupal::languageManager()->getCurrentLanguage()->getId();

```

EDIT: If you want to return `NONE` if the current language is the default language, you probably need to make a helper function:

```
$languagecode = \Drupal::languageManager()->getCurrentLanguage()->getId();
$default_languagecode = \Drupal::languageManager()->getDefaultLanguage()->getId();
if ($languagecode == $default_languagecode) {
  return "NONE";
}
else {
  return $languagecode;
}

```

helper function to ge it from settings

```
function getLanguagePrefix() {
    if($prefixes = \Drupal::config('language.negotiation')->get('url.prefixes')) {
      $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
      return "/". $prefixes[$language];
    }
    return null;
  }

```

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


title: Register user with empty password

text:
# Question
Title: Register user with empty password
I create a cordova app, and trying to register new user from my app using drupa 7, drupal 7 service 3 and angularjs 1.

I send post request with below data and user created successfully.

```
    $http({
        headers: {
            'X-CSRF-TOKEN': $rootScope.globals.auth.token
        },
        method: "POST",
        url: registerUrl,
        data: {
            name: data.name,
            pass: data.password,
            mail: data.email,
            "field_ac_mobile_number": {"und": [{"value": data.mobile}]}
        }
    }).success(function(userData) {
    }).error(function(data, status, headers, config) {
    });

```

But my problem is- **after create user, password is empty.**

How to solve it?

**UPDATED QUESTION:**

I altered registration form by three step registration form for verify customize 6 digit character instead url for email verification.

All works fine. But when I send final request with all params, user created without password.

But if I register from site, all values set well.

I don't understand, whats my problem...

**UPDATED QUESTION 2nd:**

# Answer
> 0 votes
It is very simple.

The steps are the following:

1. Please go to: admin/config/people/accounts
2. In the secction "REGISTRATION AND CANCELLATION " select "Visitors".
3. Uncheck "Require e-mail verification when a visitor creates an account".
4. Click in the buton "save configuration".

Try again register one user.

I did a test and everything went well.

# Answer
> 0 votes
I have done a test and everything works fine.

steps:

1. Please go to: admin/config/people/accounts
2. In the secction "REGISTRATION AND CANCELLATION " select "Visitors".
3. Uncheck "Require e-mail verification when a visitor creates an account".
4. Click in the buton "save configuration".

try the following code:

```
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>
    Untitled Document
</title>

<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
$(document).ready(function(){
 $("#botonesss").click(function(e){
  e.preventDefault();

 $.ajax({

   data: JSON.stringify({
  "name": "newuser",
    "mail": "test30@test30.com",
    "pass": "newuser",
    "status": 1,
  }),
   url:   'http://localhost/rest/user/register',
   type:  'post',
   beforeSend: function(xhrObj){
        xhrObj.setRequestHeader("Content-Type","application/json");
        xhrObj.setRequestHeader("Accept","application/json");
    },
     success:  function (response) {
      $("#cargaexterna").html(response);
      console.log(response);
     }
  });  //end $.ajax
 }); // end $("#botonesss")
}); // fin $(document).ready(function()
</script>
</head>
<body>

 <input id="botonesss"  type="button" value="login">
<div id="cargaexterna"> </div>
</body>
</html>

```

Modify the URL by your URL and try again.

If it works well, let me know

---
Tags: services
---


title: How do I get view mode

text:
# Question
Title: How do I get view mode
Is there an easy way to get `node's` `view mode` from `entity.view`?

```
function classier_preprocess_views_view(&$vars) {
    $vars['rows'][0]['#rows'][0]['#view_mode'];
}

```

# Answer
If you're trying to get the view mode of a node you probably want to use a different hook.

```
function classier_preprocess_node(&$vars) {
    $view_mode = $vars['view_mode'];
}

```

Should do the trick.
> 1 votes

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


# Question
Title: Drupal Commerce variations missing when creating content
I have downloaded and installed the Commerce module.

**Note 1:** I have a product which is made up of 2 changeable parameters e.g. say size and colour... depending upon the size and colour chosen the user will be presented with a price... Currently, this leads to a potential 18 combinations all with unique prices.

**Note 2:** I have created a product content type e.g. T shirt

**Note 3:** I have created 18 products with unique SKU codes for each of the possible combinations and associated prices (of the product type created in Note 2)

**Note 4:** I have created a standard content type (under structure - which is intended to be used to show the product as a piece of content e.g. admin\>structure\>content type). The field holding the product is of type "Product Reference" and the product reference fields, field setting is set to unlimited

**Note 5:** The content type is configured to allow the user to select the 18 different variants (created in Note 3) of the product type created in note 2.

**Note 6:** The content node of the type created in Note 4 works by showing the product and changes the price depending upon what the user selects from the two options e.g. size and colour

**The issue:** In the content type created in Note 4 (e.g. the content node) it only shows the last 10 products created (of the product type created in Note 2) rather than showing the required 18 products... how do you get to see the other 8 product variations so that they can be selected and show up in the content node in order that those combinations may be selected?

Anyone else experience this issue? And found a solution to it?

It looks like the widget in the content creation gui only lists up to 10 items - so I'm only seeing the last 10 items created but how to I also see the addition 8 items created.

# Answer
Upgrade to Commerce 1.14. This is a well-known issue with an artificial options list introduced in prior versions. While you're at it, make sure you're running the latest version of Drupal core and taken care of any security releases, too.
> 0 votes

---
Tags: 7, nodes, commerce
---


# Question
Title: Restructure Language Prefix example.com/ca-fr
I created new Language method in Drupal 8, I need url example: example.com/en-fr, The first part of URL is a country code and the second is a language code. Language switcher should give possibility to change country and language

# Answer
Drupal doesn't support "country" selection in the language switcher, but you can easily add this yourself.

When you add languages (`/admin/config/regional/language/add`), choose "Custom" and then set the language code to whatever you want and then add the country to the name.

By default, custom languages will all be based off the site's default language (usually English).

If you want to base them off a different language, you will have to import translations for that language after adding the language.
> 1 votes

---
Tags: 8, i18n-l10n, path-aliases
---


# Question
Title: How to group fields and place in seperate tabs/local tasks?
I want to group fields and create different tabs/local tasks for them with their own dedicated pages. How can I do that?

I found one module that looked promising, but also that one has bug on installation: https://www.drupal.org/project/entity\_ui

What other options do I have?

I tried ask the question before but it was mistakenly marked as duplicated so open a new question to allow for answers: How to group fields and place in seperate tabs?

# Answer
> 0 votes
You can create local tasks for this in yml. Local tasks are what appear as tabs when viewing an Entity. You can code the tabs yourself. There's not much to it: https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-local-tasks

Answer from Kevin here: How to group fields and place in seperate tabs?

---
Tags: 8, entities
---


# Question
Title: How to calculate a date difference in twig?
I am using date range field in views and would like to display dates in the format `5-May +3 days` using twig. Te values that can be used as per drupal are:
`{{ field_mycontent_dates__value }} == Raw value
{{ field_mycontent_dates__end_value }} == Raw end_value`

How can I make the calculation and display it using rewrite output option in views?

# Answer
I ended up creating a pre-processor as @Kevin suggested:

**cargaview.info.yml**

```
       name: cargaview
    type: module
    description: modifies carga node fields
    core: 8.x
    package: Flete
    dependencies:
      - field
enter code here

```

---

**src/Plugin/Field/FieldFormatter/CargaViewFormatter.php**

```
<?php

namespace Drupal\cargaview\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Datetime\DrupalDateTime;

/**
 * Plugin implementation of the 'carga_view' formatter.
 *
 * @FieldFormatter(
 *   id = "carga_view",
 *   label = @Translation("Carga View"),
 *   field_types = {
 *     "daterange"
 *   }
 * )
 */
class CargaViewFormatter extends FormatterBase {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      'separator' => '+',
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];
    $separator = $this->getSetting('separator');

    foreach ($items as $delta => $item) {
      if (!empty($item->start_date) && !empty($item->end_date)) {
        /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
        $start_date = $item->start_date;
        /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
        $end_date = $item->end_date;

        if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {

          $date_diff = $end_date->getTimestamp() - $start_date->getTimestamp();
          $day_diff = floor($date_diff / (60 * 60 * 24));

          $elements[$delta] = [
            '#type' => 'markup',
            '#markup' => date('d-M-Y', $start_date->getTimestamp()) . ' ' . $separator . ' ' . $day_diff . 'd',
          ];
        }
        else {
          $elements[$delta] = [
            '#type' => 'markup',
            '#markup' => date('d-M-Y', $start_date->getTimestamp()),
          ];

          if (!empty($item->_attributes)) {
            $elements[$delta]['#attributes'] += $item->_attributes;
            // Unset field item attributes since they have been included in the
            // formatter output and should not be rendered in the field template.
            unset($item->_attributes);
          }
        }
      }
    }

    return $elements;
  }
}

```
> 0 votes

# Answer
I think this is what you are looking for? There is good info here to pass the cred... https://stackoverflow.com/questions/15657687/twig-date-difference

Top answer:

```
{# endDate and startDate are strings or DateTime objects #}
{% set difference = date(endDate).diff(date(startDate)) %}
{% set leftDays = difference.days %}
{% if leftDays == 1 %}
  1 day
{% else %}
  {{ leftDays }} days
{% endif %}

```

Another tidbit from same question:

```
{{ entity.ending_date|time_diff(entity.starting_date) }}

```

If not let us know. Plus depending on how you have configured Drupal to render out the value of the {{ field\_mycontent\_dates\__value }} field, it may be as simple as something like:

```
{% set time = value_1 - value_2 %} then {{ time | date('F j i') }}

```

Ultimately, what you're looking for I believe are "twig filters".
> 0 votes

---
Tags: views, theming
---


# Question
Title: How to change default file system path in D8?
In D8, where to change the Public File System Path to be :

sites/default/files/\[nodeID\]/

Do I need write a module?

# Answer
> 2 votes
You can't change the public file system path globally to include a `nodeID` because there are things that can store files that do not have a `nodeID` (such as non-node entities).

Instead, you can change where files are stored per file storage field (examples: File fields and Image fields).

To do so, go to `Structure -> Content Types -> My Content Type -> Manage Fields` and then choose **Edit** for the relevant field.

Then, in **File directory**, you can use tokens to set up the path however you like. For example:

`myfiles/[date:custom:Y]-[date:custom:m]-[date:custom:d]`

There is a link below **Help text** that you can click to see a list of available tokens.

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


# Question
Title: How to display a taxonomy term's immediate children on its page?
In Drupal 8, how can I display a taxonomy term's immediate children on its page?

For example, I have a hierarchical taxonomy vocabulary like this (simplified):

Animals
--Fishes
----Blennies
------Yellow Blenny
------Green Blenny
----Gobies
------Blue Goby
------Red Goby

On the page for the taxonomy term "Fishes" (e.g. drupal/fishes) I would like Blennies and Gobies (but not their children) to appear.

I have tried configuring Contextual Filters in Structure\>Views\>Advanced but not been able to do this.

# Answer
Given your additional information, this short step-by-step guide, that should give you the desired results:

* Duplicate/disable the original Taxonomy view / alter it as follows.
* In "Advanced/Contextual filters" remove "Content: Has taxonomy term ID"
* Add a new Contextual filter "Content: Has taxonomy term ID (with depth)":
    + Depth: 1 (will show content for the next level child terms as well)
    + When the filter value is NOT in the URL:
        - Provide default value
        - Type: Taxonomy term ID from URL
        - Load default filter from term page: checked
    + When the filter value IS in the URL or a default is provided:
        - Override title: checked, use the variable `{{ arguments.term_node_tid_depth }}` (this will make sure the term name will be shown in the page title)
        - (Optionally, but strongly suggested) Specify validation criteria: checked
        - Validator: Taxonomy term ID
        - Vocabulary: (your vocabulary name checked)
        - (Optionally) Validate user has access to the taxonomy term: checked

As you'd like to show an image, you may also wish to change the Format of the view from Content to Fields and add the image field of your tagged content.

Please note, that the depth modifier may lead to duplicates. So within the Advanced / Other section's Query settings, you should enable the "Distinct" option.

You can further improve your view results by adding relations to the actual terms, the term name and adding grouping. But this seems out of scope for your initial question.

I did the above steps on a clean D8 test instance with auto-generated content and vocabularies, and it was working fine.

EDIT:

According to your comments, you actually like to show fields of the child taxonomy terms only. So here is how to do that:

* disable the default taxonomy view
* create a new view
* in View settings / Show choose "Taxonomy term"
* "of Type" is your vocabulary
* in "Page settings" check "Create a page" and provide the URL "taxonomy/term/%"
* click "Save and edit"
* in Advanced / Contextual filter add the filter "Taxonomy term: Parent"
* apply the same settings as in my above solution to the contextual filter, except for the title variable, which should now be '{{ arguments.tid }}'

As result, you should see the first level children of the taxonomy term in the view.

If you like to see some of their properties only, switch the type of the view to fields and add the field you like to display.
> 2 votes

# Answer
**In the view :**

if your are modifying/duplicating the default taxonomy\_term view, you should remove the default contextual filter (*has taxonomy term id*) and add a new one *"Has taxonomy term ID (with depth)"*, with a depth of 1.

**Programmaticaly :**

```
$terms = \Drupal::service("entity_type.manager")->getStorage("taxonomy_term")->loadTree("<VID>","<TID of Fishes>", 1 /* the depth : 1 */, true /* to load entities */);
foreach($terms as $term){
  //rendering whatever...
  print $term->label();
}

```
> 1 votes

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


# Question
Title: Entity browser not showing image after selecting an entity (Drupal 8)
I'm using drupal 8 entity browser to select entities/images. I cannot figure out how I can show a thumbnail or rendered image after selecting an entity. Below is an image that only shows the label of the entity after selecting

I have already checked the `View` and `Entity Browser` but couldn't not find an option to display the image after selecting

# Answer
Go to Manage Display of your media bundle. You may have disabled the image from Manage Display, you can enable it and update the format to Image / Responsive Image or whatever best suits you. Please check the attached screenshot
> 3 votes

# Answer
First you need to set up a view mode for the media entity, which is showing the image field.

Then, on the node, set the view mode of the media entity field to "rendered entity" and select the view mode previously created for the media entity.
> 1 votes

---
Tags: 8, entities
---


title: Annotations syntax

text:
# Question
Title: Annotations syntax
Hello I was just wondering about the hints syntax. PhpStorm automatically resolves parameters with:

```
@param ConfigFactoryInterface $config

```

But every ressources I find are using the full path:

```
@param \Drupal\Core\Config\ConfigFactoryInterface $config

```

How come?

Thanks you, Mathias

# Answer
> 1 votes
Preface: annotations are something different, what you're talking about are called DocBlocks.

> PhpStorm automatically resolves parameters

Not in my experience; if you're using the namespace at the top of that file

```
use Drupal\Core\Config\ConfigFactoryInterface;

```

then yes, just like in the rest of your PHP code in the same file, you don't need to use the fully qualified namespace when referring to that class.

*Without* that `use` statement at the top of the file, PhpStorm won't be able to resolve the class (without the differentiator of namespace, how would it distinguish between two identically named classes?). At that point you'll probably see a squiggly line under the class in the docblock, informing you that it couldn't be found.

# Answer
> 0 votes
According to drupal coding standard, you should write class full path in your phpdoc.

In phpstorm : *File \>\> settings \>\> Editor \>\> Code style \>\> PHP \>\> PHPDoc* tab, check "**use fully-qualified class names**" :

---
Tags: 8
---


title: How to delete taxonomy term?

text:
# Question
Title: How to delete taxonomy term?
I would like to delete taxonomy term. Unfortunately on taxonomy -\> list I can only see "edit" button next to each term (under "operations"):

How can I delete the term I added earlier?

# Answer
When you click "edit":  Drupal will take you to the page where you can delete that term; right beside the "save" button:  For bulk deletion you may take a look at the taxonomy manager module.
> 6 votes

# Answer
You can use the following module to delete taxonomy terms.

https://www.drupal.org/project/taxonomy\_multidelete\_terms
> 1 votes

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