title: How do I translate menu link URIs?

text:
# Question
Title: How do I translate menu link URIs?
Is there a way to translate a menu link URI?

When I change it in one language (e.g. http://www.example.**com**), it is also changed in the other language, where I want a different domain (e.g. http://www.example.**de**).

Link title and description is working as expected.

# Answer
> 8 votes
It is not possible to translate the menu uri itself. If you want different menu links per language you need to create a unique menu per language, and use block visibility settings to limit each menu block to its respective language.

See this Drupal 8 multilingual hack for a step by step guide: build unique menus per languages

# Answer
> 3 votes
I faced a similar requirement. The best solution I found for myself on Drupal 8.5.x was Translatable menu link uri module. You just need to install and follow the steps mentioned in the module description.

# Answer
> 2 votes
Change the menu-link URL-alias as per the required language

for e.g.

I wanna products page URL in French =\> /produits and I wanna products page URL in Netherlands =\> /producten

than first create a menu and place the menu item in it =\> main menu \- products (menu item) /node/1 (menu link) URL-alias:- go to the URL alias and add the alias for French language =\> select the language French =\> IN System path "/node/1" =\> In Alias path "produits" Like wise for the Netherlands site =\> select the language Dutch =\> IN System path "/node/1" =\> In Alias path "/producten"

and the title of the link are being translatable from menus itself only

Note:- Enable this settings located at Configuration =\> "Content language and translation" enable the menu custom menu link,content,custom block and tick all the all their check boxes specially URL-alias in content.and don't forget to enable the Drupal 8 multilingual modules.

# Answer
> 1 votes
It is not currently possible to have language-specific external links. I created a module that addresses this issue. https://github.com/bbenjamin/Drupal-8---Multilingual-Menu-Links With this module, if users are translating a menu item, they are given the option of adding a language specific external link. If they choose this option, the default Name and Link fields are hidden, and replaced with language-specific fields.

# Answer
> 1 votes
A quite small module we used is Menu Multilingual:

> The Menu Multilingual module provides multilingual features for menu blocks, to filter out menu items that do not have translated labels or link to untranslated content.

You have to create a menu link for each language and on the configuration for the menu block you should activate both options:

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


# Question
Title: Custom 'required' field message ignored for file uploads
File upload fields in the D8 Webform module don't show my custom 'required' message when they fail validation.

Here's the YAML source of a simple Webform:

```
cv:
  '#type': managed_file
  '#title': CV
  '#required': true
  '#required_error': 'Please upload a copy of your CV.'
  '#file_extensions': 'doc docx pdf odt rtf'
test_document:
  '#type': document_file
  '#title': 'Test document'
  '#required': true
  '#required_error': 'Custom missing document file message.'
  '#format_items': comma

```

Instead of *Please upload a copy of your CV* etc., I get the default:

> CV field is required.
> Test document field is required.

I've run `drush webform:repair`
I've tested this on an otherwise empty form.
I've also cleared Drupal's cache.

Site setup:

Drupal 8.5.4.
No custom code yet.
(edit: we've since established it's nothing to do with contrib modules)

# Answer
The error message for managed\_file fields is added by ManagedFile::validateManagedFile \- it does not support `#required_error` \- the 'file missing' message (and others) are hardcoded:

```
  $form_state
      ->setError($element, t('@name field is required.', [
      '@name' => $element['#title'],
    ]));

```

**This is presumably because of the multiple types of error possible:**

* file does not exist
* file is "not referenced" (it exists but is "unmanaged" - i.e. orphaned as far as DB concerned - see function docs linked above)
* or, in our case, a file has not been uploaded at all

**Workaround:**

I bypassed this by adding my own validation to the form.

The Webform module has `hook_webform_submission_form_alter` \- you can use this to append your own validation method:

```
function mymodule_webform_submission_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    if ( $form['#webform_id'] != 'application' ) {
        // only do this for the specified form
        return;
    }

    $form['#validate'][] = 'mymodule_fix_webform_validation';
}

function mymodule_fix_webform_validation($form, &$form_state) {

    // grab all the existing errors
    $errors = $form_state->getErrors();

    if ( isset( $errors['cv'] ) &&
         $errors['cv']->getUntranslatedString() == '@name field is required.' ) {
         // if (a) there's an error for this field, and
         // (b) it's the correct TYPE of error

         // reconstruct the error message
         // (you might add translatable strings if you need them)
         $errors['cv']->__construct( 'Please upload a copy of your CV.' );
    }

}

```

(Decided to use the constructor from reading this answer to a similar question.)

**Things I tried first:**

The standard approach is to use $form\_state-\>setError() or setErrorByName() \- but neither appeared to have any effect on the error array - don't understand why.

On the actual form, the field was nested in a Webform "section"…

```
$form['elements']['uploads_section']['cv']

```

…so assumed I should supply the full array to setError(), for it to pull out the value of `#parents` and use that to construct the key. Except the error is actually stored as a flat 'cv' key, without the parent. Trying to set the 'cv' error using ByName didn't work either.

**Overriding strings:**

An alternative would be override the string (at time of writing, needs to be done programmatically: the string overrides module is not yet ready for D8). Add the following to `settings.php`:

```
$settings['locale_custom_strings_en'][''] = array(
    '@name field is required.' => 'Hello world!',
);

```

But this is a very broad brush and will apply to every file input on every form (plus anywhere else the phrase "*@name field is required.*" is used - you can't specify the `@name` placeholder).
> 1 votes

---
Tags: 8, webforms
---


title: display a view in admin theme

text:
# Question
Title: display a view in admin theme
I have a custom view for editing contents for the authors. When I'm logged in as a use with this author role this view is displayed with the 'frontend' theme. But I need it displayed in 'backend' theme.

I absolutely don't know how to get this view displayed in another theme.

# Answer
Go to Admin -\> People -\> Permissions & search **View the administration theme** check the checkbox for author role. Check screenshot below:
> 4 votes

# Answer
The ability to add "use admin theme" on a view will be available from 8.6, until then it's necessary to do some coding.

You must add a RouteSubscriber which goes through all the available routes until it finds the one (or more) you want to change, then add the '\_admin\_theme' = TRUE, option.

Use Drupal Console to add the RouteSubscriber (**drupal rs**) then insert the following code:

```
$admin_routes = ['view.example_page.page_1'];
foreach ($collection->all() as $name => $route) {
  if (in_array($name, $admin_routes)) {
    $route->setOption('_admin_route', TRUE);
  }
}
// or for a single route alter without a loop:
$route = $collection->get('view.view_id.display_id');
if ($route) {
  $route->setOption('_admin_route', TRUE);
}

```

And that's all you need.

More details here: https://www.computerminds.co.uk/drupal-code/drupal-8-views-how-set-admin-path
> 2 votes

# Answer
You can use themekey. This module allows you to define simple or sophisticated theme-switching rules which allow automatic selection of a theme depending on current path
> -2 votes

---
Tags: views, theming
---


# Question
Title: Different twig template for user profiles of different role
I would like to theme user profile pages differently based on the role but I can't figure it out how to do so.

I will need when someone is viewing an administrator profile this twig file to be loaded: user--administrator.html.twig

and when is viewing an editor profile this: user--editor.html.twig

Any idea how can I achieve this?

# Answer
> 4 votes
It can done by adding a hook theme suggestion based on roles in your `YOUR_THEME.theme` file

```
/**
 * Implements hook_theme_suggestions_user_alter().
 */
function YOUR_THEME_theme_suggestions_user_alter(array &$suggestions, array $variables) {
  foreach ($variables['elements']['#user']->getRoles() as $role) {
    $suggestions[] = 'user__' . $role;
  }
}

```

Then you can use templates like `user--administrator.html.twig`, `user--editor.html.twig`

---
Tags: 8, theming, users
---


title: How to edit vocabulary machine name?

text:
# Question
Title: How to edit vocabulary machine name?
I migrated my site from lower version of drupal, during migration process the machine name of my vocabularies was changed, now I want to modify them manually, but I cant find the proper table in database. now the question is :

> How can I edit vocabularies machine name manually?

# Answer
> 1 votes
Suppose that the machine name of your vocabulary is: **test**.

Then you can use the following code

```
$vid= 'test';

$vocabulary= taxonomy_vocabulary_load($vid);

$vocabulary->set('name', trim('newmachinename'));

$vocabulary->save();

```

> change the **newmachinename** by your machine name.

**Note**. you must be careful when using this code, because those configurations that you have with the previous machine name will be affected

# Answer
> 0 votes
```
// Create new vocabulary.
$vid = 'site_press_centre';
$name = 'News';
$vocabularies = \Drupal\taxonomy\Entity\Vocabulary::loadMultiple();
if (!isset($vocabularies[$vid])) {
  $vocabulary = \Drupal\taxonomy\Entity\Vocabulary::create(array(
        'vid' => $vid,
        'name' => $name,
  ));
  $vocabulary->save();
}

// Update current terms.
$vid_old = 'press_centre';
$query = \Drupal::entityQuery('taxonomy_term');
$query->condition('vid', $vid_old);
$tids = $query->execute();
foreach ($tids as $tid) {
    $term = \Drupal\taxonomy\Entity\Term::load($tid);
    if (!empty($term)) {
      $term->vid = $vid;
      $term->save();
    }
}

// Delete old vocabulary.
$vocabulary = \Drupal::entityTypeManager()->getStorage('taxonomy_vocabulary')->load($vid_old)->delete();

```

# Answer
> 0 votes
Just to round this question up, if you do have access to the migration YAML files, you can already set the new vocabulary names during the migration.

```
process:
  vid:
    -
      plugin: make_unique_entity_field
      source: machine_name
      entity_type: taxonomy_vocabulary
      field: vid
      length: 32
      migrated: true
    -
      plugin: forum_vocabulary
      machine_name: forums
    -
      plugin: static_map
      map:
        vocabulary_1: new_vocab_1
        vocabulary_2: new_vocab_2
        vocabulary_3: new_vocab_3
      bypass: TRUE

```

The last plugin in the chain allows you to rename machine names of vocabularies, in the above example, these are originally Drupal 6 names (vocabulary\_X) which where now transferred into proper vocab names.

The `bypass: TRUE` allows the migration to leave any other machine name that is not in the list to remain untouched. The opposite would be to set a default value, which will be returned instead if the name is not in the list.

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


# Question
Title: How can I render plain text as HTML in a template?
I've run into a wall trying to render a SVG image markup code into html from a plain text field.

I'm looking to render the SVG code from a plain text field without overriding the plain text field rendering everywhere else.

plain text format currently converts all HTML tags and \<\> to `< >`.

I created a field template and tried both outputting the field content as

```
{{ item.content.context.value }}

```

and

```
{{ item.content|raw }}

```

both render the value as string wrapping every line with "quotation marks" and converting line-breaks into `<br/>` tags.

I previously had the field type formatted text, but that also wrapped everything in `<pre>` tags, even when all tags were allowed. I'd really like to get it working with plain text.

Example of the svg-code the field has to hold in text form:

```
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         viewBox="0 0 290 290" enable-background="new 0 0 290 290" xml:space="preserve">
    <g>
        <path fill="none" stroke="#78C681" stroke-width="3" stroke-miterlimit="10" d="M261.1,273.1H28.9c-6.6,0-12-5.4-12-12V28.9
            c0-6.6,5.4-12,12-12h232.1c6.6,0,12,5.4,12,12v232.1C273.1,267.7,267.7,273.1,261.1,273.1z"/>
        <circle fill="none" stroke="#1B435D" stroke-width="2" stroke-miterlimit="10" cx="145.2" cy="166.9" r="62.7"/>
        <line fill="none" stroke="#78C681" stroke-width="3" stroke-miterlimit="10" x1="16.9" y1="60.8" x2="273.1" y2="60.8"/>
        <circle fill="none" stroke="#1B435D" stroke-width="2" stroke-miterlimit="10" cx="178.3" cy="152.3" r="6.8"/>
        <path fill="none" stroke="#1B435D" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M115.1,167.9
            c8.8,0,22.3,3.2,28.4,4.7"/>
        <path fill="none" stroke="#1B435D" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M151.9,216.9
            c0,0,17.2-1.5,29.6-14.8"/>
    </g>
</svg>

```

# Answer
> 23 votes
A solution by **iworkyon** from the Drupal community:

field--node--\[field name\].html.twig:

```
{% if svg %}
  <div class="my-svg">
    {{ svg|raw }}
  </div>
{% endif %}

```

MYTHEME.theme:

```
/**
* Implements hook_preprocess_field().
*/
function MYTHEME_preprocess_field(&$variables, $hook) {
    switch ($variables['element']['#field_name']) {
      case 'field_svg_test':
        $variables['svg'] = $variables['items'][0]['content']['#context']['value'];
        break;
    }
}

```

# Answer
> 16 votes
This worked for me:

```
{{ item.content['#context'].value|raw }}

```

# Answer
> 9 votes
Did you try to apply the raw filter on the value?

```
{{ item.content.context.value|raw }}

```

But this is not secure. To output files, you can use a file field. This has the correct field formatters to generate the link. If you are not able to configure the link in the ui to your needs, you can modify the twig or preprocess for this specific field.

---
Tags: 8, theming
---


title: Convert boolean field to custom style

text:
# Question
Title: Convert boolean field to custom style
I have a **`Boolean`** field with **`Yes/No`** values with default style of Drupal .

I want to change that field to **`ON`** and **`OFF`** toggle style like below .

I understand that it can be done using the **`bootstrap`** theme and the bootstrap toggle module. But I don't need to change my theme. How can I do that ?

# Answer
A quick look at the bootstrap toggle JavaScript code does not show any actual dependencies in it for the actual bootstrap theme. You may be able to install the bootstrap\_toggle module without the Bootstrap theme and it will work.

Won't hurt to try on a dev environment. :)
> 1 votes

---
Tags: 8, entities, theming
---


# Question
Title: Hide blocks from the administration page according to the user role
Is there a way that certain roles can only manipulate blocks that are assigned to them?

That is, if a user with an a editor role enters to `"admin/structure/block"`, I just want you to see and be able to manipulate the blocks that I define, the rest of the blocks must remain hidden for this user / role.

Is this possible to do?.

# Answer
To make this work, you will need a custom page, the "admin / structure / block" won't do the work.
> 0 votes

---
Tags: 7, blocks
---


# Question
Title: Not able to connect to remote database after migration
I am moving a running site from staging to production. The production environment has 2 servers, one for frontend and the other for the database.

The issue is when I try to browse the website, I get this error

> PDOException SQLSTATE\[HY000\] \[2002\] Permission denied in \[ROOT\]/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php on line 79

The real problem is I am sure that the database connection is set right. Permissions and ports are set right.

I tried the same database connection info from an external PHP file on the same server and I got successfully connected.

Also, I tried `drush st` and it told me that database status is Connected, and Drupal bootstrap status is Success.

Even tried `drush sqlc` and I got connected to the remote database. I can list tables, execute queries, etc.

Any ideas what might be the problem?

# Answer
In case you're using SELinux see this article.

> setsebool -P httpd\_can\_network\_connect 1
>
> setsebool -P httpd\_can\_network\_connect\_db 1
> 1 votes

# Answer
Wild guess- I saw that error after making some changes to my MAMP environment (specifically, I upgraded MAMP Pro). It turned out that the server was using one version of PHP, and the CLI (e.g., DRUSH) was using another. When I got one to work, the other would fail.

When I got both environments using the same PHP version, the issue was resolved.
> 0 votes

# Answer
In the `sites/default/settings.php` file, change the value of `host` key from `localhost` to `127.0.0.1`.

**Code sample**

```
$databases['default']['default'] = array (
  'database' => 'foo',
  ...
  'host' => '127.0.0.1',
);

```
> -2 votes

---
Tags: 8, database
---


# Question
Title: How to translate a custom module template file?
How do I translate a custom module theme file?

```
function bonds_graph_theme($existing, $type, $theme, $path)
{
    $items = array();

    $items[BONDS_GRAPH_MODULE_NAME] = array(
   'arguments' => array(),
   'file' => 'inc/theme.inc',
   'template' => 'tpl/bonds_graph',
 );

return $items;
}

```

The theme file has a translatable string

```
<?php print date('Y') . ' ' . t('Issuance'); ?>

```

The language file zh-hans.po has the translation

```
#: tpl/bonds_graph.tpl.php:7
msgid "Issuance"
msgstr "发行"

```

The site language is set. How do I get the string translated?

# Answer
The .po file must be located in `custom_module/translations` directory - see locale\_batch\_by\_component function. Translation file though is only imported once module gets installed, so in case you want to reimport the file you would have to run some "hacky" drush command, such as `drush php-eval "locale_system_update(array('custom_module'));drush_backend_batch_process();"`

You can also upload .po file manually using Drupal's admin UI.
> 4 votes

---
Tags: i18n-l10n
---


# Question
Title: Embed a view into a Webform for submission
I have the following set up on a D8 install using the Flag, Views and Webform modules:

* A content type named Product with a Flag field that can be set to "Add product to quote" or "Remove product from quote".
* A view named "My Quote" that displays all products Flagged with "Add product to quote".
* A Webform named "Get Quote" set up to capture the client's name, email, address, etc.
* I now need to add the the view for "My Quote" to the Webform in some way.

I see in D7 there was a module called Webform View that provided similar functionality to what I'm looking for. If I understand the Webform Computed Elements correctly there should be a way to do this using Twig or Tokens, but I have no idea how to get the View data using either method.

I would be very grateful if someone could point me in the right direction, or help me understand the Twig syntax for referencing a View so I can use it in my Weform.

# Answer
To embed a View in a Webform, you can use the View element.

Below is the YAML for how you would embed the Frontpage view into a Webform.

```
frontpage:
  '#type': view
  '#name': frontpage

```

@see \Drupal\views\Element\View
> 3 votes

---
Tags: views, 8, webforms
---


# Question
Title: Rules module doesn't send emails to user roles once conditions are met
I'm working in drupal 7 and I've configured the rules module to send emails you specific user roles when content is created. For some reason I'm getting inconsistent results, sometimes not receiving any emails. Any insight to why rules isn't generating emails would be helpful.

Here's my Rule:

```
{ "rules_announcements" : {
    "LABEL" : "Announcements",
    "PLUGIN" : "reaction rule",
    "WEIGHT" : "10",
    "OWNER" : "rules",
    "TAGS" : [ "announcements" ],
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_insert--announcements" : { "bundle" : "announcements" } },
    "IF" : [
      { "node_is_of_type" : {
          "node" : [ "node" ],
          "type" : { "value" : { "announcements" : "announcements" } }
        }
      }
    ],
    "DO" : [
      { "mail_to_users_of_role" : {
          "roles" : { "value" : { "5" : "5", "4" : "4" } },
          "subject" : "Announcements: [node:title]",
          "message" : "\u003Cp\u003E[node:title]\u003C\/p\u003E\r\n\u003Cp\u003E[node:field_announcement]\u003C\/p\u003E\r\n\u003Cp\u003E[node:body]\u003C\/p\u003E\r\n\u003Cp\u003E[node:url]\u003C\/p\u003E",
          "from" : "[site:mail]"
        }
      }
    ]
  }
}

```

# Answer
Attempt to answer this part of your question:

> Any insight to why rules isn't generating emails would be helpful.

I doubt that Rules is the culprit ... and that it is rather something in actually sending the eMails. To verify this, just add a Rules Action to "Show a message" (as the very first Rules Action), and with actual content something similar to the subject / message body as what you have already in the Rules Action to send an eMail. Pretty sure that each time you'll get such extra message shown on your site. If it does indeed, you found a confirmation that there is nothing wrong with your rule itself.

However, just looking at the subject / message body of the eMail you want Rules to send: make sure to also verify that all those tokens (such as `node:field_announcement`) are available (not blank).

PS: a completely different explanation might be related to your event "after saving content", whereas the saving actually happens ... "before saving content". To verify if that's what your issue is about, replace your Rules Action by an appropriate Rules Component (which does the same thing), and actually "schedule" that Rules Component (using the rules Scheduler) to run after just a few seconds or minutes (at that time, for sure the save will have been completed).
> 1 votes

---
Tags: rules, emails
---


# Question
Title: Get relationships between tables when no foreign keys are present
How can tell the relationships between tables when no FKs are being used?

Just started working on a (partial) data export from Drupal MySQL database with ~1000 tables that contains hardly any foreign keys. Forgive my ignorance but I don't even know whether this is standard modus operandi in Drupal or some sort of anomaly. I have been expecting FKs as on most RDBS that I ever worked on FKs were present.

*Entity API* is being used extensively and so is data versionning if that makes any difference.

I know I could capture all the SQL queries hitting the database at runtime and then, assuming all the queries were run, I could tell how joins are made.

But looking for simpler way to tell relationships between tables similar to the one below.

# Answer
You have 3 possible options, but you most likely want to start with #2 and combine it with #3.

1. Use php to print out the Entity Metadata Wrapper for various nodes objects of different types.
2. Use the Devel Module and view the Node object
3. Use Views

If the Entity definitions were properly implemented (a huge IF) it is possible to print out the relationships using entity\_metadata\_wrapper from php. You can even write it out to a file from command line using Drush but this will take some advanced skills. However, this typically results in tens of thousands of lines, an overwhelming amount of information, with many circular references.

Using the Devel Module will be much easier as you can simply click down into what the Node object is presenting. This may not show all the fields if they aren't filled out so you will want to create a test Node of each type with data in each field. If filled properly this may help relate structures when looking at the raw MySQL data as well.

Using Views, Drupal's built in query builder, will help you either understand the schema or just export it by adding the Views Data Export module. You will want to start from a perspective of particular Node type (a content type). Each Node type will show fields it can access and you should be able to build the queries from there. You may need to add Relationships (joins) to get all the data depending on how the developers built the system, its hard to say. Drupal will limit you to only the tables that are defined with Relationships.

You can see the MySQL Queries you are building at the bottom of the page if Show the SQL Queries is enabled in the Views settings tab (/admin/structure/views/settings).
> 3 votes

---
Tags: 7, entities, database
---


# Question
Title: How to restrict a field choice allowing only one to be populated?
On a basic page I have two similar fields. One for an image and the other for a video.

Either can be populated, but preferably not both, as I don't not want two fields to be displayed on the front end. I also want consistency across multiple view modes with only one being displayed in teasers etc

This trouble is, some editors do not appreciate the reasons and populate both fields, so I need to method for limiting this.

With D7 I found a good solution by using Conditional Fields module. By using a select list (for the file type). the corresponding field input would be exposed in the admin and the same field would be displayed on the frontend. Even if both fields were populated, only the current selection would display.

The D8 version of conditional\_fields does not yet have this functionality, and may not get it. See my issue

I am therefore looking for an alternative method and hoped one of the experts here might some suggestions. I am looking for something simple and could not consider anything unsuitable for an untrained editor.

# Answer
> A bit confusing because it is rare for me to attempt any coding.

For this example I will pretend the content type is "Article".

First go to manage fields, and add a new field of **list (text)** to your content type. Let's say the possible values are "video" and "image". So For *allowed values list*, put

```
image|image
video|video

```

In /themes/your\_theme\_name/**your\_theme\_name.theme** add the following

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function your_theme_name_form_node_article_edit_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id) {
  $form['field_image']['#states'] = [
    'visible' => [
      'select[name="field_select"]' => ['value' => 'image']
    ]
  ];
  $form['field_video']['#states'] = [
     'visible' => [
       'select[name="field_select"]' => ['value' => 'video']
    ]
  ];
}

```
* Replace `your_theme_name` with your actual theme name.
* Replace `article` with your actual content type name.
* Replace `field_select` with the machine name of your select field.
* Replace `field_image` with the machine name of your image field.
* Replace `field_video` with the machine name of your video field.

**Lastly, clear and flush all cache to see changes.**

Source: Drupal 8 - Conditionally hide a form field
> 0 votes

---
Tags: 8, entities
---


title: Control access to buy products

text:
# Question
Title: Control access to buy products
We would like to be able to restrict access to *buy* products.

* A product could be members-only
* Users who are already members should be prevented from buying membership again until near expiry.

If there is no access to buy, the "add to cart" button should not be shown. There also needs to be a check during checkout, for example in case the a member added a membership to the cart as anonymous then logged in, they still should not be able to buy membership.

We don't want to restrict access to *view* products. Non-members should be able to see the benefits of membership, and what extra things they could buy. The price should still be visible for products that cannot be bought (so we can't hide the entire "Add to Cart" form as that's where the price comes from).

Please can someone explain how to achieve this?

# Answer
I believe that good start is to implement EventSubscriber listening on ProductEvents::FILTER\_VARIATIONS event. It was introduced to filter out some product variations based on different aspects, such as stock, date, etc.
> 2 votes

---
Tags: 8, commerce
---


# Question
Title: How to hook payment created on commerce 2
I use commerce to create a bakery. Unfortunately, there is no module to pay by check or cash. So I use the payment example "manual". I need to debit the user account when a payment is entered (a "balance" field has been created on the user account). Is there a hook when a payment is created so that I can do this operation on the user entity?

# Answer
> 0 votes
One option would be to use hook\_entity\_create() but I would rather react on Order transition event, such as `commerce_order.place.post_transition` which is triggered when Order reaches Completed state.

---
Tags: commerce, payment-gateways
---


# Question
Title: Need to convert datetime to date during D8 migration from non-drupal source
I'm working on a migration where I have

2012-05-07 00:00:00.000000

in my timedate field, but I need to convert it to:

2012-05-07

I realize that I should put this in the prepareRow function, but I'm not sure what it should look like.

# Answer
> 1 votes
```
public function prepareRow(Row $row) {

   $date = $row->getSourceProperty('database_date_field');
   $date = strtotime($date); // -> 1336341600 unix timestamp
   $date = date('Y-m-d', $date); // -> "2012-05-07"

   // Here you 'rewrite' the field with the new value before it gets saved
   $row->setSourceProperty('database_date_field', $date);
   return parent::prepareRow($row);
}

```

# Answer
> 1 votes
Why not use a format\_date process plugin:

```
process:
  field_my_date:
    plugin: format_date
    from_format: 'Y-m-d H:i:s'
    to_format: 'Y-m-d'

```

# Answer
> 0 votes
If the source property containing that value is, say, "timestamp", then in prepareRow you can do:

```
$row->setSourceProperty('timestamp', strtok($row->getSourceProperty('timestamp'), ' '));

```

---
Tags: migrations
---


title: how to print html code

text:
# Question
Title: how to print html code
Could you please help me, i'm trying to print a block of html code.

Im using a template file wid.tpl.php i need to pass some variables:

```
$htmlget = theme('wid',array('id'=> $id,'temp'=> $temp,'game'=> $game));

```

and this is my code on that file:

```
<?php
$list = get_defined_vars();
$idcompetition=$list['idcompetition'];
$temporada=$list['temporada'];
$idgame=$list['idgame'];

print "<style>
.Opta h2{background-color: #ff191e !important;}
</style>
<link rel='stylesheet' href='https://secure.widget.cloud.opta.net/v3/css/v3.football.opta-widgets.css'>
<script src='https://secure.widget.cloud.opta.net/v3/v3.opta-widgets.js'></script>
<script>
    var opta_settings = {
    subscription_id: 'bccfa17c076140fd251fc5edc10c4dc6',
    language: 'es_CO',
    timezone: 'America/Mexico_City'
    };
</script>
 <div id='container-opta-all-widget'>
        <opta-widget competition=". $idcompetition." season=". $temporada." match=". $idgame."></opta-widget>
</div>";
?>

```

but i need run that javascripts files `v3.opta-widgets.js` and that between `<script>` tags to add somethings to `container-opta-all-widget` tag

how can i do that

# Answer
You should preprocess the template itself in template.php, and call `drupal_add_js` to add inline JS like that when you need it.

https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal\_add\_js/7.x

You can do the same with `drupal_add_css` too.

HTML code does not need to go within `<?php ?>` tags. Just write it as normal and inject your variables like `<?php print $variable; ?>`.
> 0 votes

---
Tags: theming
---


# Question
Title: Serve Anonymous Pages when users are logged in for some pages
so essentially I have a Drupal website with great performance for anonymous users and terrible performance for logged in users.

What I am looking for is a way to serve some pages that logged in users access as if they were an anonymous user.

In custom development this would be done using a:

```
cache-control:public

```

header for varnish, but obviously when viewing that page anything such as the users profile information and the login status must not be shown so its not cached in varnish.

I was hoping there would be a config change or module that could perform this without having to write a custom module,

any ideas would be greatly appreciated

# Answer
> 0 votes
You may implement ESI block caching.

Have a look at ESI module and varnish basic tutorial. You would be able then to cache whole pages except the blocks with session data.

Additionally, @Kevin comment points a complementary way: using **Redis** or **Memcache** will substantially speed the pages when logged, by *caching data and objects in server memory* to reduce the number of times the data source must be read.

---
Tags: caching, performance, proxies
---


title: Adding a file download link to a node

text:
# Question
Title: Adding a file download link to a node
I have a content type `recipe` and for each recipe type content I want to add a link which can download the recipe for the user.

How can this be done in Drupal 8.5.2?

I'm not sure if I should provide a field to attach the file or if it should be done in some other way like creating a template adding the values to it dynamically and then generating a PDF for the template and attaching a download link for it.

# Answer
It sounds that you should be able to implement what you want like so:

* Add a custom field to your `recipe`, assume you use a machine name like "`file-containing-recipe`" (change this name to whatever fits).
* For the `file-containing-recipe` field, specify a field type "*file*", and combine it with whatever other configuration options that fit (eg: single value or multiple values, optional or mandatory, etc).

To verify your configuration, create a node of content type `recipe`, and use the newly defined "`file-containing-recipe`"-field to actually attach your file(s). After saving the new node, verify if the results are what you're asking for. If (still) not, go back to your "`file-containing-recipe`"-configuration to further tune any of its settings.

***Done***.
> 0 votes

---
Tags: 8, nodes, files
---


# Question
Title: Can't migrate alias with Wordpress Migration
I am using the Wordpress Module to migrate from Wordpress to Drupal 8. I am trying to have the alias be set to the link value (`<link>https://myurl.com/wordpress-path</link>`). I added the following to the source:

```
    -
      name: link
      label: 'The link value'
      selector: 'link'

```

and the following to process:

```
  path/pathauto:
    plugin: default_value
    default_value: 0
  alias:
    -
      plugin: get
      source: link
    -
      plugin: str_replace
      source: link
      search: 'https://myurl.com/'
      replace: '/'

```

I have also tried `path/alias` and `path` instead of `alias` but no luck. I verified that the str\_replace plugin does return the correct value but somehow it does not save in the node.

Here is my full migrate\_plus.migration.my\_wordpress\_wordpress\_content\_post.yml:

```
uuid: 5b3b3b84-8d41-4a80-b1ca-c9046c269297
langcode: en
status: true
dependencies: {  }
id: wp_wordpress_wordpress_content_page
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags:
  - WordPress
migration_group: wp_wordpress
label: 'Import content from WordPress XML'
source:
  plugin: url
  data_fetcher_plugin: http
  data_parser_plugin: xml
  item_selector: '/rss/channel/item[wp:post_type="page"]'
  fields:
    -
      name: title
      label: 'Content title'
      selector: title
    -
      name: post_id
      label: 'Unique content ID'
      selector: 'wp:post_id'
    -
      name: content
      label: 'Body of the content'
      selector: 'content:encoded'
    -
      name: excerpt
      label: 'Excerpt of the content'
      selector: 'excerpt:encoded'
    -
      name: pubDate
      label: 'Publish date of the content'
      selector: pubDate
    -
      name: post_date
      label: 'Post date of the content'
      selector: 'wp:post_date'
    -
      name: status
      label: 'Published status of the content'
      selector: 'wp:status'
    -
      name: creator
      label: 'Username of the content creator'
      selector: 'dc:creator'
    -
      name: post_tag
      label: 'Tags assigned to the content item'
      selector: 'category[@domain="post_tag"]/@nicename'
    -
      name: category
      label: 'Categories assigned to the content item'
      selector: 'category[@domain="category"]/@nicename'
    -
      name: link
      label: 'The link value'
      selector: 'link'
  ids:
    post_id:
      type: integer
process:
  title:
    -
      plugin: get
      source: title
  body/value:
    -
      plugin: get
      source: content
  body/summary:
    -
      plugin: get
      source: excerpt
  created:
    -
      plugin: callback
      source: post_date
      callable: strtotime
  changed:
    -
      plugin: get
      source: '@created'
  status:
    -
      plugin: static_map
      source: status
      default_value: 0
      map:
        publish: 1
  uid:
    plugin: migration
    migration: wp_wordpress_wordpress_authors
    source: creator
  body/format:
    plugin: default_value
    default_value: basic_html
  type:
    plugin: default_value
    default_value: page
  path/pathauto:
    plugin: default_value
    default_value: 0
  alias:
    -
      plugin: get
      source: link
    -
      plugin: str_replace
      source: link
      search: 'https://myurl.com/'
      replace: '/'
destination:
  plugin: 'entity:node'
migration_dependencies:
  required:
    - wp_wordpress_wordpress_authors

```

# Answer
> 1 votes
Turns out `path/alias` worked. I must have been doing something wrong or my page was cached that it wasn't redirecting to the alias.

```
path/alias:
  -
    plugin: get
    source: link
  -
    plugin: str_replace
    source: link
    search: 'https://myurl.com/'
    replace: '/'

```

---
Tags: migrations, path-aliases
---


# Question
Title: Patch for module applies with patch command but not composer
I have encountered a weird issue in which a patch I rolled for Commerce does not apply with Composer; it gives no errors, but the patch is not actually applied.

```
  "extra": {
    "patches": {
      "drupal/commerce" : {
        "Allow order types to have no cart": "https://www.drupal.org/files/issues/commerce-direct-checkout-2.2-2810723-37.patch"
      },

```

However, the same patch applies correctly after downloading and using the `patch` command:

```
/web/modules/contrib/commerce$ patch -p1 < ../../../../patches/commerce-direct-checkout-2.2-2810723-37.patch
patching file modules/cart/src/Form/AddToCartForm.php
patching file modules/cart/tests/src/Functional/AddToCartFormTest.php
patching file modules/cart/tests/src/Functional/CartBrowserTestBase.php
patching file modules/product/config/schema/commerce_product.schema.yml
patching file modules/product/src/Plugin/Field/FieldFormatter/AddToCartFormatter.php
patching file modules/product/src/ProductLazyBuilders.php

```

What is wrong with my patch that makes it fail in Composer?

# Answer
> 3 votes
It turns out this is an issue with Drupal patches for composer when using an older version of Git. The problem is with composer-patches 1.6.3.

Three possible solutions for now until the bug gets fixed.

**Force 1.6.2**

In `composer.json`, specify 1.6.2:

```
"require": {
"composer/installers": "^1.0.20",
"cweagans/composer-patches": "1.6.2",

```

**Force git clone with 1.6.3**

In `composer.json`, instead of "dist", use "source":

```
"config": {
    "preferred-install": "source"
  },

```

**Update git to the latest version**

# Answer
> 1 votes
The above didn't work for me but I debugged this issue by running composer install -v for verbosity.

It will show you, for example that it is running the command

```
patch '-p1' --no-backup-if-mismatch -d 'web/core' < '/my/path/to/patch.patch'

```

I believe the -d indicates that we are running the patch from the web/core directory. When I look at this patch it looked like:

```
diff --git a/web/core/modules/quickedit/js/quickedit.js b/web/core/modules/quickedit/js/quickedit.js
index 4548c013a..f930746b3 100644
--- a/web/core/modules/quickedit/js/quickedit.js
+++ b/web/core/modules/quickedit/js/quickedit.js
@@ -170,7 +170,10 @@
   // code here

```

The a/b indicates the location of the files to patch. Since we are already in the web/core folder, it cannot find the web/core directory inside there and so fails. If we edit those two lines without that in there, it worked. ie

```
diff --git a/web/core/modules/quickedit/js/quickedit.js b/web/core/modules/quickedit/js/quickedit.js
index 4548c013a..f930746b3 100644
--- a/modules/quickedit/js/quickedit.js
+++ b/modules/quickedit/js/quickedit.js
@@ -170,7 +170,10 @@
// code here

```

---
Tags: composer
---


title: Different content in a block per page

text:
# Question
Title: Different content in a block per page
I'm using Drupal 8. I have a content type of “course”. Each course should have a “Banner” block in it that we can upload different background images to (per course).

I've created a “custom block type” of Banner and in this block type I have fields for “desktop image file”, “tablet image file” etc. I then created a “block” called Banner that uses this “custom block type" of Banner. Then, I added the block to the top of the “Content region” and set it to display for the course content type only. I can then see the block on the course pages. So far so good...

However, if I alter the text in the block, it changes the text on all pages... how do I configure it so that I can change the text and images I upload per course/page? Thanks in advance! (Hoping the answer doesn't involve installing extra modules).

# Answer
The trouble with this approach is that there are block definitions and block instances. A block definition is the code or custom block that defines the block's behavior.

A block instance is what you create when you place a block onto your theme and defined its settings (e.g. nodes to display it on, values for custom fields).

To have different banners for each class using this method you would need to create a different block instance for each class. (and set the display rules appropriately).

To use a single block, you will need to define a location outside the block that has the needed information. Probably on your course page. Then you can use either a view block as mentioned in the comments or write a custom block to pull the info. If it is only needed on the main course page, you could probably just use a custom content type twig file and add it when the page is rendered.

If you need the block on subpages, e.g. secondary pages of a course, you will probably have to write a custom block that knows how to relate the subpage to the main course page. E.g. get the course information from a course entity reference field on the subpage and then get the banner info from the main course page).

Note that with both views and custom blocks, you will need to define the cache tags appropriately so that the content is cached per page and not overall.
> 0 votes

---
Tags: blocks
---


# Question
Title: Programmatically set date fields in Drupal 7: Date, Date (ISO Format) and Date (Unix Timestamp)
Using the Form API and hook\_form\_alter(), how can I manually set (force) the values for each of Drupal 7's date field types using a valid Unix Timestamp?

When the form is finally submit the field\_date types are always empty arrays. Below is the broken code I'm working from.

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

    // http://drupal.org/node/1455576 - Date
    $form['field_date'][LANGUAGE_NONE][0]['value'] = time();

    // http://drupal.org/node/1455576 - Date (ISO Format)
    $form['field_date_iso_format'][LANGUAGE_NONE][0]['value'] = time();

    // http://drupal.org/node/1455576 - Date (Unix Timestamp)
    $form['field_date_unix_timestamp'][LANGUAGE_NONE][0]['value'] =time();
}

```

I should mention the fields widget is set to text and it's format is 'Y-m-d H:i:s'

I have also tried `date('Y-m-d H:i:s', time())` instead of `time()`.

Example dpm() output.

I should also note that as a workaround I can set the field if I modify it in hook\_node\_presave(). To do this I set `$node->field_date['und'][0]['value'] = date('Y-m-d H:i:s', $my_unix_timestamp);` I would still like to understand how to do this using hook\_form\_alter instead.

# Answer
Here is a code that treat site timezone right for me:

```
 $node->field_date[LANGUAGE_NONE][0] = array(
    'value' => format_date(strtotime('now'), 'custom', 'Y-m-d H:i:s', 'UTC'),
    'timezone' => 'UTC',
    'timezone_db' => 'UTC',
  );

```
> 15 votes

# Answer
Each date field-type is expecting a differently formatted timestamp (based on how it's stored in the DataBase):

```
// For datetime
$node->field_datetest[$node->language][0]['value'] = "2011-05-25 10:35:58";

// For date
$node->field_datetest[$node->language][0]['value'] = "2011-05-25T10:35:58";

// For datestamp
$node->field_datetest[$node->language][0]['value'] = strtotime("2011-05-25 10:35:58");

```

> Note that you don't need to specify a complete date; for datetime and date you can just pad with zeros, e.g. "2011-05-00 00:00:00" (datetime), "2011-00-00T00:00:00" (date), etc. For datestamp you could just do e.g. strtotime("2011-05-25").
>
> **Important:** Also note that while the exact value you specify will be stored in the database, the actual time displayed on the site might be different depending on timezone settings. When you create a new datetime/date/datestamp field, you get to choose between five different timezone handling methods. The default one is "site's time zone":
>
> When entering data into the field, the data entered is assumed to be in the site's time zone. When the data is saved to the database, it is converted to UTC. However, if you set a date field programmatically like in the above example then no conversion takes place, so make sure you account for the field's timezone settings. Or in other words, if you use "site's time zone", make sure the time is in UTC.

This information was referenced from the section labeled Date field (datetime, date, datestamp) on fooninja's blog.

This is also a great general resource for programmatic node creation in Drupal 7.
> 6 votes

# Answer
This worked for me.

```
$node->field_date[LANGUAGE_NONE][0] = array(
      'value' => date('Y-m-d H:i:s', strtotime('now')),
      'timezone' => 'UTC',
      'timezone_db' => 'UTC',
);

```
> 5 votes

# Answer
The `time()` value will not work at this level.

You have to use something like :

```
$mydate = date('Y-m-d', strtotime('31 May 2011'));

```
> 2 votes

# Answer
For Date stuff we could write a js for getting the current date...

```
jQuery(document).ready(function() {

    var fullDate = new Date()
    var HR_fullDate = fullDate.toDateString().toString().substring(4,15);
    jQuery('strong.date').contents().replaceWith(HR_fullDate);

});

```
> 2 votes

# Answer
If you're using field type `Date (ISO format)` then use:

```
$node->field_datetest[$node->language][0][value] = "2011-05-25T10:35";

```
> 1 votes

# Answer
Try this:

```
$now = date_now('UTC');
$now = date_format($now, "Y-m-d H:i:s");

```
> 1 votes

# Answer
For those dealing with $form\_state and popup widget:

```
// The date format in this sample is dd/mm/yyyy
$form_state['values']['field_my_date_field']['und'][0]['value']['date'] = '14/05/2014';

```
> 1 votes

# Answer
To set a value to a date field follow below codes.

Using hook\_form\_alter

> $form\["field\_date"\]\["und"\]\[0\]\['#default\_value'\]\['value'\] = $new\_date;

Using hook\_node\_submit or hook\_node\_presave (Saving the value to the database)

```
 function MY_MODULE_node_presave($node)
  {
      $node->field_date['und'][0]['value'] =  '2014-09-23 00:00:00';
  }

```

Or if you need to save value of one custom field(defined in hook\_form\_alter) to another, see below codes.

```
function MY_MODULE_node_submit($node, $form, &$form_state) {
  if($node->type == 'my_node_type') {
    $test_date =  $form['test_date ']['#value'];
    //Ensure that $test_date format is '2014-09-23 00:00:00'
    $node->field_date['und'][0]['value'] =  $test_date ;
   }
}

```
> 1 votes

# Answer
The accepted answer was giving me a PDO Exception. Only a simple time() call worked for a "datestamp" field!

```
        $entity->field_upload_time["und"][0]["value"] = time();

```
> 1 votes

# Answer
used time() and worked OK....

$fc\_item\_wrapper-\>field\_data\_pedido-\>set(time());
> -1 votes

---
Tags: 7, datetime
---


# Question
Title: How do I check if a module is being used by another?
I'm using a multi-site setup with Drupal 7.14 core, and I want to disable some modules within my sites/all/modules shared folder. One of them in particular is the File\_Entity module.

Is there a way (drush, programmatically, bash script, etc) to check if another module (e.g. Views, custom CCK) is using it? `drush pml | grep File Entity` only let me see what is enabled or disabled, not if it is currently in use, or safe to remove.

# Answer
> 4 votes
```
drush pm-info mymodule|grep "Required by"

```

grep or don't grep is up to you ;)

Beware this does not list fields that require the module. This implies to views that use fields too.

```
fields: admin/reports/fields

views: admin/reports/fields/views-fields

```

those will list fields only, so if you have special pagers, formatters or something else that come from a module you will still have to search for them.

# Answer
> 1 votes
There is no `drush pm-info` command in Drush 9.3, it was replaced `pm:list`.

(https://github.com/drush-ops/drush/issues/3487, https://github.com/drush-ops/drush/issues/5557)

But now there is no `Required by` field in a field list
(see FIELDS section in `drush pm:list --help`)

Current workaround is just open `/admin/modules` page and look for `Required by`,
or use some php code if you have access to the drush.

```
drush ev '$module = "views"; $modules = _system_rebuild_module_data(); \Drupal::moduleHandler()->buildModuleDependencies($modules); var_dump($modules[$module]->required_by);'

```

**UPD**: Drupal 9 version:

```
# Dependencies of the module
drush ev '$module = "views"; $modules = \Drupal::service("extension.list.module")->getList(); echo implode(array_keys($modules[$module]->requires),", ");'
# Dependencies to the module
drush ev '$module = "views"; $modules = \Drupal::service("extension.list.module")->getList(); echo implode(array_keys($modules[$module]->required_by),", ");'

```

**NOTE**: be worried with php code, may cause performance issues.

---
Tags: drush, files
---


title: unserialize() return empty

text:
# Question
Title: unserialize() return empty
I have a variable that holds a serialized string that I want to convert back into a PHP Array.

```
$str = 'a:1:{i:0;a:3:{s:2:"id";s:24:"xxxxxxxxxxxxxxxxxxxxxxxx";s:11:"description";s:3:"Two";s:9:"users-idt";s:36:"x6543rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrd";}}';
$arr = unserialize($str) // returns an empty;

```

But when I take the same string an run unserialize() on it outside Drupal, it works perfectly. Could this be a drupal issue?,

Using Drupal 7

# Answer
Cant see how it could be drupal, how are you determining that its returning empty? Are you doing a

```
var_dump($arr); die;

```

directly after your code?
> 0 votes

---
Tags: hooks
---


# Question
Title: Is there a way to strip identifying data from commerce tables?
I am interested in stripping personal addresses out of the commerce\_customer\_profile and commerce\_customer\_profile\_revisions database tables to sanitize the database for development purposes.

The site is using Drupal 7 and Drupal Commerce 7.x-1.13.

Has anyone come up with a way to do this?

# Answer
> 1 votes
There's nothing special about sanitizing Commerce. When I sanitize the db, I simply delete all the info in SQL:

```
TRUNCATE TABLE commerce_customer_profile;
TRUNCATE TABLE commerce_customer_profile_revision;
TRUNCATE TABLE field_data_commerce_customer_address;
TRUNCATE TABLE field_revision_commerce_customer_address;
TRUNCATE TABLE field_data_commerce_customer_billing;
TRUNCATE TABLE field_revision_commerce_customer_billing;

```

**NOTE: This is just an example. You need to check your database and make sure you get all the relevant tables.**

If you want to use dummy data instead of deleting the data outright, you can use a statement like this:

```
UPDATE users SET users.name = users.uid WHERE users.uid > 0;

```

If you don't have a tool like PhpMyAdmin for accessing your database easily, I would use Sequel Pro on macOS or MySQL Workbench on Windows/Linux.

Drush has a `sql-sanitize` command but I have encountered several issues with it over the years. I don't want to risk accidentally exposing anything before handing off a db to another developer, so I check the db anyway; in that case, there's no real speed advantage to using Drush vs. running the SQL myself and since I'm checking it with my own eyes I can be confident the job got done.

# Answer
> 0 votes
You can do this via custom module, implementing hook\_drush\_sql\_sync\_sanitize

You can see detailed instruction on this site

At the end, just run

```
drush sql-sanitize

```

**IMPORTANT: Drush sql-sanitize will sanitise data in the current database – you do not want to play with this on a live or production server!**

```
<?php
/**
 * @file /sites/all/modules/custom/es_gdpr_custom/es_gdpr_custom.drush.inc
 * Extends drush santize functionality.
 */

/**
 * Implements hook_drush_sql_sync_sanitize.
 */
function es_gdpr_custom_drush_sql_sync_sanitize($source) {
  // Truncate cache tables with personal data.
  $query = "TRUNCATE cache_field;";
  $query .= "TRUNCATE cache_form;";

  drush_sql_register_post_sync_op('sanitise_cache tables', dt('Truncate cache tables with personal data: cache_field, cache_form'), $query);

  // The query to sanitise field_data_commerce_customer_address table.
  $query = "UPDATE field_data_commerce_customer_address SET commerce_customer_address_administrative_area = 'State';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_locality = 'Some City';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_dependent_locality = 'Some City';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_postal_code = '00000';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_thoroughfare = 'Some address';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_premise = '00';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_sub_premise = '00';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_organisation_name = 'Some organization';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_name_line = 'First and Last Name';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_first_name = 'First name';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_last_name = 'Last name';";
  $query .= "UPDATE field_data_commerce_customer_address SET commerce_customer_address_data = NULL;";

  drush_sql_register_post_sync_op('sanitise_commerce_address', dt('Sanitise field_data_commerce_customer_address table.'), $query);

  // The query to sanitise field_revision_commerce_customer_address table.
  $query = "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_administrative_area = 'State';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_locality = 'Some City';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_dependent_locality = 'Some City';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_postal_code = '00000';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_thoroughfare = 'Some address';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_premise = '00';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_sub_premise = '00';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_organisation_name = 'Some organization';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_name_line = 'First and Last Name';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_first_name = 'First name';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_last_name = 'Last name';";
  $query .= "UPDATE field_revision_commerce_customer_address SET commerce_customer_address_data = NULL;";

  drush_sql_register_post_sync_op('sanitise_commerce_address_rev', dt('Sanitise field_revision_commerce_customer_address table.'), $query);

  // The query to sanitise commerce_order table.
  $query = "UPDATE commerce_order SET mail = 'mail@localhost.com';";
  $query .= "UPDATE commerce_order SET data = NULL;";
  drush_sql_register_post_sync_op('sanitise_commerce_order', dt('Sanitise commerce_order table.'), $query);

  // The query to sanitise commerce_order_revision table.
  $query = "UPDATE commerce_order_revision SET mail = 'mail@localhost.com';";
  $query .= "UPDATE commerce_order_revision SET data = NULL;";
  drush_sql_register_post_sync_op('sanitise_commerce_order_rev', dt('Sanitise commerce_order_revision table.'), $query);

  /*
   * Sanitize custom fields.
   */

  // Place your custom fields here.
}

```

---
Tags: 7
---


# Question
Title: How to navigate the URL after booking page
I have node content type for booking and created booking page in drupal 7 and same page is displaying error, confirmation and booking page. I am trying to split into three different pages(nodes) using same `node--booking.tpl.php` content type. I have custom `booking.class.php` that manages the booking process using two steps function `prebooking` and `postbooking`

After booking, I would like to redirect to `xyz.com/booking-confirm` if it's successfully booking and if it's error `xyz.com/booking-error` and currently, using `xyz.com/booking` for all actions.

What should I do? I am not sure, which option works. I have found this using some articles and stuck at this point.

1. Should I use header to redirect it?

```
header('Location: /booking-confirm');
header('Location: /booking-error');

```
2. Should I hook them in `template.php`?

`function MYMODULE_user_register_form($form, &$form_state) {
 $form_state['redirect'] = 'path/to/somewhere';
}`
3. Should I use `drupal_goto` to redirect it? it's in `booking.class.php` class?
4. Should I use `hook_init`? It's in `template.php` or `booking.class.php` ?

I am not sure, which is correct option to figure it out. I would like to split the URL using same content type. Any approach to solve the issue.

# Answer
You should use form state to do redirects since users are interacting with forms. `header` is not really want you want and neither is `drupal_goto`.

The class(es) should return either a success/fail style response to the caller (in form submit) and based on that, you should handle the response and redirect with form\_state redirect. The only job of your booking class should be to create a booking, it does not need to handle redirects or worry about any of that logic.

Also, no, absolutely don't do redirects from `hook_init`.

Vanilla example:

```
function myform_submit($form, &$form_state) {
  $book = new MyBookingClass();
  $form_data = $form_state['values'];

  // createBooking() returns either TRUE or FALSE

  if ($book->createBooking($form_state['values'])) {
    $form_state['redirect'] = '/booking-confirm';
  } else {
    // There was some sort of error.
    $form_state['redirect'] = '/booking-error';
  }
}

```
> 3 votes

---
Tags: 7, views, nodes, commerce, hooks
---


title: content_entity_example

text:
# Question
Title: content_entity_example
I'm studying the **content\_entity\_example** module and there are some things I'd like to understand better. In the file **content\_entity\_example.routing.yml** there is this block:

```
entity.content_entity_example_contact.collection:
   path: '/content_entity_example_contact/list'
   defaults:
   # Calls the list controller, defined in the annotation of the contact entity.
     _entity_list: 'content_entity_example_contact'
     _title: 'Contact list'
   requirements:
   # Checks for permission directly.
     _permission: 'view contact entity'

```

This is the routing path that shows the contact list, but I did not understand what it means

**\_entity\_list: 'content\_entity\_example\_contact'**

Examples are avaiable

The examples are available at this link: Drupal 8 examples

# Answer
> 3 votes
As the comment states, it looks at the defined entity (Contact) and checks the value of the annotation in Contact.php which is `Drupal\content_entity_example\Entity\Controller\ContactListBuilder` to see what its entity list builder class is. It knows this because `content_entity_example_contact` resolves to the class, because it has an `id` annotation defining it as such.

See: https://cgit.drupalcode.org/examples/tree/content\_entity\_example/src/Entity/Contact.php

---
Tags: 8
---


# Question
Title: How to tell if you are on a view page in preprocess_page
I am trying to see if we are on a view page in the preprocess\_page function in my MYTHEME.theme file.

views\_get\_page\_view() gives me an undefined function error.

I want to get values from my view to display outside the view area in page.html.twig

# Answer
> 11 votes
That function will error because it does not exist in Drupal 8.

You can do this though:

```
$view_id = \Drupal::routeMatch()->getParameter('view_id');
$view = \Drupal\views\Views::getView($view_id);

```

Be sure to validate `view_id` first though, that it exists/length before calling the second line.

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


# Question
Title: Why isn't this functionality in submitForm firing?
I'm in the process of writing a module. The module works very well. In the module, I generate a form which consists of one submit button, and in the .module file, I'm calling that form and the submitForm works too. I was asked to move that button into a block, so I did. submitForm still works, but the main functionality doesn't. How come?

```
<?php

namespace Drupal\my_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
* Generate button.
*/
class myModuleForm extends FormBase {

  /**
  * {@inheritdoc}.
  */
  public function getFormId() {
    return 'my_module_form';
  }

  /**
  * {@inheritdoc}.
  */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['my_module_btn'] = [
      '#type' => 'submit',
      '#value' => 'Do something'        ];
    return $form;
  }

  /**
  * {@inheritdoc}.
  */
  public function validateForm(array &$form, FormStateInterface $form_state) {
  }

  /**
  * {@inheritdoc}.
  */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $mpdf = new \Mpdf\Mpdf(['tempDir' => 'sites/default/files/tmp', 'default_font' => 'roboto', 'margin_left' => 6, 'margin_top' => 6, 'margin_right' => 6, 'margin_bottom' => 11]);
    ...
    ...
    ...
    $mpdf->Output($title."-".date("Ymd-His").".pdf", 'D');
  }
}

```

# Answer
Though 4k4 says its not usually advisable, you can add an `exit;` at the end of `submitForm` in your particular case since you are generating a PDF and immediately serving it to the client. This will stop any further code from executing and solve the immediate problem (though it sounds like more scalable ones exist).
> 4 votes

# Answer
I googled the Mpdf library and it supports a string output. So you can use the string output to build a response and return it via $form\_state:

```
use Symfony\Component\HttpFoundation\Response;

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $content = '%PDF-1.3...';
    $headers = [
      'Content-Type' => 'application/pdf',
    ];
    $response = new Response($content, 200, $headers);
    $form_state->setResponse($response);
  }

```
> 9 votes

# Answer
I think it will be because the form functionality will be attempting to reload/redirect back to the page the form is on and you can't interrupt that mid flow with your own output.

You should probably add a redirect in your form submit to go to a custom controller page that will output your PDF
> 1 votes

# Answer
You can update the code as follows-

```
public function submitForm(array &$form, FormStateInterface $form_state) {
    $mpdf = new \Mpdf\Mpdf(['tempDir' => 'sites/default/files/tmp', 'default_font' => 'roboto', 'margin_left' => 6, 'margin_top' => 6, 'margin_right' => 6, 'margin_bottom' => 11]);
    ...
    ...
    ...
    $mpdf->Output($title."-".date("Ymd-His").".pdf", 'D');

  // Add the line for custom redirect

  $form_state->setRedirect('NEW PATH');

  exit;

  }

```
> 0 votes

---
Tags: 8, forms
---


# Question
Title: Drupal Node Display Main Image or Video not both
We have a content type that in addition to the body field it has a field for Image and another field for Video.

Both video and image are currently displayed at the top of the node, in Node \> Manage Display. But if there is already a value for video field, that should be all that needs to display. Unless the video field has no value in which case, display the image field.

In other words, we want to have a condition where the image field is hidden IF there is a value for the Video field. If no data is present for video filed, display image.

Does anyone have an idea of how this can be accomplished?

# Answer
> 2 votes
This should work:

```
{% if node.field_video is not empty %}
  {{ content.field_video }}
{% else %}
  {{ content.field_image }}
{% endif %}

```

If the field is populated with a value, render that field. Otherwise, render the image field.

---
Tags: 8, theming, nodes, bootstrap-theme
---


# Question
Title: Pass parameters to external JS file with drupal_add_js()
My organization is using Eloqua, and to this point have been using the Eloqua module. The main point of this module is just to determine where the external tracking script should be loaded on the site, and then load the external script while passing it a couple of parameters. This call is creating a huge performance hit, and so after talking to Eloqua support, I copied the external file to the site so it could be cached. Since we need the file to be loaded for every page, we really don't need the module, and so all we really need to do is load the file and pass it the required parameters

The problem is determining how to pass the required parameters to the script. Here is the current `eloqua.js`:

```
var _elqQ = _elqQ || [];

(function ($) {

  Drupal.behaviors.eloquaTracking = {
    attach: function (context, settings) {

      _elqQ.push(['elqSetSiteId', Drupal.settings.eloqua.siteId]);
      _elqQ.push(['elqTrackPageView']);

      function async_load() {
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.async = true;
        s.src = '//img.en25.com/i/elqCfg.min.js';
        var x = document.getElementsByTagName('script')[0];
        x.parentNode.insertBefore(s, x);
      }
      if (window.addEventListener) {
        window.addEventListener('DOMContentLoaded', async_load, false);
      } else if (window.attachEvent) {
        window.attachEvent('onload', async_load);
      }
    }
  };
})(jQuery);

```

The `_elqQ` array is accessed by `elqCfg.min.js`, so I need to make it accessible to the script with the `elqSetSiteId` and `elqTrackPageView` parameters. Is there a way to do that while adding `elqCfg.min.js` via `drupal_add_js()` in template.php or somewhere else?

**CLARIFICATION:** What I'm looking for here is a way to include this file and pass the parameters to it without having to create a whole module. That seems like a lot of unnecessary overhead for this one file.

# Answer
> 0 votes
I ended up just going with a modification of the current code. I modified the behavior above so that it just loads the variables:

```
var _elqQ = _elqQ || [];

(function ($) {

  Drupal.behaviors.eloquaTracking = {
    attach: function (context, settings) {

      _elqQ.push(['elqSetSiteId', Drupal.settings.eloqua.siteId]);
      _elqQ.push(['elqTrackPageView']);
    }
  };
})(jQuery);

```

and then used `drupal_add_js()` to load the tracking file in my module

```
drupal_add_js(drupal_get_path('module', 'eloqua') . '/elqCfg.min.js');

```

---
Tags: javascript
---


title: Provide name for Entity Reference

text:
# Question
Title: Provide name for Entity Reference
Is there any way referenced entities could be named in a meaningful way?

Currently when I am creating a custom view and need to reference some entity, I have tens of entities that are named exactly the same: *Entity Referenced: Referenced Entity* (see the picture below).

In such setup there is no way to tell what the referenced entity is before using it. Is there any better way to have referenced entities on the system and still know what they are before using them?

# Answer
> 0 votes
You can read a little bit more info in the Description text: `A bridge to the Content entity that is referenced via field_entityref` so if you're using different fields you can discern them by the field machine name.

Your theme seems to have the Description text hidden behind an icon. Can you see it when you click on the icon?

---
Tags: 7, entities, views
---


# Question
Title: How do I tell Twig not to print any form field?
I am trying to theme a form in Drupal 8.

This is the template that I am using which is basically from form.html.twig

```
<form{{ attributes }}>
{{ element.app_theme_settings }}
{{ element.a2 }}
{{ element.a3 }}

 {% print remaining required form fields. %}
 {{ children }}
</form>

```

My problem is I want to print children variable but without app\_theme\_settings, a2 and a3 children. In Drupal 7 we could use unset function, but in twig I am not sure what to use. I know I can use without filter, but it does not accept the array argument so I have to write name of each element already printed.

```
 {{ children|without('app_theme_settings','a2','a3' }}

```

How can I print children without specifying the name of each field one by one?

# Answer
Loop through the keys

```
{% for key in element|keys %}
    {{ children|without(key) }}
{% endfor %}

```
> 0 votes

---
Tags: 8, theming
---


# Question
Title: How to get node url/address from entity reference (content type)?
Is there a way to fetch or print the `node` `url/address` from a entity reference to my twig template.

I have already tried `{{ related_links.entity.uri }}`, `{{ related_links.entity.url }}` or `{{ related_links.entity.path }}` but nothing seems to work

```
<div>

{% for related_links in node.field_pbn_additional_items %}

    <h2>{{ related_links.entity.label }}</h2>
    <a></a>

{% endfor %}

</div>

```

# Answer
> 1 votes
No need to add the `<a>` tags, because Drupal will automatically create the link.

So just simply do `<h2>{{ related_links.entity.toLink }}</h2>`

You don't even need the label with `.toLink()` because Drupal will automatically grab it when generating the link.

The above is suppose to work, but I get an error

> Twig\_Sandbox\_SecurityError: Calling "toUrl" method on a "Drupal\node\Entity\Node" object is not allowed. in Drupal\Core\Template\TwigSandboxPolicy-\>checkMethodAllowed() (line 105 of /home/ubuntu/workspace/drupal-8.5.3/core/themes/bartik/templates/node.html.twig).

There is an issue about this on drupal.org Add $entity-\>toUrl() and $entity-\>toLink() methods to whitelist in Twig sandbox policy applying the patch in #30 solved the issue.

---
Tags: 8, theming, entities
---


# Question
Title: Bad request with Acquia Dev Desktop2 overriding installation
I use Acquia Dev Desktop2 on Mac for php7.0. I think that it is the previous version. I was waiting for the upgrade to use php7.1, but there was no announcement in check for update menu. I have no choice, so I downloaded it and overwrite install. The bad request will be displayed on all local sites. Phpmyadmin of all sites will be displayed correctly. What is the solution?

What I can think of is using underscores for site addresses.

test\_drupal8\_mockup1.dd:8083

In order to remove the underscore, I edited vhosts.conf and restarted apache. 'But request' was not improved.

# Answer
> 0 votes
As an alternative solution, I tried to add the following setting setting to httpd.conf.

```
<IfVersion> = 2.4.25>
 HttpProtocolOptions unsafe
</ IfVersion>

```

'Bad request' message is solved. The reason was that ServerName contained underscores.

---
Tags: acquia-dev-desktop
---


title: Multiple domains with a language each

text:
# Question
Title: Multiple domains with a language each
We've setup that english language points to an english domain, and for spanish we have a language.

The spanish one is simply a symlink to the english code base. When translating nodes, I am being redirected to the Spanish domain when changing a spanish node, and have to login on that domain to be able to work.

How can I make sure; that either I'm logged in, or that I can stay on the same domain when editing content?

# Answer
You can't stay logged in on a different domain except you'd use some kind of single-sign-on system between your domains.

Cookies are assigned to a specific domain, the browser has no idea that he is still on the same website.

You might be able to configure separate content and interface negotation, so you stay always on your own language, or you could use the admin language feature so a certain user always stays in his language when he's on the site. But not sure if that works 100% for editing translations in Drupal 8, havent tried it yet.
> 0 votes

# Answer
if you have multiple domains on the same drupal 8 site, and if they share the same master domain (en.something.mydomain.com, fr.something.mydomain.com...etc), then you can specify a value of "cookie\_domain" in the file "sites/default/services.yml", like this :

```
parameters:
  session.storage.options:
    cookie_domain: '.something.mydomain.com'

```
> 0 votes

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


# Question
Title: Approach to create headless drupal with login
I am curious on the approach I will have to take if I would like to build an app that connects to Drupal. I have already built simple headless drupal app using only get requests.

I am able also to make posts requests with Basic Auth or Auth0 mainly via postman and the concept of this is clear.

What is not clear to me is how I will be able to manage a logged in user from let's say a React/Vue.js app.

Let's say we have an app that servers 2 types of content: News and Events. News is public and Events is for logged in users. News and Events will be two Rest Export views in Drupal and Events will have an authentication method.

Now if a user wants to see Events he/she must be logged in. So the user will login via a login form and the session should be persisted. The app sends the request to Drupal, logs the user in and give a cookie/token/jwt back? So I will be able to use that cookie/token/jwt to access events and events/nid?

What should I use in this case in order to persist a login?

Thanks in advance.

# Answer
> 6 votes
I'd recommend you look at OAuth 2.0, which more or less standardizes the process of how to get to a valid login state/token.

I used https://www.drupal.org/project/simple\_oauth recently in a project, which depends on the oauth2 component of the phpleague, which comes with great documentation: https://oauth2.thephpleague.com/. And the module itself also has a lot of documentation and whole video series on how to configure and use it.

OAuth2 provides 5 different ways to handle what it calls a grant, based on whether your client is an API, another website, a 3rd/1st-party client and so on: https://oauth2.thephpleague.com/authorization-server/which-grant/

E.g if you're OK with the user entering his password then you can just use the password grant, if you don't want that, you can use the oauth/authorize page which then redirects the user back to the app and so on.

---
Tags: users, 8
---


title: Storing data as entity or node?

text:
# Question
Title: Storing data as entity or node?
I am working on a module where I need to save thousands or I guess millions of data (product'data from various e-commerce sites). So I am not sure of saving that data in a custom table by using custom entity or should I save that data in nodes?

As for searching, a user can use elastic or search\_api\_solr and use views for displaying the data, so is it better to use custom row or nodes to save that much of data?

# Answer
I actually disagree with the comment from @Kevin, using or not using nodes can make a huge performance difference, for multiple reasons.

Yes, node is a pretty standard content entity, but..

* It is revisionable
* It is translatable
* It has a bunch of standard base fields like promote, sticky that are likely not relevant for your use case
* Any data that actually is relevant needs to be stored in configurable fields, which results in additional tables.

So if you need 20 additional fields to store stuff, you end up with 4 base tables and 40 additional tables, so 44 tables in total.

If you don't need revisions and translations and assuming you only have single-value fields, you can do that with a single table instead with a custom entity type and base fields. If you need revisions then it's 2. And each multi-value field does require 2 additional tables but usually there are not that many of those.

With millions of records, it's definitely worth thinking about if creating a custom entity type is worth it and sounds like for that case, the answer is probably yes.

It's worth pointing out that there's still a decent amount of modules (even in core), that currently only work with nodes, e.g. book or diff. So make sure that you don't need any of that or be prepared to re-implement that functionality.
> 13 votes

# Answer
It depends. As Kevin pointed out, there are not much difference as "entities". However: using a custom entity CAN be a big advantage in some cases.

Since nodes are being used in the most cases too many contrib and core modules can integrate with it, which can lead to unnecessary overhead.

When going for custom entity maybe you have to do some initial extra work for it, but then it is in your hands: it's much easier to make custom changes for it. Also can make your code easier to read.

So final conclusion: If you use already a couple of node bundles and your new type will need a special highlight I would go for a custom content entity.
> 2 votes

---
Tags: 8, entities
---


# Question
Title: How do I do namespacing in a module from an external project which is not in the src directory?
Based on Why do I have conflicts in namespacing? I adjusted my complete system.

As long as I do namespacing in /src, it is goes all very well.
I included my project from Github. Those class files are located in modules/custom/tb/vendor/ccxt/ccxt/php.

When not working with namespaces I included them with `include "vendor\ccxt\ccxt\ccxt.php";`.

How should I include those classes to module? Because of the Composer structure, those files are in the vendor sub-directory.

Because of namespacing in Drupal, `use \Drupal\tb\<classfile>` doesn't work.

The content of the composer.json file is the following.

```
    "name": "org/tb",
    "description": "This extension provides new commands for Drush.",
    "type": "drupal-drush",
    "authors": [
        {
            "name": "Author name",
            "email": "author@example.com"
        }
    ],
    "require": {
        "php": ">=5.6.0",
        "arcturial/clickatell": "^3.0",
        "ccxt/ccxt": "^1.14"
    },
    "extra": {
        "drush": {
            "services": {
                "drush.services.yml": "^9"
            }
        }
    }
}

```

# Answer
> 1 votes
From your post, it looks like you added the above composer.json file, then ran composer from the module root. This is not the way to do it. This will create a vendor folder inside your module folder, which is not what you want. What you need to do is add the composer.json file to your module, then push that to the remote repository. Then use Composer to install and manage the module. Doing this will add the library to the vendor folder for your project, and the library will be available when calling `\ccxt\ccxt`

---
Tags: 8
---


# Question
Title: String validation not working for custom form
Please help me with Drupal 8 validation for string.

```
   $form['field_text'] = array(

  '#type'  => 'textfield',

  '#title' => $this->t('Name'),

  '#attributes' => array(' type' => 'alpha' ),

   );

  $form['field_phone'] = array(

  '#type' => 'textfield',

  '#title' => $this->t('Phone'),

  '#attributes' => array(' type' => 'number' ),

  );

```

I am able to validate Phone no but not string .

Please suggest what i am doing wrong.

# Answer
You can add validate form function for same.

public function validateForm(array &$form, FormStateInterface $form\_state) {

```
if(!preg_match("/^[a-zA-Z ]*$/",$field_text))

{

  drupal_set_message("MESSAGE_TO_ENTER_STRING_CHARACTERS");

}

```
> 0 votes

---
Tags: forms
---


# Question
Title: How to add author's user role as CSS class to comments?
Snippet from Bartik's comment.html.twig ( https://pastebin.com/D70cyHNp ):

```
{{ user_picture }}
    <p class="comment__author">{{ author }}</p>
    <p class="comment__time">{{ created }}</p>

```

I want to highlight comments by administrators with CSS so how can I say "if the comment author has the role administrator, add the class "comment\_author\_is\_administrator" to the author variable?

# Answer
> 1 votes
This can be done pretty easily by preprocessing your comments.

But first of all, very important: don't edit any of Bartik's files (or any core files in general). Create a sub-theme, copy the `comment.html.twig` to your sub-theme's `templates` directory and edit that file.

Second, depending on your CSS setup `comment_author_is_administrator` doesn't seem like a legit CSS class. Normally, underscores are not allowed to be used that way. And maybe you can make it a little bit shorter. Maybe just `author-administrator`.

Finally, simply place the following snippet in you sub-theme's `*.theme` file and replace `MYTHEME` with your actual theme name.

```
/**
 * Implements template_preprocess_comment.
 */
function MYTHEME_preprocess_comment(&$variables) {

  // Get the comment.
  $comment = $variables['comment'];

  // Get its owner.
  $owner = $comment->getOwner();

  // Check for administrator role.
  if ($owner->hasRole('administrator')) {

    // Append CSS class.
    $variables['attributes']['class'][] = 'author-administrator';
  }
}

```

Alternatively, you could simply append each comment's author role as CSS class like following.

```
/**
 * Implements template_preprocess_page.
 */
function MYTHEME_preprocess_comment(&$variables) {

  $comment = $variables['comment'];
  $owner = $comment->getOwner();
  $roles = $owner->getRoles();

  // Let's pop the roles array to only
  // get the last (highest) role of all.
  $role = array_pop($roles)

  $variables['attributes']['class'][] = 'author-' . $role;
}

```

---
Tags: theming
---


# Question
Title: Is it possible to combine two different Template.php functions?
How about two different functions like below? Is it possible to combine below two Drupal Template.php functions?

```
function mytheme_preprocess_node(&$vars)
function mytheme_views_pre_render(&$view)

Example:
function mytheme_preprocess_node(&$vars) {
if some field has option 1 selected
}
AND
function mytheme_views_pre_render(&$view) {
if a view is empty { attach alternative view}
}

```

# Answer
> 1 votes
You can do all of this inside the views\_pre\_render

```
function mytheme_views_pre_render(&$view) {

  if ($view->name == 'my_view_name' && $view->current_display == 'block_1') {
    if ($node = menu_get_object()) { // gets current page node object
      $field_name_val = $node->field_name[LANGUAGE_NONE][0]['value']; // get field value
      if ($field_name_val == 'option 1') {
        // your empty view code conditional goes here
        // if($view->result...
      }
    }
  }

}

```

You can find out the `current_display` name look here

# Answer
> 0 votes
I've tried below with a Profile2 field but it seems like Drupal doesn't like it..

```
function mytheme_views_pre_render(&$view) {
    if ($view->name == ‘view_name’ && $view->current_display == 'page_1') {

    $profile = profile2_load_by_user($user, 'main');
    $field_name_val=$profile->field_custom[‘und'][0]['value']

        if ($field_name_val == ‘0’) {

                if (empty($view->result)) {
                    $attachment = views_embed_view(‘view_name’’, ‘page_2’);
                    $view->attachment_after = $attachment;
            }
        }

        if ($field_name_val == ‘1’) {

                if (empty($view->result)) {
                     $attachment = views_embed_view(‘view_name’’, ‘page_3);
                     $view->attachment_after = $attachment;
            }
        }
}
}

```

---
Tags: 7, theming
---


# Question
Title: How to get field label from a field machine name
```
$fields = \Drupal\Core\Entity\EntityTypeManagerInterface->getStorage('field_storage_config')->loadMultiple();

```

This is listing me all the fields.

```
foreach ($fields as $key => $instance) {
   $label = $instance->getLabel();
   $name = $instance->getName();
}

```

$label is giving me **node.field\_image**

$name is giving me **field\_image**

My question is how can we get the label of the field in drupal 8

# Answer
> 5 votes
The label is not stored in the field storage configuration. You'll find the label in the bundle specific field definition:

```
$definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'page');
foreach (array_keys($definitions) as $key) {
  // get label for field machine name $key:
  $label = $definitions[$key]->getLabel();
}

```

Reference: EntityFieldManager::getFieldDefinitions

---
Tags: 8, entities
---


# Question
Title: Receiving Error message on every attempt to add or remove content. Is this normal?
New to drupal & collaborating on a project. Error message reads "Error ; The website encountered an unexpected error. Please try again later." I've been getting that error message for 4 days in a row. Wondering if there is actually a site issue (with Drupal) or if there's something I can do to fix this.

# Answer
> 0 votes
Just add this code to your index.php file just after the php opening tag.

```
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);

```

Then try to reproduce the scenario. You will see the exact error on web page and if you clear about error then definitely you can solve it.

# Answer
> 0 votes
This behavior isn't normal. I think you should go to `admin/config/development/logging` and choose `All messages, with backtrace information`. You will be able to see the errors and find the problem.

---
Tags: nodes, debugging
---


# Question
Title: Caching strategy for a page that varies by IP
I've created a custom cache context that determines if a request comes from in my campus network or from outside my campus network:

```
class NetworkContext extends RequestStackCacheContextBase implements CacheContextInterface {

  /**
   * {@inheritdoc}
   */
  public static function getLabel() {
    return t('Network');
  }

  /**
   * {@inheritdoc}
   */
  public function getContext() {
    if (Util::requestFromCampus($this->requestStack->getCurrentRequest()->getClientIp())) {
      return 'oncampus';
    }
    else {
      return 'offcampus';
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata() {
    return new CacheableMetadata();
  }

}

```

This custom cache context is registered in my module's services file and given the name "network".

I have a custom controller action that returns some data that varies based on if the user is on campus or off campus:

```
public function myCustomAction(Request $request) {
  $build = [];

  $build['my_data'] = [
    '#theme' => 'my_custom_theme_function',
    '#rawdata' => $this->fetchData(Util::requestIsFromCampus($request->getClientIp()));
  ];

  // Add some cache metadata that indicates this render array varies
  // based on the user's network. We can't effectively use cache tags
  // here since the data is retrieved from an external service and we
  // don't know when it's updated. Instead, expire the result after
  // one hour.
  $build['#cache'] = [
    'max-age' => 60 * 60,
    'contexts' => [
      'network',
    ],
  ];

  return $build;
}

```

Here's what I've found:

**Internal Page Cache won't work here:** The Internal Page Cache module, to my knowledge, doesn't support cache contexts at all. It will store the entire page result for ALL anonymous traffic. If the request that warmed the cache for this page happened to be on campus, off campus users will also see that result, despite their cache context being different. This means I have to tell Internal Page Cache to not cache this page. One way is to add the "no\_cache" option to the routing definition, which is what I've done.

**Dynamic Page Cache DOES work, but not when I have the "no\_cache" option set**. I've found that dynamic page cache DOES support cache contexts entirely, so it will correctly vary the response by my custom cache tag! However, I can't keep Dynamic Page Cache working while also turning off Internal Page Cache, because the mechanism to disable one will disable both.

My questions:

1. Is there a way I can disable internal page cache for a page but NOT dynamic page cache?
2. Is using the dynamic page cache appropriate here, or am I using it incorrectly? I looked into auto placeholdering but that seems to be for things that are *highly* dynamic, but my cache context is not. It's either "yes" or "no".

# Answer
> 2 votes
Page cache is a service, which means you can override it in a ServiceProvider of a custom module, subclass it and override \Drupal\page\_cache\StackMiddleware\PageCache::getCacheId(), where you can make the IP subnet or what you need exactly part of the cache key.

You could simply disable the page\_cache module and still use the dynamic page cache.

Yet another option would be a to implement a request policy that prevents caching either for internal or external requests, I think dynamic page cache doesn't consider that. See \Drupal\basic\_auth\PageCache\DisallowBasicAuthRequests for an example.

# Answer
> 2 votes
One approach could be to use a middleware to set a query parameter:

```
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
    $ip = $request->getClientIp();
    if (Util::requestFromCampus($ip)) {
      $request->query->add(['oncampus' => '1']);
    }
    else {
      // remove the query parameter in case an off-campus user sets it incorrectly
      $request->query->remove('oncampus');
    }
    return $this->httpKernel->handle($request, $type, $catch);
  }

```

Set a priority higher than 200, so that it runs before the page cache. The page cache uses the url including the query string as cache key and so both versions can be delivered from cache, which is good for performance.

As example how to set this up see Drupal\ban\BanMiddleware.

If you use this approach you don't need the custom cache context anymore, you can use a context for the query argument in content that varies for off- and on-campus users.

# Answer
> 0 votes
I found that the core maintenance mode module makes a call to the service `\Drupal::service('page_cache_kill_switch')->trigger();` in `MaintenanceModeSubscriber.php` so that the maintenance mode page does not get cached.

I was able to add this to my custom Event Subscriber:

```
<?php

namespace Drupal\my_module\EventSubscriber;

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

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

  public function myCustomRedirect(GetResponseEvent $response, $event, ContainerAwareEventDispatcher $event_dispatcher) {
    if (\Drupal::service('router.admin_context')->isAdminRoute()) {
      return;
    }

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

    // ...

  }
}

```

---
Tags: 8, caching
---


title: Clearing Cookies

text:
# Question
Title: Clearing Cookies
I have a website and I have configured it such that only once the user accepts the use of cookies on their website, cookies will be enabled.

I tried using javascript to delete all cookies on page load. But for some reason one cookie still remains.. and the cookie in itself and it's value are a string of junk characters. Cookie name: SESSbcb9eecbd50e36ecb0e5050944c6a793 Cookie Value: r87wIdULAl26ZINb3F7QuCbajCwskPi99eEjJh6VtZ0

Based on what I have read online, cookies that are httpOnly cannot be deleted. Is this true? Can it be done through Drupal core itself? Please let me know. Thanks.

# Answer
> 0 votes
I'm assuming you are attempting to comply with the new EU privacy laws... I suggest you use https://www.drupal.org/project/eu\_cookie\_compliance since they have done a lot of work to make sure that sites with this module installed are in compliance and as changes are needed the module will be updated.

---
Tags: cookies
---


# Question
Title: Add "n" fields when click on "Add another item"
When I click on "Add another item", It should create 10 new fields. Is there a way I can do this?

# Answer
> 0 votes
There is an open feature request for this on Drupal.org but it is not currently supported out of the box. See https://www.drupal.org/project/drupal/issues/1394184 for details

---
Tags: 7, entities
---


# Question
Title: Is there any hook or event that is fired when user data is set/updated/deleted
I am using the `user.data` service to store additional data for users. I would like to trigger some custom functionality each time the `user.data` is changed. I can't find any hook or event that I could use. Is there any way to achieve this?

# Answer
> 0 votes
`hook_entity_presave` (`hook_ENTITY_TYPE_presave`)

> Act on an entity before it is created or updated.
>
> You can get the original entity object from $entity-\>original when it is an update of the entity.

`hook_entity_update` (`hook_ENTITY_TYPE_update`)

> Respond to updates to an entity.
>
> This hook runs once the entity storage has been updated. Note that hook implementations may not alter the stored entity data. Get the original entity object from $entity-\>original.

---

Here's a sample implemented by `system.module`:

```
/**
 * Implements hook_ENTITY_TYPE_presave() for user entities.
 */
function system_user_presave(UserInterface $account) {
  $config = \Drupal::config('system.date');
  if ($config->get('timezone.user.configurable') && !$account->getTimeZone() && !$config->get('timezone.user.default')) {
    $account->timezone = $config->get('timezone.default');
  }
}

```

---
Tags: 8, users
---


# Question
Title: How to make a regular expression case insensitive?
I am working on a Drupal Commerce shipping rule and it needs a regular expression to compare postcodes with the buyers address as below;

```
/^AB37|^AB38|^AB41/

```

I am finding this code to be case sensitive and I need it to be more relaxed allowing lowercase or mixed.

I have read I need a 'i' flag, but I am unsure how to apply this.

Could somebody please provide me with an example?

# Answer
> 0 votes
The case insensitive usually is adding a "i" char after the delimiter bar, something like this: /^AB37|^AB38|^AB41/i

but depends of the case it can be changed. In JS, for example is adding a new param (`var re = new RegExp(myVar,"ig")`) or in php is `preg_match("[expression]i", $text, $matches);`

---
Tags: 8, commerce
---


# Question
Title: How to limit the display of a field on the front end, based on a Form API state
Following on from a previous question.

I have a slideshow field, an image field and a video field, but I only want editors to choose one of these.

Using **Form API states** I have created a form\_alter in a custom module which reveals one input field at a time based based on a choice from a select list. This is working fine. Code below.

```
    <?php

    /**
     * Implements hook_form_alter().
     */
    function mymodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id) {
      $form['field_slideshow_image']['#states'] = [
        'visible' => [
          'select[name="field_selection_display"]' => ['value' => 'slideshow']
        ]
      ];
      $form['field_image']['#states'] = [
        'visible' => [
          'select[name="field_selection_display"]' => ['value' => 'image']
        ]
      ];
      $form['field_video_embed']['#states'] = [
        'visible' => [
          'select[name="field_selection_display"]' => ['value' => 'videoembed']
        ]
      ];
    }

```

This method makes for a good UI, but it does not prevent more than one field being populated. Therefore I need to extend the module to;

1). Prevent an editor populating more than one field, perhaps by displaying an inline error message. OR 2). Limit the display on the front end, to the field which has a visible state (based on the selection list choice).

My feeling is that number 2 would make for the best UX, but it would be good to try both.

How would I go about this?

# Answer
> 0 votes
For option #1 you would have to create a custom validation.

For option #2 which is the better solution you would have to load the fields via AJAX.

---
Tags: 8, forms
---