# Question
Title: Migration after server crash: maintenance mode and/or cache problem
I had a crash of my previous server and I tried to rise my website from the dead. I had backups of all the files & of the database (PostgreSQL). I was not the one who set up the website and my knowledge of Drupal is pretty low. From what I understood/gathered, it is a 7.54 version and it runs with multisite.

What I did so far:

* Import my database backup in PostgreSQL (in the dumbest way possible: recreate the right database & user, import everything back in place);
* Upload all the files to my new server (running Debian Jessie);
* Give access to the `sites/` directories to `www-data` user;
* Clear the `sites/mysite/css/` and `sites/mysite/js/` directories;
* Disable CSS & JS aggregation (using `drush`).

I did the latest because the style of the website was broken; that was enough to revive it.

I still have on major issue: when I log in, I get the maintenance message. I therefore tried to disable `maintenance_mode` with `drush`; it didn't work.

I saw it could be related to cache issues; I therefore tried to clear the cache (once again with `drush` with `drush cc all`). It put the whole site in maintenance, and not only when I'm logged in.

I am not sure where the problem comes from. Any hint or suggestion would be greatly appreciated!

# Answer
Here is finally how I solved the problem with Yogesh help: when I tried to access the admin section while logged in as an administrator, I got an error. I therefore checked the watchdog table. The `image_dimensions` table was somehow missing:

```
[...] Undefined table: 7 ERROR: relation "image_dimensions" does not exist [...]

```

I created the missing table, and everyhting was then working (access to the admin section, access to the user section and so on).
> 1 votes

---
Tags: migrations, backups, maintenance-mode
---


# Question
Title: Where is the parent/child relationship between nodes stored in the database?
I am migrating a site from one CMS to Drupal and I'm working on migrating link structures over correctly. This is something I am going to have to automate because there are over 3,500 nodes of content that I am migrating over.

I can't seem to find in Drupal 8's database schema where the relationship between parent and children nodes are stored. I have been looking for something like a 'pid' or a 'cid' column (parent id and child id, respectively), but I can't seem to find a column like that in the schema.

I know you can make nodes children of other nodes, so I know it has to store this information somewhere. If someone could tell me what table and column this information gets stored in I would greatly appreciate that.

Drupal 8 Database Schema

# Answer
> 3 votes
The simple answer is, there is none.

Nodes in Drupal does not have a hierarchy, it's other things on top of it that allow you to do that, depending on the use case:

Menu links: You can have menu trees and each points to a node, but the nodes themself don't really about that. Some parts might look like it does, e.g. breadcrumb but that is simply based on the path.

Book module: This allows to create a book (basically a hierarchic structure of nodes), but this only makes sense for specific cases, e.g. structured documentation that has chapters and so on.

References: In many cases, nodes are just *connected* between each other with reference fields, which you could make look like a hierarchy.

Taxonomy: You can have Terms with a hierarchy and reference those from nodes, but again by default that doesn't give you anything hierarchy-like unless you start to combine with with path aliases or so.

=\> Content in Drupal is very different from how most other sites handle it and you can't just convert it 1:1.

# Answer
> 2 votes
What you are looking for is the `EntityReferenceField`. To understand more its behavior:

1. Create a content type ('MyTest')
2. Add a `ContentReferenceField` (`EntityReferenceField` on nodes). It machine name could be for example `field_my_reference`.
3. Choose whatever bundle you want a reference to.
4. Create a 'MyTest' element, and add a reference.

Now go to PHPMyAdmin or similar, and start type in the autocomplete field the following:

**node\__field\_my\_reference**

Then you can see the table scheme, and how referencing in the Drupal works in general. There are two main columns:

1. "entity\_id" - that is the host entity which has the reference field
2. And the last column of the table "...\_target\_id", that's the ID to which entity it is referring too

**That being said, I don't recommend you to do this by "hand".** I mean writing SQL queries with exact table names. Instead, **use Drupal `EntityTypeManager` when setting up relationships** between two entities (one must have of course an `EntityReferenceField`).

More on that, how to do that programmatically read this.

---
Tags: 8, nodes, database
---


# Question
Title: Drupal: node_load() in php file - load via ajax
i try to load a node in Drupal 7 in a php file, which will be loaded with ajax.

my php file looks like this:

```
require_once '../../../includes/bootstrap.inc';
$i = 16;
$content = node_load($i);

```

The include of bootstrap.inc works fine, but this file returns 'PHP Fatal error: Call to undefined function node\_load()'. i guess i've read that the function node\_load needs the bootstrap.inc file, but it doesnt seems so.

Is there any possible way to use the node\_load function right without 'register' a module in drupal - i just want to load a self made php file, which just returns the content of a node - without the template!

# Answer
> 2 votes
Rather than using a custom php file you should attempt to solve the issue "the drupal way" via a custom module or in your template.php... Please see my answer in this question.

It explains how you can add to the original url to change the template (or create a blank template so it is only node data presetned).

# Answer
> 0 votes
> 7 node.module node\_load($nid = NULL, $vid = NULL, $reset = FALSE)

node load API is in node.module file. You probably need to include this file to get it working, but I suggest not to take this approach. If you dont want to write a separate module then add your functions to theme files. Its better to create a module or edit any existing modules and make a note that you have edited just in case you upgraded it then it will be over written.

# Answer
> 0 votes
Please paste this code in the start of PHP file

```
<?php

    define('DRUPAL_ROOT', getcwd());

    require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
    ?>

```

Hope it will work!!

---
Tags: nodes, ajax, database
---


# Question
Title: How to keep some fields or a content type private
I have a content type for concerts, and a view for upcoming concerts.

For some of the upcoming concerts, the performer (site owner) wants to list just the date and the venue, but cannot list the title of the performance, because the company has not yet announced the season.

Is there a way to keep part of a node of that content type private, preferable until a specific date has been reached?

I am looking for a secure and foolproof solution, because I don't want to be subject to a lawsuit, in case the information leaks prematurely.

The alternative could always be to create two nodes - one of them published with only the public information, with an expiration date, the second one with the full information, initially unpublished, with an automatic publish date. However, I would like to provide a more comfortable way to input the information - add it only one time and don't worry about it.

So, for the alternative solution - what is the best way to create a node from a node with extracting part of the info of the parent node to the child node? For this scenario, I imagine changing the content type permissions to allow only authenticated users, and creating or updating child nodes in a "public" content type with the allowed subset using something like rules.

Any hints would be greatly appreciated.

# Answer
> 1 votes
You can do this using Views. Set up a contextual filter for the node id. And then a filter that sets a condition on your date field. This means the View will only have results when (a) your node is displayed and (b) the date condition is matched. Set the filter up as a block. And set that block to show only for that node type.

This is an approach I've used a lot. For example, you can use the same approach to show some fields to logged on users but not to non-logged on users. In effect, you're using the View to show fields depending on some condiiton.

# Answer
> 0 votes
have you treid Field Permissions Module.

this module will help to give view/edit access for each field while creating cck fields.

Best,

Anas

---
Tags: 7, entities, rules, nodes
---


# Question
Title: Create user profile using content type or add additional fields to the default registration form
I am good enough to build an entire drupal 7 website but my problem goes below:

I am in the process of building a very simple drupal website for all volunteers in my country. So every volunteer will have a profile page on the website where volunteers can search for each other, send emails to each others and even send sms to each other in addition to other basic features.

And so to create such website there is two way that i am little bit confuse which one to use: (any suggestion please)

**Method 1:** Add any additional field such as city ,district, bio, age, birtbday, phone number, profile picture, blood type, education degree, languages spoken.... directly inside the registration form by going to account settings in configuration page. And so i will use the "User" entity to pull out the information required for the creation of blocks, views....

**Method 2:** Let the volunteer register to the website by using the default registration form where only email address and password are required. And after completion of registration the user will be redirected to create a node of content type "Volunteer" where all the required fields mentioned above will be available. Also i will use the node limit module to limit the creation of 1 node per content type per user. And so i will use the "Volunteer" content type to pull out the information requited for the creation of blocks, views....

Which one is the best to go with ? Are there any limitation for any of the above method in case i need to expand the website in the futur ?

***Please note that i know how to do everything mentioned above, only i need suggestion about what method is the best and why ?***

Thank you,

# Answer
> 0 votes
I think there are two more possibilities. One, use social media integration to get as much information as possible to pre-fill the profile. Two, use panels to create a form that will collect a minimal number of required fields from your user profile. Overall, reduce the number of required fields and let users fill out their profiles gradually, with a little nudge from your site. If you ask them to fill out a large number of fields just to get started you may end up with a high form abandonment rate.

I would avoid creating a new Volunteer content type. It may just be my opinion, but I like to follow Occam's razor and avoid the proliferation of entities.

# Answer
> 0 votes
Please try to use **Profile 2** Module or Add fields to default registration form. When i am facing same issue i tried to create a new content type called "profile" so when user logged in at first time i redirect them to the Profile add form with node limit module and Rules module.

will explain you brief if Profile 2 module will not suit for you.

cheers!

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


title: How to make my gallery as expected?

text:
# Question
Title: How to make my gallery as expected?
I created a content type named 'Book page with Gallery'.
It has a standard 'Body' field and a 'Gallery' field which type is Image (Allowed number of values: unlimited).
And by default, I get this:
I tried to add some CSS to have the pictures "floating left" (field\__item being the class of the div containing the picture):

```
.field__item {
  float: left;
  margin: 0 10px 5px 0;
}

```

And it works!
But it works too well
As you can see, the Book navigation items float too :-(
How can I do this?
Thanks in advance

# Answer
> 0 votes
Finally, I made it work.
With the help of someone who put me in the good direction (his comment has been removed, Why?)

```
.field__item:last-child { float: none; !important; }

```

---
Tags: theming, 8
---


# Question
Title: How to achieve if else statement while querying with database?
I want to export some data from `test_records` table depend upon supplied `from date and to date`. I from and to date not supplied I want to export whole data. So how I can achieve that. Below is my code.

```
$from_date = strtotime($form_state['values']['fromdate']." 00:00:00");
$to_date   = strtotime($form_state['values']['todate']." 23:59:59");

$result = db_select('test_records', 'n')
      ->fields('n')
      ->condition('submitted_time',  array($from_date, $to_date), 'BETWEEN')
      ->execute()
      ->fetchAll();

```

I am using one condition that will compare `submitted_time` in database with supplied `from` and `to` dates. But When I pass nothing, it should get all the data from that table. Any suggestion will be appreciated.

# Answer
> 0 votes
I'm not sure if you can add if statement to a query but as you already have the values of `$form_state['values']['fromdate']` and `$form_state['values']['todate']` you can just add an if statement. If those two don't have values then execute a different query without the `condition('submitted_time', array($from_date, $to_date), 'BETWEEN')` condition.

---
Tags: 7, database
---


# Question
Title: How do I fill the authors name in a term reference field?
Content type `stock` contains the term reference field `field_producer`. What is the rule for Rules in order to fill this field with the node author name on creation?

## In detail

**The form looks like:**

-- Content type **Stock** (`stock`)

---- field **Producer** (`field_producer`); of field type *Term reference*; of widget *Autocomplete term widget (tagging)*; number of values: *1*; Vocabulary: *Producer*

**The goal is:**

When a user creates a node of the type *Stock*, his user name should automatically be filled/(pre-)populated in the field *Producer*.

**Why Rules:**

Since tokens aren't working for the autocomplete term reference field and a text field isn't available, rules might be a workaround. I've tried Prepopulate, Entityreference prepopulate, and other modules, but none of them supported the aim.

**Where I am struggling with Rules:**

* Event: *After saving new content*, Restrict by type *Stock*
* Condition: *Entity has field*, Data selector *node:field-producer*, Field Value *field\_producer*
* Action: *Set a data value*, Data (to be modified) *node:field-producer*, **Value (to set for the specified data): HERE REMAINS THE PROBLEM. I can't choose node:author or other tokens that display the user name. I get the restriction: "Data types: Select data of the type Taxonomy term."**

That's why I am not able to successfully create this rule.

What am I doing wrong? How should this rule look like?

# Answer
> ... I can't choose node:author or other tokens that display the user name. I get the restriction: "Data types: Select data of the type Taxonomy term."

## 1. Switch to the direct input mode

You should click the `Switch to the direct input mode` button (near the bottom left), which looks like this:

After clicking that button, it will bring up a selection list of the ***available*** terms (= possible values) that you can use in your taxonomy field.

## 2. Example

Consider this example, in Rules Export format, of a rule (actually a Rules Component, but the idea is the same) to illustrate how such Rules Action to "***Set a data value***" should look like and which will set the value of the term reference field `field_sample_tags` to term id = `31`:

```
{ "rules_replace_a_term_field_by_another_term_field" : {
    "LABEL" : "Replace a term field by another term field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
      { "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
      { "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
    ]
  }
}

```

Some more details to explain the above prototype:

* It uses a node as a parameter (to execute the Rules Component).
* These are the Rules Conditions:

+ check if the entity (= node) has a field `field_sample_tags`.
    + check if the entity (= node) has a field `field_demo_tags`.
    + check if the value of the field `field_demo_tags` corresponds to the term we want to replace (in this example, the term has id = `1`).
* These are the Rules Actions:

+ Set the value of field `field_sample_tags` equal to the term with term id = `31` (which is the term in the vocabulary for which we want to add the term reference).
    + Display a message on the site (only used for demo / testing).

## 3. Improvement - Pick the existing term that fits

Your question doesn't say "*How to pick the appropriate term (i.e. its term id) to be used to perform the 'Set a data value' for a given node author (how can you derive that term id from the data about the node author)?*".

If you only have a few node authors (say "Xin" and "Pierre"), you could use the Conditional Rules module to improve that Rules Action to 'Set a data value', so that the value to be used for the term id depends on the value of the node author.

## 4. Open question

Your question doesn't say "*What should happen if no term exists yet for a specific node author?*". If such scenario is impossible in your site, then you're lucky (and good to go). Otherwise you'll have to further improve the Rules logic you're implementing to:

1. get the appropriate (new) term created on the fly.
2. go find out what the term id is for the newly created term.
3. improve the Rules Action to 'Set a data value' to actually use the term id of this newly created term.

If you wonder how to do that (also), use this link ... 3 times (one for every bullet).
> 0 votes

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


title: How to trim body text (field_body)?

text:
# Question
Title: How to trim body text (field_body)?
I've created a view for a node which shows the content as rendered entity. Among others, I output the body field in the twig template:

```
{{ content.field_body }}

```

Now, I'd like to limit the text to 200 characters and put three dots. I've tested three different ways to do that, but nothing has worked. The problem is, that each way counts and trims the HTML characters too.

1: I've added the format "Trimmed" in "Manage display" =\> The text is limited but not correct. And I do not have the three dots.

2: I've trimmed the text in the twig template. But to count the text I have to render it first. Thereby, twig outputs the text as HTML (I see HTML tags on my page!)

```
{% set text = content.field_body|render %}
{{ text|length > 200 ? text|slice(0, 200) ~ '...' : text }}

```

3: I've tried to solve the problem in template\_preprocess\_node(). Here I have the same problem with counting the HTML markup too.

```
$body_text = $node->get('field_body')->getValue()[0]['value'];
$trimmed_text = substr($body_text, 0, 200) . '...';

```

How can I trim my text right?

Thank you very much for your help!

# Answer
> 23 votes
There's a few solutions you can try but take note truncating strings with html is generally a bad idea due to having potential unclosed or malformed tags.

**1. Use |raw to output the html as html, may produce malformed tags:**

```
{% set text = content.field_body|render %}
{{ text|length > 200 ? text|slice(0, 200)|raw ~ '...' : text|raw }}

```

**2. Strip html first, cleaner:**

```
{% set text = content.field_body|render|striptags %}
{{ text|length > 200 ? text|slice(0, 200) ~ '...' : text }}

```

**3. Register a twig extension (untested):**

https://gist.github.com/leon/2857883

Another helpful extension you can check out is the Text extension, which helps you prevent chopping up words:

http://twig.sensiolabs.org/doc/extensions/text.html

# Answer
> 7 votes
Improvements:

1. if you strip tags you should `|trim` to **get rid of whitespace**
2. **trim on word boundary** \- see below `slice()` and `split()`
3. Use **ellipsis** (`…`) rather than "..."
4. `|raw` the output

`{% set text = content.field_header_intro|render|striptags|trim %}`

`{{ (text|length > 200 ? text|slice(0, 201)|split(' ')|slice(0, -1)|join(' ') ~ '…' : text)|raw }}`

# Answer
> 6 votes
You can now do this with the twig\_extender module and use `|truncate`.

Here is an example of how to use it in the .twig template, note that I'm also using twig\_field\_value:

```
{{ content.field_name|field_value|first['#text']|truncate(15, true, '....') }}

```

*note:* I usually keep my devel settings (./admin/config/development/devel) set to use ***Symfony var-dumper*** and can figure out the chain with

ie: `{{ devel_dump(content.field_name|field_value) }}`

# Answer
> 4 votes
This is how I handled this.

Example:
**field--node--body--article.html.twig**

```
{% set mode = element['#view_mode'] %}
...
{% for item in items %}
  {% if mode == 'full' %}
    <div{{ attributes.addClass('texto') }}>{{ item.content }}</div>
  {% elseif mode == 'teaser' %}
    {# if there is something about trim_length in field formatter #}
    {% if item.content['#text_summary_trim_length'] %}
      {# first remove html tags then you slice with trim_length #}
      {% set texto = item.content['#text']|striptags|slice(0, item.content['#text_summary_trim_length']) %}
      <p {{ attributes }}>{{ texto }}...</p>
    {% else %}
      <p {{ attributes }}>{{ item.content }}</p>
    {% endif %}
  {% endif %}
{% endfor %}
...

```

---
Tags: theming, 8
---


# Question
Title: How to trigger a rule if a node has a certain Taxonomy term?
I'm trying to create a rule using Rules that will apply a watermark to an image within a node (using the ImageCache Actions module) if that given node has a specific Taxonomy term. For example, nodes with the term "Video" will get a play button icon over their image.

Is there a way to add taxonomy terms as a condition in Rules? It seems like it would be a simple task but I can't seem to figure it out. Does anyone know how I could do this?

# Answer
> 1 votes
Have a look at this, rather basic, rule (in Rules export format):

```
{ "rules_check_taxonomy_term" : {
    "LABEL" : "Check Taxonomy Term",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_insert" : [], "node_update" : [] },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_tags" } },
      { "list_contains" : { "list" : [ "node:field-tags" ], "item" : "21" } }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "A node containing the tag [node:field_tags] just got created or updated." } }
    ]
  }
}

```

Here is what this rule does:

* Rules Event: After saving new content, After updating existing content
* Rules Conditions:

+ ***Entity has field*** "`field_tags`", which is the machine name of the term reference field I want to check for.
    + ***List contains item*** "node:field-tags" and with Taxonomy term identifier value "`21`" (which is the term id of the term I want to check in this Rules Condition).
* Rules Action: Show a message on the site (which is "*A node containing the tag \[node:field\_tags\] just got created or updated.*" (with `[node:field_tags]` the actual term with term id = `21`).

What is crucial in the above rules example in the context of this question, are the 2 Rules Conditions.

Use the Rules UI to import the above rule in your site. Here are the tweaks you'll need to make it fit your case:

* Replace the Rules Event (if needed).
* Within the Rules Conditions, perform these changes:

+ replace the "node" entity with your entity.
    + replace the machine name of term reference "field\_tags", and adapt the "term id" to fit your case (for the term "Video").
* Replace the Rules Action by whatever fits your case.

---
Tags: 7, taxonomy-terms, rules, media
---


# Question
Title: How to conditionally send emails Drupal 8 Webform
I am trying to figure out how to do the following; based on a submitted value change the email behavior:

1. If (field 'send' value == no) then don't send the email
2. If (field 'member' value == yes) then change the email message

If I can find out how to do #1 above I could use that to achieve #2, in fact I suspect they have the same answer. I am looking for a hook but perhaps that is just me being stuck in D7 style of doing things.

# Answer
The latest dev release of Webform 8.x-5.x supports conditional emails and handlers.
> 5 votes

---
Tags: 8, webforms
---


# Question
Title: How to render specific form elements from the *.theme file
I am using Drupal 8 and would like to customize how form elements are being displayed. Specifically, I don't like how uneditable, populated textfields are displayed as plain text. I would have it being displayed as an editable textfield (or have the text look like it is in an uneditable textfield). I have looked at various hook functions to try and achieve this but nothing seems to work.

I figure the best way to go about this is if I can render the form fields individually myself and then create a twig file that displays the individual fields as I would like them to be displayed. Here is what I would like the twig field to look like:

```
<div class="from">
  {{ form.mail }}
</div>

<div class="message">
  {{ form.message }}
</div>

<div class="actions">
  {{ form.actions }}
</div>

```

This is what I came up with so far:

```
function theme_preprocess_form(&$variables) {

  $elements = $variables['element'];
  foreach($elements as $key => $element) {
    if (substr( $key, 0, 1 ) !== "#" ) {
      // $variables['form'][$key] = render[$element];
      // This is where I need the code to actually render the element
    }
  }

```

}

What is the function I need to call to return a fully rendered form element?

To clarify, I would like to accomplish this by only using they my\_theme.theme file for my\_theme.

Thanks.

# Answer
> 11 votes
The base hook `form` from the question is for rendering the HTML form tag. To render single form elements you need to specify a separate custom template.

**1. Register the custom template in a theme hook**

*mytheme.theme* or *mymodule.module:*

```
/**
 * Implements hook_theme().
 */
function mytheme/mymodule_theme() {
  return ['entity_moderation_form' => ['render element' => 'form']];
}

```

**2. Add the custom template to the form**

While building the form

*EntityModerationForm::buildForm():*

```
  public function buildForm(array $form, FormStateInterface $form_state, ContentEntityInterface $entity = NULL) {
    ...
    $form['#theme'] = ['entity_moderation_form'];
    return $form;
  }

```

or to an existing form in a form alter hook:

*mytheme.theme* or *mymodule.module:*

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function mytheme/mymodule_form_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['#theme'] = ['entity_moderation_form'];
}

```

You can skip this step if you use as template name the form id, see the comment from @BradJ.

**3. Use the custom template to style single form elements**

*entity-moderation-form.html.twig:*

```
{{ attach_library('content_moderation/content_moderation') }}
<ul class="entity-moderation-form">
  <li>{{ form.current }}</li>
  <li>{{ form.new_state }}</li>
  <li>{{ form.revision_log }}</li>
  <li>{{ form.submit }}</li>
</ul>
{{ form|without('current', 'new_state', 'revision_log', 'submit') }}

```

The example is from the core module Content Moderation.

# Answer
> 2 votes
Drupal 8 tend to move towards to TWIG template files rather than write theme\_hooks (however that has still a big role right now). I suggest you enable TWIG Debuging and that will "spam" the DOM with comments. Before each element there are two types of comments (for your purpose):

1. How to name your template file to make effect on that element
2. Which theme\_hook to use to modify its outlook/value etc.

I would definitely start on field template level first. If the widget of the field is hard to manipulate, you could also create your own widget type (extending from the current one) and use that. More on that: here

---
Tags: 8, forms, theming
---


# Question
Title: "Call to a member function label() on null", while it's defined
I'm using a module\_suggestions\_alter hook to force (or not) which template must be used in a specific case. The custom template I chose must is used in several cases, but sometimes, the default template must be used instead.

A while ago, I discovered that having too much templates for one node causes Drupal to choose the wrong template. I also discovered that I can remove the other suggestions so that I'm sure Drupal will choose the right template.

Now, I'd like to do the following: if the node type is equal to "node type 1" or "node type 2" (for example), then I unset every suggestions so Drupal uses the default template, `node.html.twig`. If not, I leave my custom template as a suggestion

> Disclaimer : I don't know if my "method" is the best one, but this is all I could think about. Feel free to tell me if this is heresy.

Here is my code:

```
function module_pdf_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {

  $node_type = ['node type 1', 'node type 2'];
  $view_mode = "node__module_pdf";
  $type = $variables['elements']['#node']->type->entity->label();
  // Outputs 'node type 1' if I do a die(kpr($type));

  if(in_array($type, $node_type)) {
    $view_mode = '';
  }

  if($variables['elements']['#view_mode'] === 'module_pdf') {
    foreach($suggestions as $i => $suggestion) {
      if($suggestion !== $view_mode) {
        unset($suggestions[$i]);
      }
    }
  }
}

```

So, as I told you, if the node type is equal to one of the elements that I set in the array, it will "erase" the `$view_mode` content. This way, the `foreach` will unset everything, and tell Drupal to use `node.html.twig`.

My main problem however, is that even though `$type` gives me the correct node value when tested, it will cause a server error if I use it in my foreach, and I don't know why. Error output is the following:

```
Error: Call to a member function label() on null

```

I tried a verification to check if the node type existed, but nothing changed. How can I fix this?

# Answer
> 1 votes
You have to check if you are in a node hook:

```
if ($hook != 'node') {
  return;
}

```

In other hooks you don't have a node object and the function label() is called on null.

Though you might want to check the machine name of the node type, because the display name can change when you have multiple languages:

```
$node->getType()

```

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


# Question
Title: How to check the value for specified field across all nodes?
I have minimal Drupal and PHP experience ...

**Problem**:

I have an autocreate function for a Content Type ('hannibal'), which has one defined field type ('faceman'). When Content Type 'hannibal' is created, it is done automatically through rules by passing the value for field 'murdock' from another content type. 'murdock' and 'faceman' are sometimes identical values (they are also identical formats: text, same formatting, direct copies).

I need to check across all other nodes of type 'hannibal', to see if the value for 'faceman' already exists in that field. I have Unique Field module active, but because the nodes are being created through Rules, it is not functioning in this case (perhaps it only works when in a user entered form).

**Issue**: A method to check field 'faceman' for the value being entered, in all nodes of type 'hannibal'.

I've already tried a LOT of options for this:

Rules - I have tried setting conditions, but can't find a way to load all nodes of type 'hannibal' to check that field value. I've tried to do it in PHP using snippets taken from elsewhere, but no luck. Also tried setting a rules component, but couldn't make sense of it.

Database query - I'm using SQLite. I've identified the table to check, and tried an EntityFieldQuery but the code I've tried as a condition is just crashing the page:

```
$value = token_replace('[node:field_murdock]', array('node' => $node));

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'source')
  ->propertyCondition('status', NODE_PUBLISHED)
  ->fieldCondition('faceman', 'faceman_value', '$value',)

$result = $query->execute();
if (isset($result['node'])) {
  return TRUE;
}

```

So long as I can create the nodes automatically, and prevent new nodes being created if they have an identical value to a pre-existing value for field\_faceman, I'm not that bothered about how it is done (within reason!).

This seems like such a basic function (checking all the values of a given field in the database), I must be missing an easier way to do this. Right?

Any help?

**UPDATE & SOLUTION**

Managed to solve it with EntityFieldQuery in the end. I'm convinced I can't be the only person with this issue, so for anyone of around my skill level in the same position in future:

Solution is via Rules using the PHP conditional.

Rules trigger is save content event. Conditional 1 is "content has 'faceman' field". Conditional 2 is Execute Custom PHP as below. No link between the two conditionals - trying an AND function broke them.

Custom PHP code:

```
// display murdock field taken from saved content as plaintext

$value = token_replace('[node:field_murdock]');

// search database for identical values of field faceman

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'hannibal')
->propertyCondition('status', 1)
->fieldCondition('field_faceman', 'value', $value, '=')
;

// if identical value of field faceman is found, return FALSE to Rules condition

$result = $query->execute();
if (isset($result['node'])) {
return FALSE;
}
else {
return TRUE;
}

```

Therefore the action part of the Rule will only be executed if the value is not already present in the Faceman field somewhere in another node. So long as your existing node types Hannibal have fields Faceman with equivalent values / formats, then a duplicate node will not be created.

My actions rules then create the Faceman field in the new content by directly copying field Murdock from the saved content which triggered the Rule. This ensures that the above logic works, and the node should only be created once, because Faceman will always be a child & copy of a Murdock field.

# Answer
> 3 votes
You can make this work by using Rules in combination with the Views Bulk Operations module, as further detailed below.

In what follows, I'm assuming that the machine name of your field is `field_optionlist` (change to whatever fits).

## Step 1 - Create a VBO view

Use the Views Bulk Operations (VBO) module to create a view of all relevant nodes, in which you should:

1. Add a VBO field to it.
2. Add a contextual filter for the `field_optionlist` field for which you want to check that its value is unique. Make sure to correctly configure this contextual filter, similar to what is mentioned in this answer to "How to have a field that counts the nodes submitted by the current user?" (credits to Niall Murphy, merci!).

Include a field like `nid` for each node (no need for any other fields). Just make sure you get exactly 1 row for each node you want to take into consideration.

Here is an export of such VBO view:

```
$view = new view();
$view->name = 'relevant_nodes';
$view->description = 'Produce a list of node ids that satisfy a specific filter';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Relevant nodes';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Relevant nodes';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'table';
$handler->display->display_options['style_options']['columns'] = array(
  'title' => 'title',
);
$handler->display->display_options['style_options']['default'] = '-1';
$handler->display->display_options['style_options']['info'] = array(
  'title' => array(
    'sortable' => 0,
    'default_sort_order' => 'asc',
    'align' => '',
    'separator' => '',
    'empty_column' => 0,
  ),
);
/* Field: Content: Nid */
$handler->display->display_options['fields']['nid']['id'] = 'nid';
$handler->display->display_options['fields']['nid']['table'] = 'node';
$handler->display->display_options['fields']['nid']['field'] = 'nid';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Content: OptionList */
$handler->display->display_options['fields']['field_optionlist']['id'] = 'field_optionlist';
$handler->display->display_options['fields']['field_optionlist']['table'] = 'field_data_field_optionlist';
$handler->display->display_options['fields']['field_optionlist']['field'] = 'field_optionlist';
/* Field: Bulk operations: Content */
$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations';
$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'node';
$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations';
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['display_type'] = '0';
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['enable_select_all_pages'] = 1;
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['row_clickable'] = 1;
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['force_single'] = 0;
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['entity_load_capacity'] = '10';
/* Contextual filter: Content: OptionList (field_optionlist) */
$handler->display->display_options['arguments']['field_optionlist_value']['id'] = 'field_optionlist_value';
$handler->display->display_options['arguments']['field_optionlist_value']['table'] = 'field_data_field_optionlist';
$handler->display->display_options['arguments']['field_optionlist_value']['field'] = 'field_optionlist_value';
$handler->display->display_options['arguments']['field_optionlist_value']['default_action'] = 'default';
$handler->display->display_options['arguments']['field_optionlist_value']['default_argument_type'] = 'raw';
$handler->display->display_options['arguments']['field_optionlist_value']['default_argument_options']['index'] = '0';
$handler->display->display_options['arguments']['field_optionlist_value']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['field_optionlist_value']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['field_optionlist_value']['summary_options']['items_per_page'] = '25';
$handler->display->display_options['arguments']['field_optionlist_value']['limit'] = '0';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'article' => 'article',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'relevant-nodes';

```

## Step 2 - Create a Rule

Create a rule like so:

* Rules Event: something like "Before saving content of type Article" seems most appropriate, though you can use any variation that fits.
* Rules Condition: "***Check number of results returned by a VBO view***". And select the VBO view created in the previous step. In doing so, you will be asked to "*specify arguments to pass to the view, one per line. You may use token replacement patterns.*". The token to be entered there is `node:field-optionlist`. If the number of results is 1 or more, then you know the value already exists. So within **Minimum number of results** you should enter the value `1`.
* Rules Action: this is pretty much up to your own imagination. For example if the Rules Condition is TRUE, you could use "Set a data value", to restore the value of that field to what it was before, i.e. `node-unchanged:field-optionlist`. Maybe also display an appropriate message, such as (when trying to change the value from `Advanced` to `Basic`):

> The value "Basic" has already been used in at least 1 other node ... (field value remains "Advanced").

Here is an export of a Rule that does exactly what is described above (if you have the Rules UI enabled, and a field with the machine name `field_optionlist`, you should be able to just import this rule):

```
{ "rules_prevent_multiple_nodes_with_same_field_value" : {
    "LABEL" : "Prevent multiple nodes with same field value",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "views_bulk_operations", "rules" ],
    "ON" : { "node_presave--article" : { "bundle" : "article" } },
    "IF" : [
      { "views_bulk_operations_condition_result_count" : {
          "view" : "relevant_nodes|page",
          "args" : [ "node:field-optionlist" ],
          "minimum" : "1"
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "The value \u0022[node:field-optionlist]\u0022 has already been used in at least 1 other node ... (field value remains \u0022[node-unchanged:field-optionlist]\u0022).",
          "type" : "error"
        }
      },
      { "data_set" : {
          "data" : [ "node:field-optionlist" ],
          "value" : [ "node-unchanged:field-optionlist" ]
        }
      }
    ]
  }
}

```

Note that my Rules Event is limited to "Article" (change to whatever fits), and replace (prior to trying to import this rule) the machine name of `field_optionlist` to whatever other machine name your field.

***Done!***

---
Tags: 7, entities, rules
---


title: How to modify path alias in Drupal 8

text:
# Question
Title: How to modify path alias in Drupal 8
Currently I'm on `example.com/node/add page`. Now I wish to add content in content type = article. What I want is, when accessing path `/node/add/article`, add content url should look like `node/add/article?keyword='hello'`

And this page still opens add node article page.

I tried changing alias at /admin/config/search/path/add

`/node/add/article`

to

`node/add/article?keyword='hello'` But it didn't worked?

# Answer
> 1 votes
One option would be to create a custom route. You might need to use a different name than /node/add/

So in a custom module add in your\_module.routing.yml

```
article_add:
  path: /add/article/{{ keyword }}
  defaults:
    _form: '\Drupal\your_module\Form\AddArticle::AddArticleWithYourKeyword'
  requirements:
   _permission: 'administer site configuration'

```

And then create a Form in your\_module/src/Form/AddArticle.php

```
<?php

namespace Drupal\your_module\Controller;

use Drupal\Core\Controller\ControllerBase;

class AddArticle extends ControllerBase {
    public static function AddArticleWithYourKeyword($keyword) {
         //Here you can generate your form with your added keyword and return it as a render array
    }
}

```

This will allow you to grab a form and make edits to it, or generate an entirely custom one. In my example I made it so you pass the keyboard in the path itself not as a GET variable, but if you need you can just make the route /add/article/ and then check for GET variables inside your function.

**UPDATE** Another method would be to implement the hook\_form\_alter function

```
function yourmodule_or_theme_form_node_form_alter(&$form, FormStateInterface $form_state) {
$request = \Drupal::request();
$keyword       = $request->get('keyword');
  if (in_array($form['#form_id'], ['node_article_edit_form'])) {
    $form['keyword'] = [
      '#type' => 'textfield',
      '#title' => 'keyword',
      '#default_value' => $keyword,
    ];
  }
}

```

Not 100% sure of the syntax but that's the general idea.

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


# Question
Title: How to let user decide how comments be sorted
The scenario is, in a project comments has a vote up/down field so users can rate a comment. What I'm looking for now is a solution so user can decide if comments should be sorted by date created (newest first) or by its rate (top rated first). Should I use a views for that? if so how can I hide main comment section?

# Answer
It seems that the most obvious way to manage your user's behavior on comments would be to use **Views**.

And if you want to **hide the main comment section**, you can do so in your content type's parameters (check the comment section of you content type). You'll see stuff like hide and close.

Hope that gives you a start point.
> 0 votes

---
Tags: 7, views, theming, comments
---


title: Problem with cache in template

text:
# Question
Title: Problem with cache in template
In the hook\_preprocess\_page i'm sending at twig template the value of one cookie, but always have the value of the first time of loading page.

```
function supertics_preprocess_page(&$variables) {
    $variables['#cache']['contexts'][] = 'url.query_args';
    $variables['utm_medium'] = $_COOKIE['utm_medium'];
}

```

It's possible avoid this cache?

Thanks

# Answer
Yep in this case cache depends of the query args, wich means once some url query args are met a cache is bind. Then it won't change any more. This is usefull fore search pages for examples: `/search?type=article&status=published` You should try with `$variables['#cache']['contexts'][] = 'cookie:utm_medium';` Or if it still doesn't work with session or user contexts... hope it helps,
> 0 votes

---
Tags: theming, caching
---


# Question
Title: How to get the value of an item from a list field to add it to a computed field
I am on Drupal 7 and I have issue. I want to set a **token** system that will make people buy **token from their user account settings** in order to be able to do some particular actions on the site.

So I've created three fields in the user's form with the help of Display Suite:

* **field\_buy\_tickets** (Yes/No) : Yes if the user wants to add more tickets. If "Yes", field "field\_nb\_of\_tickets" appears.
* **field\_nb\_of\_tickets** : is a list of numbers from 1 to 9 that the user choose one item.
* **field\_avoir** : When the user Save the changes, the number in the item chosen in "field\_nb\_of\_tickets" should be added to the this field\_avoir. I chose this field to be "computed" because I want the new value to be added to the old one, not to override it.

I was sure that it would work well, **but I get an error**. After a few time trying to make it work, I am **still at the same point**.

Can somebody help ?

**Here are some pictures to illustration the case**:

**1. The first 2 fields**

**2. The third field**

**3. The field\_avoir settings**

**4. The error**

**Thank you**.

# Answer
Definitely I found out what to do. **Maybe this will help somebody else**.

* **I wrote this before :**

*$entity\_field\[0\]\["value"\] = field\_get\_items($entity\_type, $entity, "field\_nb\_of\_tickets");*

* **This is what's new :**

I did put the foreign field's value in a variable before adding it to the current field :

*$nb\_of\_tickets= field\_get\_items($entity\_type, $entity, "field\_nb\_of\_tickets");*

*$entity\_field\[0\]\["value"\] = $entity\_field\[0\]\["value"\] + $nb\_of\_tickets;*

Now it works.
> 0 votes

---
Tags: entities
---


# Question
Title: How to hide the filename in drupal 7 files and add link to icon?
I would like to know how to hide the filename in Drupal 7 files and add a link to an icon? The default style is awful I would like to change that. I am looking for the simplest solution because I just know basic HTML and CSS. Maybe I can use some module to do that? If somebody can explain me step by step how to do it will be great.

# Answer
Ran across your question looking for the same answer... This is what I found. I'm at best a novice with Drupal, so I need easy solutions.

There is this module: https://www.drupal.org/project/file\_field\_icons

There are also some more options/notes here using CSS: How to change File field icons (without changing core)?
> 0 votes

---
Tags: entities
---


# Question
Title: How to check if a user has ever ordered a product/list of products
Given a list of product IDs, I'm trying to determine if a user has ever purchased any of them.

At the moment my logic consists of loading all the orders related to a user, then looping through the order lines to check individual product IDs:

```
$ordered = FALSE;

$node_wrapper = entity_metadata_wrapper('node', $node);
$product_ids = array();
foreach ($node_wrapper->field_products as $product) {
  $product_ids[] = $product->product_id->value();
}

$orders = commerce_order_load_multiple(array(), array('uid' => $account->uid, 'status' => 'checkout_checkout'));
foreach ($orders as $order) {
  $wrapper = entity_metadata_wrapper('commerce_order', $order);
  foreach ($wrapper->commerce_line_items as $order_line) {
    $product = $order_line->commerce_product;
    if (in_array($product->product_id->value(), $product_ids)) {
      $ordered = TRUE;
    }
  }
}

```

This feels like a long way round, and that perhaps I'm missing a helper function somewhere in Commerce that would get me this information.

Anyone know if such a function exists, or if there's a more elegant method to get this data?

NB. I know 'checkout\_checkout' isn't the right order status for the production code, this is just test code at the moment.

I'm looking for an API solution to this; building up an SQL query would obviously be very easy, but more verbose and error-prone. What I'm looking for is a *more* elegant solution than my existing one (if one exists; it might not).

# Answer
Here's an alternative approach, using an SQL query

```
$ordered = FALSE;

$node_wrapper = entity_metadata_wrapper('node', $node);
$product_ids = array();
foreach ($node_wrapper->field_products as $product) {
  $product_ids[] = $product->product_id->value();
}

// Query order details for products
// Note this is the line item product reference table
$query = db_select('field_data_commerce_product', 'p');
// Example if you want more fields, but would need to change ->fetchCol()
// $query->fields('o', array('order_id', 'order_number', 'uid', 'mail'));
$query->fields('o', array('uid'));
$query->innerJoin('field_data_commerce_line_items', 'l', 'l.commerce_line_items_line_item_id = p.entity_id');
$query->innerJoin('commerce_order', 'o', 'o.order_id = l.entity_id');
$query->condition('p.commerce_product_product_id', $product_ids, 'IN');
$query->groupBy('o.order_id');
// Fetch array of uids
$result = $query->execute()->fetchCol();

// Check if account->uid in array of order uids
// If so, uid has ordered product.
if(in_array($account->uid, $result)){
  $ordered = TRUE;
}

```
> 4 votes

# Answer
In a project I added a hidden field called 'Bought history' to user account, containing a list of products a user has bought, then using Rules module in the event of "completing checkout" I added the product ID to user's bought history.

Now I easily load user data, and check if products are stored in this list or not (Even node ID can be saved rather than Product ID)
> 0 votes

---
Tags: commerce
---


# Question
Title: 'Views Field' issue in NO RESULTS BEHAVIOR - Hide if empty not working
'Hide if empty' configuration of views is not working properly as a result all the empty fields are showing.

Is there any work around to force fully hide empty fields in the views result (Page/block) neither using the configuration under 'No Results behaviour nor using views-php/block-php?

# Answer
> 1 votes
Your questions does not give much information about your view, but if you want to hide the complete output of a row (when using a table) you can do this:

> You can add filter criteria corresponding to the field on which you want to hide the row . Suppose you want to hide the row if content: body is empty then you can add filter criteria as Content:Body not equal to "" (where value field should be left empty). This will automatically hide the row if the specific field is empty .

source: Hide row in view if any field is empty

---
Tags: views, entities
---


title: bulk node translation

text:
# Question
Title: bulk node translation
We have a lot of languages on the site and a node needs to be translated in every one of them. We create the node in English and then some people translate the content to their language. So when there is no translation available the content remains in English. The translators only have edit permissions for the nodes in there language. To not have to give them more access we create the nodes that should be translated.

Now when creating a node we have to click translate several times to create a node for every language. I'm looking for a way to do this in one click.

One way i was thinking of this is by selecting the node to be translated and do something like the existing bulk operations to translate them.

Or by using rules to create a translation for every language when the node is created.

Anyone with experience in this field?

# Answer
Try the Entity translation actions module. https://www.drupal.org/project/entity\_translation\_actions
> 1 votes

---
Tags: nodes, i18n-l10n
---


# Question
Title: GMap Module, How do I make my map change its marker icons faster/without hang?
A bit of a newbee, but I have a somewhat complex issue.

**Background:** I am creating a map for a client, with a filtered list beneath it. when they click one of the categories at the top, the list filters to that category, and the respective markers on my GMap view change icons from a light blue to dark blue if they are the active category, and vice-versa if inactive. I have been working on this on and off for a little over a month, but the deadline is the end of the month. I'm on the last few steps, namely optimizing. The Module I am using is GMap 2.11-7.x

**The problem:**  I have everything *working*, but not very quickly. When I go to switch the categories, it calls

`var map=Drupal.gmap.getMap('auto1map');
 map.bind('addmarker', function (m) { ... }); //bind addmarker-handler, the marker is available as callback-argument`

However, I noticed, to update a marker, it calls that method for each marker, AND it calls the methods within to update each marker, which seems necessary because otherwise it stops after the first marker.... Ultimately, it hangs for a few seconds where the webpage freezes up, which is not ideal.

I get my brain all jumbled up, this is my first web dev job, and I don't have the most solid grasp on JavaScript. Do I need to extract the setIcon code from the bind event? Is there a better way to update Icons on a Google Map?

Full code is as follows:

```
(function ($) {
  //When click on marker, act on related link

  //initiates drupal gmap module
  Drupal.behaviors.gmap = {
    attach: function (context, settings) {
      //I get all the html list elements
      var listBlock = $('.project-prof'); //choose .project-prof elements
      var li = $(listBlock).parent().parent().parent(); //chooses the list item of .project-prof elements
      var activeCategory = "Healthcare"; //sets default activeCategory
      var activeLi = $("."+activeCategory).parent().parent().parent(); //chooses list item of active .project-prof
      var location = []; //this will be used to keep track of the locations of each activeLi in the array of <li>
          // now we .push() the position(integer) of each list item that has activeCategory
      $(li).each(function(i){
        if($(this).children().children().children().hasClass(activeCategory)){
                location.push(i);
            }
      });
      console.log(location); //debug

      //Set index to associate list element and markers
      var index = 0;

      //reference for the map
      var map=Drupal.gmap.getMap('auto1map');
      //bind addmarker-handler, the marker is available as callback-argument
      map.bind('addmarker', function (m) {
        var element = $(li)[index];
        m.marker.index=index;

        //remove listeners set automatically by the library
        google.maps.event.clearListeners(m.marker, 'mouseover mouseout click');

        //hover over markers
        google.maps.event.addListener(m.marker, 'mouseover',function(){
          //Hide other elements
          //so activeLi toggle here hides the active category
                $(activeLi).stop().animate({
                  height: "toggle",
                  width:"toggle",
                  opacity: "toggle"
                });
      //element toggles the specific moused-over object
                $(element).stop().animate({
                  height: "toggle",
                  width:"toggle",
                  opacity: "toggle"
                });
        });
        //same thing but just mouseout
        google.maps.event.addListener(m.marker, 'mouseout',function(){
                $(activeLi).stop().animate({
                  height: "toggle",
                  width:"toggle",
                  opacity: "toggle"
                });
                $(element).stop().animate({
                  height: "toggle",
                  width:"toggle",
                  opacity: "toggle"
                });
        });
        //hover is set

        //filter list after button press (button event further down)
        function toggleCategory(thisVar) {
            //console.log("" + thisVar+ " "); //debug to make sure activeCategory is bound correctly

            activeLi = $("."+thisVar).parent().parent().parent(); //gotta set activeLi again
            var location = []; //empty out the old location array
                        //do it again
            $(li).each(function(i){
                if($(this).children().children().children().hasClass(thisVar)){
                    location.push(i);
                }
            });
            console.log(location); //more debug
            //fancy animations
            $(activeLi).stop().animate({
                  height: "toggle",
                  width:"toggle",
                  opacity: "toggle"
            });
                        //this is how the icons are actually set for the markers to their correct active or inactive look
            if($.inArray(m.marker.index,location) != -1){
                console.log("2." + m.marker.index + " = " + "true"); //debug
                m.marker.setIcon('marker.png');
            } else {
                m.marker.setIcon('marker2.png');
            }
        }
        //filter is set

        //setting defaults
                //initial setup on page load of which markers are active and inactive
        if($.inArray(m.marker.index,location) != -1){
                console.log("2." + m.marker.index + " = " + "true"); //debug
                m.marker.setIcon('marker.png');
        } else {
                m.marker.setIcon('marker2.png');
        }
        $(listBlock).not($(".Healthcare")).parent().parent().parent().hide();
        //defaults are set

        //filtering buttons
        $("#block-block-38 input").on("click", function(){
            $(activeLi).stop().animate({
                  height: "toggle",
                  width:"toggle",
                  opacity: "toggle"
            }); //fancy animations
            activeCategory = $(this).attr('name'); //set activeCategory to this new button's name
            toggleCategory(activeCategory); //pass activeCategory into the above function (it becomes thisVar)
        });
        //buttons set

        //toggle marker location's modal, same as clicking on respective list item
        google.maps.event.addListener(m.marker, 'click',function(){
            $($(element).find('a').attr("data-target")).modal("show");
        });
        //modal is set

        index++; //increment index so we can do this all over again for each marker?
      });
    }
  }
})(jQuery);

```

How can I cut the fat out of this code/make this work faster?

Here's a visual aid:

# Answer
> 0 votes
I have managed to fix the hang. I learned a lot about Google Maps in general, but as I was clicking a filter button, it would add new markers, which would make new arrays, which would then execute 66 more times, doing all of it at once. So I realized after a while, why not just take out all the code from that addmarker block, putting it below?

To replace all that code, the most important thing was to stuff each new marker into an array, to compare their index later to the "active" list that resides below the map. If this helps anyone, yet they need help, let me know, I might be able to assist.

```
(function($) {
    //When click on marker, act on related link
    //initiates drupal gmap module
    Drupal.behaviors.gmap = {
        attach: function(context, settings) {
            //I get all the html list elements
            var listBlock = $('.project-prof'); //choose .project-prof elements
            var li = $(listBlock).parent().parent().parent(); //chooses the list item of .project-prof elements
            var activeCategory = "Healthcare"; //sets default activeCategory
            var activeLi = $("." + activeCategory).parent().parent().parent(); //chooses list item of active .project-prof
            var location = [];
            var markers = [];
            //Set index to associate list element and markers
            var index = 0;
            //reference for the map
            var map = Drupal.gmap.getMap('auto1map');

            //pushes the location of the active list item into the location array
            $(li).each(function(i) {
                if ($(this).children().children().children().hasClass(activeCategory)) {
                    location.push(i);
                }
            });

            //bind addmarker-handler, the marker is available as callback-argument
            map.bind('addmarker', function(m) {
                var element = $(li)[index];
                m.marker.index = index;

                //remove listeners set automatically by the library
                google.maps.event.clearListeners(m.marker, 'mouseover mouseout click');

                //hover over markers
                google.maps.event.addListener(m.marker, 'mouseover', function() {
                    //Hide other elements
                    //so activeLi toggle here hides the active category
                    $(activeLi).stop().animate({
                        height: "toggle",
                        width: "toggle",
                        opacity: "toggle"
                    });
                    //element toggles the specific moused-over object
                    $(element).stop().animate({
                        height: "toggle",
                        width: "toggle",
                        opacity: "toggle"
                    });
                });
                google.maps.event.addListener(m.marker, 'mouseout', function() {
                    $(activeLi).stop().animate({
                        height: "toggle",
                        width: "toggle",
                        opacity: "toggle"
                    });
                    $(element).stop().animate({
                        height: "toggle",
                        width: "toggle",
                        opacity: "toggle"
                    });
                });
                //hover set

                //now we push this marker into an array that contains the markers
                markers.push(m.marker);

                //now check if this marker's index in that array is a number in location[]
                if ($.inArray(m.marker.index, location) != -1) {
                    m.marker.setIcon('../markers/stevens.png');
                } else {
                    m.marker.setIcon('../markers/stevens2.png');
                }

                //toggle marker location's modal, same as clicking on list
                google.maps.event.addListener(m.marker, 'click', function() {
                    $($(element).find('a').attr("data-target")).modal("show");
                });
                //modal set

                index++;
            });

            //filtering buttons
            $("#block-block-38 input").on("click", function() {
                $(activeLi).stop().toggle();
                $(".prof-cat-active").removeClass("prof-cat-active");
                $(this).addClass("prof-cat-active");
                activeCategory = $(this).attr('name');
                location = [];
                $(li).each(function(i) {
                    if ($(this).children().children().children().hasClass(activeCategory)) {
                        location.push(i);
                    }
                });
                console.log(location);
                toggleCategory(activeCategory);
            });
            //buttons set

            //default for the list below map
            $(listBlock).not($(".Healthcare")).parent().parent().parent().hide();

            //function that toggles the category
            function toggleCategory(thisVar) {

                activeLi = $("." + thisVar).parent().parent().parent();
                $(activeLi).stop().toggle();

                for (var i = 0; i < markers.length; i++) {
                    console.log(markers[i]);
                    console.log($.inArray(markers[i].index, location));
                    if ($.inArray(markers[i].index, location) != -1) {
                        console.log("2." + markers[i] + " = " + "true");
                        markers[i].setIcon('../markers/stevens.png');
                    } else {
                        markers[i].setIcon('../markers/stevens2.png');
                    }
                }

            }
        }
    };
})(jQuery);

```

---
Tags: 7, javascript, google-maps
---


title: How to sort by condition in entityQuery

text:
# Question
Title: How to sort by condition in entityQuery
I want to get a list that the items with a specific term in the top (like promote). The query would be like:

```
$query = \Drupal::entityQuery('node')
  ->condition('status', 1)
  ->condition('type', 'news')
  ->sort('field_product_category', $tid, '<>') //Error <>
  ->range(0, 5);

```

Can I put calculation in sort condition? I do not want to make 2 queries.

# Answer
> 1 votes
I don't think you can sort that way with an entity query. But with a select query, you have more flexibility.

I would try something like this:

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

$query = $database->select('node_field_data', 'nfd')
  ->fields('nfd', ['id']);

$query->condition('nfd.status', 1);
$query->condition('nfd.type', 'news');
$query->range(0, 5);

$query->leftJoin('field_product_category', 'pc', 'pc.entity_id = nfd.nid');
$query->addExpression('pc.field_product_category_target_id <> :target_tid', 'is_featured', [':target_tid', $target_tid]);

$query->orderBy('is_featured');
$query->orderBy('nfd.changed');

$matches = $query->execute()->fetchAll();

```

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


# Question
Title: How to download file upon submitting a form?
I have a form with the submit button. And I have a file in '/sites/default/files/tmp/my\_doc.docx' I'm trying to download the file upon submitting the form.

Here is my code

```
public function submitForm(array &$form, FormStateInterface $form_state){
   $filename = '/sites/default/files/tmp/my_doc.docx';
   $response = new BinaryFileResponse($filename);
   $form_state->setResponse($response);
}

```

But it doesnt't work properly.

That is, the file is being downloaded but has the same name that name of php file containing this code.

Could you clarify me, what have I done wrong ?

# Answer
> 6 votes
You need to set the filename with setContentDisposition, as the constructor only takes the file, but doesn't set the name itself:

```
$response->setContentDisposition(
    ResponseHeaderBag::DISPOSITION_ATTACHMENT,
    'my_doc.docx'
);

```

Don't forget to add `use Symfony\Component\HttpFoundation\ResponseHeaderBag;` at the top of your file.

There is quite a bit more you can do with BinaryFileResponse as well, so check out some of the methods.

---
Tags: 8, files
---


# Question
Title: Drupal 8 Webform - Change to Dev Version
I need to send emails in Drupal 8 Webform conditionally based on what the user has selected. I know this feature was added in the most recent release in 8.x-5.x-dev, but I have the beta branch installed (8.x-5.0-beta16). Is there an easy way for me to change to this version of the module, or am I out of luck?

Thanks, Lisa

# Answer
> 0 votes
if you have drush on your server you can easily select a version with this command

```
drush dl webform --select

```

it should show something like this

```
Choose one of the available releases for webform:
 [0]  :  Cancel
 [1]  :  8.x-5.x-dev     -  2017-Sep-07  -  Development
 [2]  :  8.x-5.0-beta16  -  2017-Aug-08  -  Supported, Recommended
 [3]  :  8.x-4.x-dev     -  2016-Nov-28  -  Development

```

and you could press 1 then enter to select 5.x-dev

i believe you'd also be prompted with a message warning you that you're overwriting the previously installed beta16 version and you'll say ok

# Answer
> 0 votes
If you have installed your site using composer you can try this command

```
composer require drupal/webform:5.x-dev
```

---
Tags: 8, webforms
---


title: Form API image preview

text:
# Question
Title: Form API image preview
I've read many discussions about image preview in fapi with `'managed_file'`, but I can't find a conclusive answer on how to do this properly in D8.

An obvious solution would be to reuse `Drupal\image\Plugin\Field\FieldWidget\ImageWidget`, but I don't know how to accomplish this.

So my question is: how can I have an image upload field with image preview in my form in D8 and what would the associative array in my `buildForm` function look like?

# Answer
> 16 votes
After searching for a while, I have found some kind of workaround solution for this here: https://stackoverflow.com/a/38268567/2267244

I have tested it and it works, here is bit modified version which I have used.

Also I'm not sure if we should mark this question as dpulicate as I found the solution on stackoverflow.com.

Anyway Here is how your form field should looke like:

```
$form['image_with_preview'] = [
  '#type' => 'managed_file',
  '#title' => t('Image with preview'),
  '#upload_validators' => [
    'file_validate_extensions' => ['gif png jpg jpeg'],
    'file_validate_size' => [25600000],
  ],
  '#theme' => 'image_widget',
  '#preview_image_style' => 'medium',
  '#upload_location' => 'public://',
  '#required' => FALSE,
];

```

And also you will need to implement `hook_preprocess_HOOK` in your module like this:

```
function YOUR_MODULE_preprocess_image_widget(&$variables) {
    $element = $variables['element'];

    $variables['attributes'] = array('class' => array('image-widget', 'js-form-managed-file', 'form-managed-file', 'clearfix'));

    if (!empty($element['fids']['#value'])) {
      $file = reset($element['#files']);
      $element['file_' . $file->id()]['filename']['#suffix'] = ' <span class="file-size">(' . format_size($file->getSize()) . ')</span> ';
      $file_variables = array(
        'style_name' => $element['#preview_image_style'],
        'uri' => $file->getFileUri(),
      );

      // Determine image dimensions.
      if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
        $file_variables['width'] = $element['#value']['width'];
        $file_variables['height'] = $element['#value']['height'];
      } else {
        $image = \Drupal::service('image.factory')->get($file->getFileUri());
        if ($image->isValid()) {
          $file_variables['width'] = $image->getWidth();
          $file_variables['height'] = $image->getHeight();
        }
        else {
          $file_variables['width'] = $file_variables['height'] = NULL;
        }
      }

      $element['preview'] = array(
        '#weight' => -10,
        '#theme' => 'image_style',
        '#width' => $file_variables['width'],
        '#height' => $file_variables['height'],
        '#style_name' => $file_variables['style_name'],
        '#uri' => $file_variables['uri'],
      );

      // Store the dimensions in the form so the file doesn't have to be
      // accessed again. This is important for remote files.
      $element['width'] = array(
        '#type' => 'hidden',
        '#value' => $file_variables['width'],
      );
      $element['height'] = array(
        '#type' => 'hidden',
        '#value' => $file_variables['height'],
      );
    }

    $variables['data'] = array();
    foreach (\Drupal\Core\Render\Element::children($element) as $child) {
      $variables['data'][$child] = $element[$child];
    }
}

```

I have tested it on my local Drupal instance and it works fine, image preview was displayed after AJAX upload finished.

---
Tags: 8, forms, media
---


# Question
Title: Create a view from one result of another view and link to it
I need to set up a contextual filter that will pass the information from a single row of a view into a new view that only shows that one row, using maybe a link that opens it into a new page or a PDF.

When a user clicks "Print" I would like the resulting page to just show the information from that one line...

**Background**

I have a view that lists a row of things in a table. It's data imported into MySQL that's not associated with a node. I need to build a view page certificate to use instead of Certificate.

The data is quiz scores and the fields are QID, Date, Course, Score and Print Certificate. The "Print Certificate" column is a Global: Math Expression field that basically compares the score (`score`) with the global passing score variable (`pass_rate`) and prints a link if the expression is not zero, otherwise the field is left blank. The expression I am using to accomplish this is: `abs(([score]+1)-[pass_rate])+(([score]+1)-[pass_rate])`.

Course is a custom content type that is connected to the quiz that was taken. The quiz also links to the course so that it comes up in this view and Quiz is using the Quiz module.

**What I've Tried**

I created another view as a page that is similar to the view that shows all the scores, except I limited it to one item, excluding all fields from showing and I arranged it as an unordered list instead of a table. Using Global Text field which is not excluded, add back all the other fields using replacement patterns in order to control how the data is rendered so that it reads more like a certificate about *one specific quiz score or QID*. What needs to be done in order that the information displayed on this view page is the same as the row that linked to it, or just one QID?

**Notes**

So why not just use certificate? Biggest issues are that there is no token for when the certificate was earned or when the quiz was passed. See my SE post. The other reason is because the quiz scores were imported as values from another site. See my other SE post on this.

**Ideas** Can I use a contextual filter in the parent view with some php using the fetchfield() function such as something like:

`db_query_range('SELECT 1 FROM {quiz_node_results} WHERE qid = :qid', 0, 1, array(':qid' => $[something]->qid))->fetchField();`

# Answer
> 1 votes
With much help from an answer in this post I was able to solve my issue. Here are the steps in case it is helpful to anyone else:

* create a view (in my case, to show information from the quiz\_node\_results table, using quiz result ID or `result_id`)
* create a PDF view containing the same fields as in the first view; use the views PDF module
* in the first view, add a Global PHP field (use the Views PHP module) and add some PHP to print a link to the data in the row of the table from the PDF view if the score is at least the score threshold (`pass_rate`) for getting a certificate:

`<?php
if ($row->score>=$row->pass_rate) {
print l('Print','/data/'.$row->result_id);
}
?>`

* in the PDF view, make sure the URL to the view is `/data/%` and add a contextual link; in my case, for the quiz result ID, set to show all if validation is provided and to show basic validation to show all if not provided

# Answer
> 0 votes
Except of rewriting the result from 'Notes' to 'View Notes' there is the option to make this field a link. The other option is to add a 'Global: Text Area' element and set there the link of your view and also you can pass parameters. In you second view (Book Notes) you can use contextual filers to fetch which book you want to display.

If you want to add extra details except of the view, I would suggest to use panel page where you can place your view as a block (and you can pass parameters through URL) and also add whatever else you want.

---
Tags: 7, views
---


# Question
Title: How do I translate a views field to lowercase and with spaces replaced with dashes but not make it a link?
I've got a link that surrounds some code (jquery hexagons). I'd like to be able to just print out the link.

The solution

Firstly, 2 copies of the 'studio name field'. The second set to 'rewrite as link' with the translations.

Secondly, 'exclude from display' both fields.

Thirdly. Custom text to print out the hexagon.

```
<div class="comb studio-comb">
<div class="front-content">
    <a href="/studio/[field_studio_name_1]">
        <h2>[field_studio_name]</h2>
        <hr class="break">
        [field_studio_address]
    </a>
</div>
<div class="back-content">
      <a href="/studio/[field_studio_name_1]">
        <h2>[field_studio_name]</h2>
        <hr class="break">
        [field_studio_address]
    </a>
</div>

```

If I use the 'rewrite as link' replacement then I get

```
 <a href="/studio/<a href=... >">

```

If I use the raw version I am stuck with

```
<a href="/studio/My Studio">

```

Here is a fiddle with a views export that demonstrates the problem.

# Answer
> 1 votes
You want link all output with studio/my-studio .First convert My studio to lowercase then rewrite as link custom text.

Think My studio is \[field\_studio\_name\_1\] .Convert this to lowercase. Then rewrite as link custom text like this .

---
Tags: views
---


# Question
Title: Display Views Result Summary in Twig Template
I have views with exposed filter and display exposed filter as a block. I need something like views result summary on my twig template. How am I supposed to achieve this in Drupal way.

# Answer
> 1 votes
I hope you mean views results count. If that is what you are looking for then you get it by
{{ view.total\_rows }}

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


title: How to theme Bean block in drupal 7

text:
# Question
Title: How to theme Bean block in drupal 7
I have create a custom block using Bean. It have a field collection and that field collection have 8 values. I have create a bean.tpl.php to override block. Now i need to know how can i get that field collection values using loop inside bean.tpl.php file.

# Answer
First you need enable for create tpl name bean.tpl.php call for every bean type.

```
$conf['theme_debug'] = TRUE;

```

In this tpl you get $content variable . Please print\_r($content) in tpl or install devel module to dmp($content). I suggested you install devel module. After that you can find your field collection

Load field collection like this

Thank you
> 0 votes

---
Tags: theming, blocks
---


title: Ajax textfield in hook_form_alter

text:
# Question
Title: Ajax textfield in hook_form_alter
I'm attaching ajax on textfield value. One enter value in textfield and ajax callback returns form element.

Below code is showing ajax 500 error. Can anyone tell what is mistake in this code?

```
function hook_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

    $form['field_base_price']['widget'][0]['value']['#ajax'] = array(
            'event' => 'change',
            'wrapper' => 'final-price-wrapper',
            'callback' => 'final_price_ajax_callback',
            'method' => 'replace',
          );

    $form['field_final_price']['#prefix'] = '<div id="final-price-wrapper">';
        $form['field_final_price']['#suffix'] = '</div>';
          $form['final_price_label'] = array(
            '#weight' => 11,
            '#prefix' => '<div id="final-price-wrapper" class="field-name-field-final-price form-item">',
            '#suffix' => '</div>',
          );
          $form['final_price_label']['title'] = array(
            '#type' => 'markup',
            '#markup' => '<label>' . $form['field_final_price']['widget'][0]['value']['#title'] . '</label>',
          );

    }

    /**
     * Final price AJAX callback.
     */
    function final_price_ajax_callback($form, $form_state) {
      return $form['final_price_label'];
    }

```

# Answer
You can use simple jQuery to achieve this then. Try putting the following code in your JS file:

```
$("#fname").blur(function(){
  var fname = $("#fname").val();
$("#lname").val(fname);
});

```
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Form redirect in hook alter submit is not working in Drupal 8
I want to create multi step form based on tabs created using Fieldgroups. I have been able to alter the ECK form as well as added my own custom submit handler.

In the custom submit handler, I have added a form redirect that redirects to the same form but with a fragment so that the next tab gets shown. I am able to generate the fragment for the route, but its not working. In-fact, the redirect seems to not work at all for any valid internal route. Kindly advise.

Please find the form redirect url.

```
$url = new Drupal\Core\Url('eck.entity.add'
, ['eck_entity_type' => 'registration_configuration' , 'eck_entity_bundle' => 'config_2']
, ['fragment' => 'edit-group-add']);
$form_state->setRedirectUrl($url);

```

# Answer
I was executing setRebuild()! I added another submit button and started doing the steps in my previous submit logic one by one, then it hit me. Form redirection will not happen if your submit is rebuilding the same form :)

```
$form_state->setRebuild();

```
> 1 votes

---
Tags: 8, forms
---


# Question
Title: How can I force Composer to install a dev branch over a stable release?
I am experimenting with Bootstrap 3 in Drupal 8 and I want to stay on the dev branch of bootstrap.

In my `composer.json`, I wrote the following line based on Drupal Packagist:

```
"drupal/bootstrap": "8.3.*@dev",

```

However, when I run `composer update`, it downloads `8.3.0-beta2` (2015-Dec-19) instead of the latest dev release (2016-Feb-20).

```
Gathering patches for root package.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Gathering patches for root package.
Gathering patches for dependencies. This might take a minute.
  - Installing drupal/bootstrap (8.3.0-beta2)
    Downloading: 100%
    Downloading: 100%

```

To make sure it wasn't some caching issue, I ran:

```
composer selfupdate
composer clear-cache
composer update

```

But it did the same thing-- install beta2.

How do I force it to download the dev release instead?

# Answer
While it will install the latest dev release of the Drupal module/theme to simply do the following:

```
composer require drupal/bootstrap:3.x-dev

```

I would argue a **best practice** when installing a dev version of a module is to make sure you are going to get the commit you want (which might not be the latest), so I would do the following:

```
composer require drupal/bootstrap:3.x-dev#5670922dea05fffb6506a6cd5d53546b9fae8df9

```

Or you can manually add it to your require in composer.json (as below) and then on the command line run `composer install`

```
"drupal/bootstrap": "3.x-dev#5670922dea05fffb6506a6cd5d53546b9fae8df9",

```

To get the commit you should go to http://cgit.drupalcode.org/bootstrap/log/ and find the commit you want (the commit hash is the id on the commit's page). btw: the above hash is not a real commit on the Bootstrap project
> 29 votes

# Answer
You can keep the original prefer-stable settings. The `@dev` in `8.3.*@dev` is the stability flag for the given package. The easiest way to force a dev-version of a package is to use a different version constraint. Use `8.3.x-dev` instead, this version constraint references to a the `8.x-3.x` branch and works independently from `prefer-stable` and `minimum-stability`.
> 16 votes

---
Tags: composer
---


title: Trigger delete cache of url

text:
# Question
Title: Trigger delete cache of url
I've two api url

* /api/v1/get-list
* /api/v1/post-item

In API url /api/v1/get-list I was set cache like this:

```
$build = [
  '#cache' => [
    'contexts' => ['url','url.query_args'],
    'max-age' => 3600,
  ],
];

$res = new ResourceResponse($response, 200);
$cache_metadata = CacheableMetadata::createFromRenderArray($build);
$res->addCacheableDependency($cache_metadata);

```

Response will be cache in one hour with url **/api/v1/get-list?\_format=josn**. When I use api **/api/v1/post-item** response of **/api/v1/get-list** will changed value. But response was cached in one hour. So how to trigger delete cache of url when use orther url. I find some code

```
\Drupal::service('page_cache_kill_switch')->trigger();

```

but just for current request.

# Answer
Add a cache tag to the response of **/api/v1/get-list**:

```
$build = [
  '#cache' => [
    'contexts' => ['url','url.query_args'],
    'max-age' => 3600,
    'tags' => ['api-v1-list'],
  ],
];

```

and then invalidate this tag in **/api/v1/post-item**:

```
\Drupal\Core\Cache\Cache::invalidateTags(['api-v1-list']);

```
> 2 votes

---
Tags: caching, 8
---


# Question
Title: How to display image preview right away for managed_file form element?
I have managed\_file for uploading an image in my form and I would like to display the image(thumbnail) right away when the user uploads it so he won' have to submit the form to see it(I am rendering it in the form if the image exists).

I think there might be an issue with the ajax wrapper/structure so I am not sure how exactly it should be achieved without too much customization/coding.

# Answer
This is my solution:

```
<?php

namespace Drupal\foo\Element;

use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Element\ManagedFile;

/**
 * @FormElement("managed_image")
 */
class ManagedImage extends ManagedFile {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $info = parent::getInfo();
    // @see \Drupal\image\Plugin\Field\FieldWidget\ImageWidget::formElement()
    $info['#accept'] = 'image/*';
    $info['#image_style'] = 'thumbnail';

    return $info;
  }

  /**
   * {@inheritdoc}
   */
  public static function processManagedFile(&$element, FormStateInterface $form_state, &$complete_form) {
    /** @var \Drupal\Core\Image\ImageFactory $image_factory */
    $image_factory = \Drupal::service('image.factory');
    $element['#upload_validators'] += [
      'file_validate_is_image' => [],
      'file_validate_extensions' => [implode(' ', $image_factory->getSupportedExtensions())]
    ];

    $element['#description'] = [
      '#theme' => 'file_upload_help',
      '#description' => isset($element['#description']) ? $element['#description'] : NULL,
      '#upload_validators' => $element['#upload_validators']
    ];

    return parent::processManagedFile($element, $form_state, $complete_form);
  }

  /**
   * {@inheritdoc}
   */
  public static function preRenderManagedFile($element) {
    $element = parent::preRenderManagedFile($element);

    if (!empty($element['#files'])) {
      foreach ($element['#files'] AS $delta => $file) {
        /** @var \Drupal\file\Entity\File $file */
        $element['file_' . $delta] = [
          'preview' => [
            '#type' => 'container',
            '#weight' => -10,
            '#attributes' => [
              'class' => [
                'image-preview'
              ]
            ],
            'image' => [
              '#theme' => 'image_style',
              '#style_name' => $element['#image_style'],
              '#uri' => $file->getFileUri()
            ]
          ]
        ] + $element['file_' . $delta];
      }
    }

    return $element;
  }

}

```
> 7 votes

---
Tags: forms, 8
---


# Question
Title: Send daily automated mails to specific roles programmatically
I'm working on a D8 project and I want to send every day an automated mail to all users with a specific role, lets say 'custom admin'. The mail should contain the results of a database query.

Rules module is not complete yet so I was thinking to use `hook_cron`.

Is this the right approach or is there a better way to achieve this?

Thank you in advance for any help/idea.

# Answer
Yes! hook\_cron is a good approach. Of course, you also will have to set up the server cron, which will trigger the Drupal one. Or at least that's the cleanest solution.

Here you can read how to configure cron.

If you don't use an OS cron to trigger, the following use case may appear. You set the Drupal cron to run each day at 00:00.

But nobody is browsing the site at 00:00. The next user will come at 6:54 in the morning. By the request the cron will know: oh.. it's 6:54, I should have run the cron at 00:00, so I will run it now.

If the subscribed modules have heavy processes on going, the request for the user could be slow. There is your module, which sending emails (not a big deal) but also the Drupal garbage collector (temporary files, abounded fields etc..) may run by this time. If this is the first extra cron hook of your site: don't mind it. It won't change much.
> 2 votes

# Answer
hook\_cron() will be the good option. Fetch the data from the database using some logic, create an email content and send it to the specific user role.
> 1 votes

---
Tags: 8, emails, cron
---


# Question
Title: Subscribe flag to auto-subscribe authors
I have set up a flag so that users can flag certain types of nodes and receive an email notification if there is any activity on it, such as comments. It's paired with the answers module. What I can't figure out how to do is make is so that authors are automatically subscribed to those types of nodes that they author. Other associated modules are message\_subscribe, flag\_actions, message\_subscribe\_email,

Using flags version 7.x-3.9. Let me know if I left out any pertinent information.

# Answer
For the Answers module (you know the dril: I'm a co-maintainer ...) to function, you must have the Rules module enabled also.

Therefor, have a look at this rule (in Rules export format, use the Rules UI to import it in your own site):

```
{ "rules_subscribe_question_author_automatically" : {
    "LABEL" : "Subscribe question author automatically",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "flag", "rules" ],
    "ON" : { "node_insert--answers_question" : { "bundle" : "answers_question" } },
    "DO" : [
      { "flag_flagnode" : {
          "flag" : "subscribe_answers_notifications",
          "node" : [ "node" ],
          "flagging_user" : [ "site:current-user" ],
          "permission_check" : "1"
        }
      },
      { "drupal_message" : { "message" : "You\u0027ve been subscribed to your own post automatically (use the unsubscribe link if that\u0027s not what you want)." } }
    ]
  }
}

```

For those who are not an expert in Rules-ese, this is what the above rule will do:

* Rules Event: after saving a new node of type "Question".
* Rules Actions:

+ flag that node by the user who created it, by the flag with machine name `subscribe_answers_notifications` (which by accident is exactly also what happens if a user manually clicks the "subscribe" link (below the question).
    + Show an informational message like "*You've been subscribed to your own post automatically (use the unsubscribe link if that's not what you want).*"

I think this Answers (oeps: *answers*) the question ... which was "***`... authors are automatically subscribed to those types of nodes that they author ...`***"

**Notes**:

* in case some author does not want to be subscribed to a question author by that author, it is still possible to use the ***`unsubscribe`*** link (typically bottom right below the question) after they created their question (node).
* the above rule only applies to nodes of type "Question", though with a minor improvement you could as well make it work for type "Answer".
> 2 votes

# Answer
The flag settings at `admin/structure/flags` allow you to specify, per flag, if you want to provide a checkbox on the node add form. Once that is selected, then within the content type settings that the flag is available for, you can specify a default for the checkbox to be selected or not.

This effectively automatically subscribes users to the content they are adding but also allows them to deselect it before they submit the node.

The only problem with this is if you have tried to disable the display of publishing settings in order to simplify the form for a block, it looks ugly.
> 0 votes

---
Tags: 7, flags
---


title: Responsive image styles

text:
# Question
Title: Responsive image styles
In /admin/config/media/responsive-image-style. I created a responsive image style. The breakpoints group is bartik so now I have 3 breakpoints. Wide, Narrow and Mobile. I want to use a new image style I created called small, its 80x80 scaled pixels. I set all 3 breakpoints to use small. But in Mobile I want the image to stretch a little maybe have it go from 120 wide to 80 wide. Is this possible? Does that make sense? If I select multiple image style under small this field appears `Enter the value for the sizes attribute, for example: (min-width:700px) 700px, 100vw.` What does this mean and where can I find some format examples?

# Answer
> 0 votes
> Is this possible?

Sure

> Does that make sense?

That depends on your design, not our opinions. ;)

You should create an image style for all variations of an image you can have. So if your default 'small' style is 80x80 and you want to use 120x80 as well, you should create a new image style 'small\_mobile'.

The purpose of the sizes attribute is explained in this change record:

> The sizes attribute tells the browser how much space this type of image will take up in the browser at various breakpoints. The image styles you select gives the browser multiple options to select an image source that is appropriately sized for the amount of space available at a particular breakpoint and screen resolution.

It is also explained in Drupal's built-in help system:

> **Sizes field**
>
> Once the sizes option is selected, you can let the browser know the size of this image in relation to the site layout, using the Sizes field. For a hero image that always fills the entire screen, you could simply enter 100vw, which means 100% of the viewport width. For an image that fills 90% of the screen for small viewports, but only fills 40% of the screen when the viewport is larger than 40em (typically 640px), you could enter "(min-width: 40em) 40vw, 90vw" in the Sizes field. The last item in the comma-separated list is the smallest viewport size: other items in the comma-separated list should have a media condition paired with an image width. Media conditions are similar to a media query, often a min-width paired with a viewport width using em or px units: e.g. (min-width: 640px) or (min-width: 40em). This is paired with the image width at that viewport size using px, em or vw units. The vw unit is viewport width and is used instead of a percentage because the percentage always refers to the width of the entire viewport.
>
> **Image styles for sizes**
>
> Below the Sizes field you can choose multiple image styles so the browser can choose the best image file size to fill the space defined in the Sizes field. Typically you will want to use image styles that resize your image to have options that range from the smallest px width possible for the space the image will appear in to the largest px width possible, with a variety of widths in between. You may want to provide image styles with widths that are 1.5x to 2x the space available in the layout to account for high resolution screens. Image styles can be defined on the Image styles page that is provided by the Image module.

Finally, if you always want to use 120x80 on mobiles, you can select a single image style.

# Answer
> 0 votes
Responsive Image Style: Here you can tell WHEN and WHAT STYLE to apply Image style: Here you can tell WHAT OPERATION should take place on the original image.

Create a new image style with scale & crop (or whatever fits you) first, and then set this image style to the right Responsive Image Style interval (in your case the smallest)

---
Tags: 8, theming
---