# Question
Title: How to acess API rest/views using token or login?
I have a Drupal 8 website. I need to access the list of articles using www.myexample.com/rest/views/articles.

I could get the token using `curl --header "Content-type: application/json" -b cookies.tt --request POST "https://www.myexample.com/user/login?_format=json" --data '{"name":"myname", "pass":"mypassword"}'`.

How do I use cUrl to pass the token or user/pass and get 'rest/views/articles' in JSON format?

I tried `curl --header 'authorization: Bearer {D12G7AajU9NdUAb260zqwCimfdddR1Krg5}' --url https://www.myexample/rest/views/artigos/format?_format=json`, but it returns an error.

**UPDATE**

I follow the @Ismail Cherri suggestion, seems a progress in the question but give me back :

```
"message":"The used authentication method is not allowed on this route."

```

In drupal website the config :

/entity/view/{view} is set to :

```
GET
formats: hal_json, json
authentication: basic_auth

```

and /entity/entity\_view\_mode/{entity\_view\_mode} is set to :

```
GET
formats: hal_json, json
authentication: basic_auth

```

anyone could help?

# Answer
First of all, does your endpoint require authentication to begin with? If yes, then use this https://www.drupal.org/docs/8/core/modules/rest/3-post-for-creating-content-entities as a guide though it is for a POST request.

---

UPDATE
You need to know which authentication method are you using, e.g. basic\_auth, cookie, Oauth, etc?
According to the method, you should formulate your request. The use of X-CSRF-Token is for Cookie Authentication.
It might be in your case that you successfully got the token, but you're using it on an endpoint which requires Basic Auth.
As I see in your posted REST configuration, you're actually using Basic Auth, thus your request should look something like this:

```
curl --request GET \
  --url http://example.com/entity/view/{view} \
  --header 'authorization: Basic HASH_HERE' \
  --header 'content-type: application/json' \

```
> 0 votes

---
Tags: 8
---


# Question
Title: How to change theme template for the same block that is loaded twice on the page?
We have created two menu blocks: `main_menu (region=main nav)` and `main_menu_footer (region=footer)` that are added to all pages. They both are displaying the same `main navigation` menu except `main_menu_footer` only displays the first level and `main_menu` displays all levels.

I have a custom module, `mymodule` that I am using to assign a custom twig template, `menu--main.html.twig`. This twig template is being assigned to both blocks.

How can I setup the twig templates so that the `main_menu` uses `main--menu.html.twig` template, but `main_menu_footer` uses `main--menu--footer.html.twig`?

**Goal:**

1. `main_menu` block uses `main--menu.html.twig` template
2. `main_menu_footer` block uses `main--menu--footer.html.twig` template

**Current setup**

```
function mymodule_theme($existing, $type, $theme, $path) {
  $items = [];
  $items['main__menu'] = [
    'base hook' => 'menu',
    'render element' => 'menu',
  ];

  return $items;
}

```

# Answer
> 0 votes
Using @4k4 suggestion, I got it resolved by doing the following

```
/**
 * Implements hook_preprocess_block().
 */
function mymodule_preprocess_block(&$variables) {
  // Only proceed if id is valid. It is not valid for all blocks.
  if(isset($variables['attributes']['id'])) {
    $variables['content']['#attributes']['block'] = $variables['attributes']['id'];
  }
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function mymodule_theme_suggestions_menu_alter(array &$suggestions, array $variables) {
  // Remove the block and replace dashes with underscores in the block ID to
  // use for the hook name.
  if (isset($variables['attributes']['block'])) {
    $hook = str_replace(array('block-', '-'), array('', '_'),    $variables['attributes']['block']);
    $suggestions[] = $variables['theme_hook_original'] . '__' . $hook;
  }
}

```

# Answer
> 1 votes
This is usually done at the theme level, not the in a module. Unless you want to create your own implementation of a menu.
First of all, enable Twig Debugging then in locate in DOM the templates you want to override.
In your active theme, create a file with the same name as the twig template you want to override. Copy the code from the original template and customize it as you like

---
Tags: 8, theming, blocks, hooks, navigation
---


# Question
Title: How do I apply a global filter on view tabs?
In Drupal 7, I have a view where I show different view tabs of different content types. I want to apply a global filter on those view tabs.

How can I achieve it?

# Answer
> 1 votes
You can use Global filter which creates filter widgets as blocks based on field or view of your choice and you can use the filter choices in ANY view as contextual filter.

Here is a simple example usage

* For `basic page` create `List (text) - field_choices` with widget `Select list` and values `choice1 choice2 choice3`

>
* Create some basic pages to include 1 of the 3 choices
* Create or modify the view and make it display the choice for each result

>
* Add contextual filter with choices as field and provide default value Global filter field

>
* Go to `Structure > blocks` and add `Global filter block 1` to a region of you choice and configure it to display `choice` field as a filter with default widget

>
* Visit the view page that has the contextual filter (on choices) and you should be able to filter the view based on the Global filter (choices dropdown widget)

>
* You can add the same contextual filter to as many views (or view displays) as you like

---
Tags: 7, views
---


title: How do I rename a field?

text:
# Question
Title: How do I rename a field?
With Drupal 7 we had the Field Rename module, but this has not yet been ported to Drupal.

So what SQL magic is needed to rename a field in Drupal 8?

# Answer
> 23 votes
I've had the misfortune to need to do this before :P , and my advice would be as follows:

Forget about renaming the existing field; the machine name is scattered across several different hard-to-edit places, and you'll probably miss some and get weird errors. For example, if you just rename the tables and the configuration, the field API will throw a fit when it tries to delete the old tables and finds they're already gone. The schema information is kept in the keyvalue store, and cannot be rebuilt from scratch, so if you make manual changes it's easy to end up in a broken state.

Instead, recreate the field with the correct machine name, then copy over the data with SQL, and finally delete the old field.

```
INSERT INTO node__field_new SELECT * FROM node__field_old;
INSERT INTO node_revision__field_new SELECT * FROM node_revision__field_old;

```

# Answer
> 1 votes
Regarding the latest comment from StevanRS, its not simply than that, because if you just import after renaming, it will fail because original field will not exist anymore. So, here is my proposal:

* Export the config. Save apart all those files with some config for the field. *
* Delete that field on drupal UI.
* Export config again (with field already removed)
* Copy renamed files again on config folder.
* Then you can import properly :)

Tipical files you need to save:

* field.field.yourentity.yourfield
* field.storage.yourentity.yourfield
* core.entity\_form\_display.yourentity.yourfield
* core.entity\_view\_display.yourentity.yourfield

---
Tags: 8, entities
---


# Question
Title: Only render translated nodes, prevent rendering of base language node
Having an entity reference, **Drupal 8** automatically renders the base language of a referenced entity if it isn't translated yet. Is there a way to globally prevent that? So if there is ContentType1 referencing ContentType2, both have a default language of `en-gb`. Translating ContentType1 to `de-de` will by default still show ContentType2's `en-gb` node unless I manually translate it or change a thing.

What I currently do is comparing the current page language `\Drupal::languageManager()->getCurrentLanguage()->getId();` with the current node language `$variables['node']->language()->getId();` and return an empty `node.html.twig`.

Is there a better solution? Especially when you have multiple `node.twig.html`

# Answer
> 1 votes
One way to think about it is to disable language fallback mechanism in Drupal. Although there are 3 different modules which handle language fallback priority, none of them provide such functionality.
However, the module Disable Language allows admin to disable an entire language entirely without deleting the content itself.
I think you can use its code to implement an EventSubscriber which checks whether the node has a translation for the current site language then return a NotFoundException in this case. This will cover direct node access.
I'm not entirely sure how to deal with nodes loaded via DB. I think you can use hook\_entity\_load for this case.

---
Tags: 8, entities, nodes, i18n-l10n
---


# Question
Title: Custom content entity field widget. This value should not be null
I've created a custom content entity in Drupal 8 and all is well in those regards. I have an issue when I go to create a new record for my entity using the entity form. "**This value should not be null.**".

The error comes from a widget plugin that I've created that only replicates the functionality of a list of checkboxes that represent taxonomy terms. The field that uses this widget is not a base field, it's added through the UI. I've looked at the plugin documentation on drupal.org and haven't found much help in regards to my issue.

---

Below, is my code for the widget form element.

```
namespace Drupal\my_entity\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsWidgetBase;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\taxonomy\Entity\Term;
use Drupal\user\Entity\User;

/**
 * A widget for displaying terms and supplying an AJAX request when a checkbox is clicked
 *
 * @FieldWidget(
 *   id = "my_entity_programme_areas_lookup_directors",
 *   module = "my_entity",
 *   label = @Translation("Programme Areas Lookup Directors Widget"),
 *   field_types = {
 *     "entity_reference"
 *   }
 * )
 */
class ProgrammeAreasLookupDirectorsWidget extends OptionsWidgetBase
{

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

    $value = isset($items[$delta]->value) ? $items[$delta]->value : NULL;

    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    $element += [
      '#type'          => 'checkboxes',
      '#default_value' => $this->getSelectedOptions($items),
      '#options'       => $this->getOptions($items->getEntity()),
      '#multiple'      => TRUE,
      '#element_validate' => [
        [static::class, 'validate'],
      ],
      '#prefix' => '<div id="programme-areas-directors-lookup">',
      '#suffix' => '</div>',
    ];

    unset($element['#options']['_none']);
    return ['value' => $element];
  }

  /**
    * @inheritdoc
    */
  public static function validate($element, FormStateInterface $form_state) {

    $value = $element['#value'];
    return true;
  }

```

For the moment, I just want it to pass validation so then I can work on from there, but right now, it can't seem to retrieve a value, even though I can see it has the expected values in the `$form_state` object (field\_programme\_areas field).

Any help and tips would be greatly appreciated. Thanks!

# Answer
I managed to get it working by extending the `OptionsButtonsWidget` class instead of `OptionsWidgetBase`. I've also added the `multiple_values` annotation which I was missing and also removed the validation callback I was supplying, so now the `validateElement` method from `OptionsWidgetBase` is the validation handler used. My widget class just extends `OptionsButtonsWidget` and works fine. I think the missing annotation was the main reason it wouldn't validate.
> 3 votes

# Answer
I had exactly the same problem with a custom entity extending Datetime (shamelessly adapted from datetime range: in my case, I need a datetime with a comment). I followed your suggestions, adding `multiple_values` to the annotations of the widget, and extending `DateTimeDefaultWidget` rather than `DateTimeWidgetBase`, but it wasn't enough, I also had to add `setRequired(FALSE)` on the property definitions in FieldType. It seems odd to me, because "required" in such a case should mean "the properties are required if there is an attached entity", yet it apparently means something different, or maybe there is a subtle bug that I don't understand.
> 1 votes

---
Tags: 8, entities, plugins
---


# Question
Title: How to apply suggested theme hook using hook_theme_suggestions_HOOK?
Following this answer, I'm trying to override `core/themes/seven/templates/node-add-list.html.twig` using hook\_theme\_suggestions\_HOOK.

So, I added the following function in `modules/custom/domain_filter/domain_filter.module`

```
function domain_filter_theme_suggestions_node_add_list(array $variables) {
  $suggestions = [];
  $suggestions[] = 'node_add_list__' . 'custom';
  return $suggestions;
}

```

I created the custom twig file in my module: `modules/custom/domain_filter/templates/node-add-list--custom.html.twig`

The suggestion appear well in theme debug but it's not applied (the `x` is in front of `node-add-list.html.twig`):

```
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'node_add_list' -->
<!-- FILE NAME SUGGESTIONS:
   * node-add-list--custom.html.twig
   x node-add-list.html.twig
-->

```

How to apply `node-add-list--custom.html.twig`?

# Answer
Finally I found a paragraph in the documentation. When using modules, we need to register the template using `HOOK_theme()`. So, I added the following function in `modules/custom/domain_filter/domain_filter.module`

```
/**
 * Implements hook_theme().
 */
function domain_filter_theme() {
  return [
    'node_add_list__custom' => [
      'base hook' => 'node_add_list',
    ],
  ];
}

```

Then my custom template `modules/custom/domain_filter/templates/node-add-list--custom.html.twig` is now applied.
> 4 votes

# Answer
you need add to your theme

```
themes/yourtheme/templates/node-add-list--custom.html.twig

```
> 1 votes

---
Tags: 8, theming
---


# Question
Title: How do I alter a form using an AJAX callback?
I have this callback function triggered by an `onChange()` event in another select box. This code, however, doesn't make the field enabled

```
public static function changeForm(array &$form, FormStateInterface $form_state) : array {
  $form['field_my_custom_field']['#disabled'] = FALSE;
  return $form;
}

```

What am I doing wrong?

# Answer
Ajax Forms in Drupal 7 states:

> Changes to the form must only be made in the form builder function. The callback function must not alter the form or any other state.

In form build/alter, check `$form_state->getTriggeringElement()` for the triggering element and then enable the field.
> 0 votes

---
Tags: 8, forms, ajax
---


# Question
Title: Migrating into a multi-value nested custom field
I have a nested field called released with three values

* By
* When

A node can have multiple releases. However, in the old dataset (d7), each node only had one release and the fields just a part of the node.

I want to now migrate it to the new format in d8

If it was just one value, I could do this

```
released/by: field_released_by
released/when: field_released_at

```

I tried the solution at https://www.freelock.com/blog/john-locke/2017-12/slick-migration-trick-convert-columns-multi-value-field-subfields which didn't help. It tried to look up the dummy fields and caused it to fail.

I can't be the first person to come across this requirement so I am loathe to write a process plugin for it.

Is there a straightforward solution for this? or is a process plugin the only way?

# Answer
> 1 votes
Turns out the answer on that page is correct, just out of date. Instead of Iterator, it needs sub\_process. It also needs a nested array

To create the nested array, I start with a temporary field with the two items it needs

```
tmp_single_published:
  plugin: get
  source:
    - field_published_by
    - field_published_at

```

I then plug it into another array and process it.

```
published:
  plugin: sub_process
  source:
    - '@tmp_single_published'
  process:
    uid: '0'
    at: '1'

```

This worked for me

---
Tags: 8, migrations
---


# Question
Title: How to output unlimited value Field Collection with dates into a Views table format with no duplicates?
I have a Content Type called "Safety Training". It has various fields within it, including a Field Collection named "Dates & Locations", set to unlimited values so they can add infinite date/location pairs.

The two fields defined within the Field Collection are Date (a date ISO field with the ability to enter start/end date and times) and Location (taxonomy). The Date and Location fields are both only single value.

I have a Views page, where I am outputting the individual nodes and grouping them by category of Course Type. This is the format I need the Views table in (from the old site, static HTML):

This is what I have right now in Views (this is in the preview):

How can I separate the date, time, and location into individual table columns called "Class Date", "Location", and "Start/End Time" that will group them like in the old site?

I tried creating a Relationship, choosing "Content: Dates & Locations (field\_safety\_date\_location)", but this immediately creates a duplicate of each item (so there's two Worker Initials, because there's two dates?).

This is the SQL query Views displays:

```
SELECT node.title AS node_title, node.nid AS nid, draggableviews_structure.weight AS draggableviews_structure_weight, 'node' AS field_data_field_safety_date_location_node_entity_type, 'node' AS field_data_field_safety_standard_fee_node_entity_type, 'node' AS field_data_field_safety_late_fee_node_entity_type, 'node' AS field_data_field_registration_link_node_entity_type, 'node' AS field_data_field_safety_category_node_entity_type
FROM
{node} node
LEFT JOIN {draggableviews_structure} draggableviews_structure ON node.nid = draggableviews_structure.entity_id AND draggableviews_structure.view_name = 'safety_environmental_training_schedule_and_fees' AND draggableviews_structure.view_display = 'page_1' AND draggableviews_structure.args = '[]'
WHERE (( (node.status = '1') AND (node.type IN  ('safety_environmental_training')) ))
ORDER BY draggableviews_structure_weight ASC

```

If anyone has any idea, please help! Thank you.

# Answer
Revisiting this two years later after asking if I'd solved it. In short, yes, I did. :)

Here's a screenshot of the final product, still live:

Here's a screenshot of the view as of this morning:

Basically, I created two fields of the Field Collection item: Date, which I was able to access by creating a relationship to the Field Collection. I then changed the formatting of those Field Collections to be what I wanted them to be.

In the Table's settings, I used Grouping field Nr.1 to group them by Content: Category, using the rendered output to group rows. I also enabled sticky table headers so that the headers will follow the table down.

For the class date, I set the formatter to Date Range, and set the format to "F j" for single date, single date all day, single day date range. For Date format for single month date range, I set it to `F j – {j}`, for single year date range I set it to `F j – {F} {j}`. For multiple years date range, I set it to `F j, Y – {F} {j}, Y`

No aggregation or distinct functionality was used in the view, as all of the trainings can only be part of a single category, so I didn't get duplicates. You may need to factor that in. I've always had great results from the Views Distinct module when running into that problem.

The items are sorted first by the taxonomy term weight, and then by item. I also integrated DraggableViews so the editor can re-arrange them as they saw fit rather than alphabetically if they want. (I actually should remove the sort by start date bit, as that doesn't do anything.)

Hope that helps.
> 3 votes

---
Tags: views, entities
---


# Question
Title: How do I check if a user has view access to a node, in a template file?
I'm currently working on a simple LMS in D8 and have already defined the fundamental content types. Among them is a content type called `Course`, which can be considered "Premium" content, i.e. all users may access those fields that contain more general information, but the users will have to buy a subscription for accessing the full content.

To make that possible without any *Premium* module (which, at the moment, have not been ported to Drupal 8), I created a simple grid-view and deactivated "SQL rewriting", which works perfectly, so far. For displaying the nodes in this view, I have created a new view mode, called *gallery*, so that the nodes that are displayed can be styled in a template.
I would like to apply different CSS styles to those nodes in the view that the user may access. I'm not sure if this can be done in the view itself.

Anyway, I'm currently thinking of checking the view permission inside node--course--gallery.html and I would like to add a class to the *article* tag, if access is permitted.

Unfortunately, I can't seem to find the right function for this. I set it up like this:

```
{%
  set classes = [
    node.bundle|clean_class,
    node.isPromoted() ? 'is-promoted',
    node.isSticky() ? 'is-sticky',
    not node.isPublished() ? 'is-unpublished',
    view_mode ? view_mode|clean_class,
    user.hasPermission('view nodes') ? 'is-permitted',
    node.access('view') ? 'is-permitted',
    'clearfix',
  ]
%}

```

Neither `user.hasPermission('view nodes') ? 'is-permitted'` nor `node.access('view') ? 'is-permitted'` seem to have any effect.

Do you have any idea?

# Answer
@Berdir, thanks again: Your comment in the last paragraph brought me on the right track. I now solved the problem as follows:

First, I extended `hook_preprocess_node()` to include

```
$node = $variables['elements']['#node'];
$check = $node->access('view');
$variables['viewaccess'] = $check;

```

(Still not sure, why `$node = Node::load(1);`, as mentioned here, doesn't work, but that's another story.) Then, I simply used

```
{%
  set classes = [
    node.bundle|clean_class,
    node.isPromoted() ? 'is-promoted',
    node.isSticky() ? 'is-sticky',
    not node.isPublished() ? 'is-unpublished',
    view_mode ? view_mode|clean_class,
    viewaccess ? 'is-permitted',
    'clearfix',
  ]
%}

```

instead of my original code. Works perfectly. Thanks to all, who posted helpful comments and replies.
> 3 votes

# Answer
Not really an answer, more like a suggestion for an alternative suggestion where that problem should exist, at least not exactly like that.

The way I handled similar problems (paywall for newspapers in my case) is to *not* use the node access system for this. In my case, I did it using logic in the template/preprocess as well as dynamically switching the view mode. If you can handle it on a field-by-field basis, then you can also implement `hook_entity_field_access()` and deny view access to just those specific fields.

That said, I would expect the method isn't allowed to be called due to the Twig sandbox that only allows is/get method calls, but then I'd kind of expect it to throw an exception.

I guess also that, with my suggestion, you'll need a way to check for something in the template but I would simply do that in `hook_preprocess_node()` and add it as a boolean variable to `$variables`.
> 3 votes

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


# Question
Title: How to use daterange field programmatically?
I activated the **Datetime Range** core module and it works inside a content type, from the BO, but I want to use it in a custom form. I tried :

```
  $form['training_interval'] = [
    '#type' => 'daterange',
    '#required' => TRUE,
    // '#default_value' => 'TODO',
  ];

```

and also *daterange\_default*, *datetime\_range* and any value which could have been relevant giving the module code, but nothing is displayed. I must confess I feel silly...

# Answer
The Datetime Range module provides a new *field* type, 'daterange'. The field is a plugin with provides the Item and List, the Widgets, and the Formatters.

The Item and List are what get actually attached to an entity, either as a base field or a configurable field.

The Widget is what gets used on the entity edit form.

The Formatters get used whenever the field is output, either as part of the parent entity itself or as part of a view.

Note I mentioned *entities* and not *forms*. The Datetime Range module does not provide any new form elements. The Widgets themselves are built around the core 'datetime' and 'datelist' elements (which really have nothing to do with the Datetime module; yes this is seriously confusing).

So, if you have a custom form and want a date range, you are going to have to build this yourself with two 'datetime' elements, and then have some validation rules to make this behave the way you want.
> 4 votes

# Answer
If you programatically need to set a datetime range field when creating a node in a custom form submit handler for example, you need to to fill two values:

The start date `value` and the end date `end_value`.

```
$node = \Drupal\node\Entity\Node::create([
  'type' => $type,
  'title' => $title,
  'field_dates' => [
    'value'=> '2018-02-02T12:12:12',
    'end_value' => '2018-05-05T12:12:12'
  ],
]);
$node->save();

```
> 3 votes

---
Tags: 8, forms
---


# Question
Title: Autosave nodes, when editing or creating new ones, in database
Looking for a way to actually save nodes every x seconds when creating or editing.

I am aware of the Autosave module, which is a great module but it only saves the forms on clientside and has quite it's issues and conflicts with several other modules on my website (jQuery Update, Drag 'n' Drop Upload,...)

So basically I'm looking for a way to save a node automatically in the drupal system, even when creating a new one. Some sort of "draft" function like Gmail uses for unfinished mails.

I think the best shot is to use an ajax script which runs every x seconds, but have no idea how to get it into the database...

Anyone who is aware of a similar module or could point me in the right direction how to achieve this?

# Answer
> 0 votes
I'm unaware of any existing production/beta modules with this functionality.

There's an old blog post available from 2014 that discusses the use of GarlicJS to save the current working version of the Drupal node you're working on in browser local storage:

https://www.shooflydesign.org/buzz/lightweight-autosave-for-drupal-with-garlicjs

Quote:

> Garlic uses HTML5 local storage, supported by all browsers these days, to cache what you're writing as you write it. I like this solution because, unlike WordPress, it doesn't create a bajillion post revisions. The values are stored by your browser until your submit the form, at which point they're cleared out.

If you're open to updating to Drupal8 (likely not, I realize), then there's a new module available called AutoSave\_Form that claims to do something similar to what you're asking for:

https://www.drupal.org/project/autosave\_form

Quote:

> The autosave form module comes with a configuration form, which could be found under Admin-\>Configuration-\>Content-\>Autosave Form. There the interval could be easily adjusted and decide whether autosave is turned on for content or config entity forms or for both. By default it is active only on content entity forms and currently it is being tested only with content entity forms. If support for config entity forms is required please feel free to open an issue if you find some bugs regarding config entity forms.
>
> At the moment the autosave works only for entity forms, but it will be extended to cover regular forms as well.

---
Tags: 7, nodes, ajax
---


# Question
Title: Create a setting.*.php file for every stage of the website
I understand that my question could be opition-based and that it depends on the comfort of every drupal developer so please do not flag it as so !

For every Drupal 8 website i start, i use the below steps from creating/installing the website to configure it to be used in two stages (Dev & Prod)

***On my Local server:***

On my Windows 10, i have installed Git, Composer and Drush.

**Step 1:** I download drupal 8 and its dependencies using the famous command:

```
Composer create-project...

```

**Step 2:**

I point Acuia Dev Desktop to my new Drupal 8 composer website by choosing the **import local drupa site** option with below:

* select the **/web** folder
* create a **new** database

**Step 3:** I launch my drupal 8 composer website using acquia dev desktop and go through the default drupal 8 installer.

**Step 4:**

I copy **default.settings.local.php** from **sites** folder and I paste it into **site/default** folder and then rename it to **settings.dev.php**

**Step 5:** I go to the include file (loc\_sitename\_dd.inc) created by default by Acquia Dev desktop to store the database credentials and other specific configurations and I copy all its contents to **settings.dev.php** file.

**Step 6:** I go to **settings.php** file and:

* Delete the code within in the tag created by Acquia dev desktop at the bottom of the file.
* Add the below lines to the bottom of the file to activate two files **settings.dev.php** and **settings.prod.php**

if (file\_exists(**DIR** . '/settings.dev.php')) { include **DIR** . '/settings.dev.php'; }

if (file\_exists(**DIR** . '/settings.prod.php')) { include **DIR** . '/settings.prod.php'; }

**Step 7** I go to the .gitignore file located one folder above the **web** folder (../sitename) and:

* Remove the line mentioning the **settings.php** file so it will **NOT** be ignored.
* Add the **settings.dev.php** file to be ignored.

**Finally** The **settings.dev.php** file will have configuration such as:

* Site name.
* Database credentials/configuration.
* Disable Caches.
* Enable rebuild.php
* and many more which are specific only to my **LOCAL HOST** (Dev website)

and will only be available on my Local Server.

***On my Web server***

**Step 1** I create a the Production Database with a permissions granted user.

**Step 2** I upload only one time the **settings.dev.php** file to my web server and I rename it to **settings.prod.php**

**Step 3** I edit the \*settings.prod.php\** file and:

* Change the Site name
* Change the database credentials.
* Enable caches.
* and many more configurations related only to the production (online) website.

**Step 4** I go to the .gitignore file located one folder above the **web** folder (../sitename) and:

* Remove the line mentioning the **settings.php** file so it will **NOT** be ignored.
* Add the **settings.prod.php** file to be ignored.

**Finally** The **settings.prod.php** will only be available on my production (online) website.

After all of the above, I start developing my website and push every changes to/from Webserver/Localhost.

Does what i am doing is right/correct ?

Maybe it is not the best method but i would like to ask the experts in this subject about their opinion on my method ?!

Thank you,

# Answer
> 0 votes
I don't see anything wrong about this. Do whatever fits your needs. I do it somehow similar in my multi-site setups:

I have one global `settings.php` file that's the same across all multi-site instances (I version track this one). Then every instance has its own `settings.site.php` (I version track this one as well). And last but not least every instance has its own `settings.local.php` (that's the only one that's ignored by Git as it holds sensitive and environment-specific information). Both of the latter are included by the global `settings.php`:

```
/**
 * Load site-specific override configuration, if available.
 */
if (file_exists($app_root . '/' . $site_path . '/settings.site.php')) {
  include $app_root . '/' . $site_path . '/settings.site.php';
}

/**
 * Load local development override configuration, if available.
 */
if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  include $app_root . '/' . $site_path . '/settings.local.php';
}

```

---

I also make heavy use of the `ScriptHandler.php` that's included into `drupal-composer/drupal-project`. I edited it so it iterates through all multi-site instances and creates a copy of my global `settings.php` in its `createRequiredFiles()` function. And stuff like that. Pretty handy.

# Answer
> 0 votes
Im not sure what's the goal you're trying to achieve with all of those steps? The normal process is for the settings.php not to be in your git repo and then you manually upload the settings.php file to each environment and change the database/other configs in the file. It sounds like you're doing all of these steps to get the settings.php file into git, but whats the benefit?

For example you mention about having caching disabled on your dev server. To achieve this you can uncomment very last few lines in settings.php that says to use a settings.local.php file (Which along with the development.services.yml will disable caches and enable rebuild) Those lines can be uncommented on both dev and prod versions of your settings.php and you just dont upload the settings.local.php to your prod server (It would be ignored by the standard .gitignore that comes with drupal)

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


# Question
Title: Views not respecting Contextual filter and Referenced Entity relationship
This is driving me crazy because it's so simple in Drupal 7.

**Scenario:**

Basic page has a entity referenced field where you can type in Spotlights that should be shown at the bottom of the page.

**View**:

**Relationships** (in order) is the field\_spotlights (which exists on the Basic Page) and field\_spotlight: Content using the previous relationship.

**Contextual filter** is the ID of the node, based on current id of page. Uses the field\_spotlights relationship

**Fields** are the fields that exist in the spotlight, each with a relationship with field\_spotlight: Content.

So the above should show only 3 results if the basic page is viewed and only has 3 spotlights in the entity referenced field.

However 4+ spotlights are showing, it's including the 3 that should show but then duplicates some or shows more.

**UPDATE:**

I've tried using Aggregation too, by adding a Content ID to the fields, and setting the aggregation setting to Count, Count Distinct, and Max/Min.

Also tried setting Distinct in the query settings.

# Answer
> 0 votes
I think you want a View of basic pages (meaning filtered down to Content Type = Basic page) with a contextual filter narrowing down to the current Basic page using the Content ID (NID). Then add in a relationship to Spotlight through the entity reference field. And then for your three fields, make them use the Spotlight relationship.

---
Tags: views, 8
---


# Question
Title: Translation has duplicate admin content listings
When I add a language translate option to a piece of content for French.

Drupal now adds a second listing of that piece of content in the content admin view.

1. Is this the expected behavior?
2. What if you had 10 different language transaltions, would you have 10 times the content listings?
3. Is there a setting or module to only show a single listing and access the translations under that content entities "translate" tab?
4. Is there a better way to translate all my content to another language that could avoid this duplication issue?

# Answer
> 2 votes
1. Yes, that's expected - until filters are applied, that page is designed to list all content on the site, and separate translations are considered separate content.
2. Assuming you had 10 translations for each piece of content, yes, you'd see 10 times the number of listings as you would if you didn't have the translations.
3. That page is powered by a View. You can edit that View and do what you want with it - there's a language filter, maybe you want to set the default for that to the default language, thus allowing people to still browse the other translations using the filters if they want, but keeping things to the default language for most cases. Maybe you want to leave it as-is, but add a "Language" column, to make it easier for admin users to distinguish. There are a lot of options so you can probably get it configured in a way that makes sense for you.
4. No, there's no other way to translate content.

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


# Question
Title: Owl Carousel does not respect Image Styles as set in node display in custom node file
I am trying to get owl carousel to respect the image style declared in the manage display setting for the content type. The code I used to output in the node is:

```
<div class="owl-carousel owl-theme nav-inside box-shadow-custom mt-xl" data-plugin-options='{"items": 1, "margin": 10, "animateOut": "fadeOut", "autoplay": true, "autoplayTimeout": 3000}'>
            <?php foreach($image as $value):?>
                <div>
                    <img src="<?php print file_create_url($value['uri']);?>" class="img-responsive"  alt="">
                </div>
            <?php endforeach;?>
        </div>

```

This renders the slides all different sizes and makes it have a background and causes it to look bad. Does anyone know how to in a custom node file make it respect the image style that I have created that cause it to scale and crop the images. Thanks.

# Answer
> 0 votes
Just to summarize my comments: 1. after getting the images' URLs, you can run them by `image_style_url()` function to get the URLs to the styled images. 2. you need to update the `foreach()` function to include an index such as `foreach($image as $key=>$value)`, and use the `$key` index to loop through the image array.

---
Tags: theming, nodes
---


# Question
Title: Error during entup when removing a field added in entity_base_field_info
I am removing a field that was added using hook\_base\_field\_info:

```
/**
 * Implements hook_entity_base_field_info().
 */
function MYMODULE_entity_base_field_info(EntityTypeInterface $entity_type) {
  $fields = array();

  if ($entity_type->id() === 'node') {
    $field_definitions['some_field'] = \Drupal\Core\Field\BaseFieldDefinition::create('datetime')
      ->setLabel(t('some  field'))
      ->setDescription(t('description'))
      ->setRevisionable(TRUE)
      ->setTranslatable(TRUE)
      ->setSetting('datetime_type', 'date')
      ->setDisplayOptions('view', [
        'label' => 'inline',
        'type' => 'datetime_default',
        'weight' => 1,
        'settings' => [
          'format_type' => 'html_date',
          'timezone_override' => '',
        ],
      ])
      ->setDisplayConfigurable('view', TRUE)
      ->setDisplayOptions('form', array(
        'type' => 'datetime_default',
        'weight' => 10,
      ))
      ->setDisplayConfigurable('form', TRUE);

    return $fields;
  }
}

```

I removed the code and ran `drush entup` I get the following error repeatedly:

drush entup -y The following updates are pending:

node entity type : Some Field field needs to be uninstalled.

// Do you wish to run all pending updates?: yes.

```
 [error]  SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '22906-42845-1-0-de' for key 'PRIMARY': INSERT INTO {field_deleted_revision_01c8f04bcd} (bundle, entity_id, revision_id, langcode, some_field_value, deleted, delta) SELECT base_table.type AS bundle, entity_table.nid AS entity_id, entity_table.vid AS revision_id, entity_table.langcode AS langcode, entity_table.compliance_approval_date AS some_field_value, :deleted AS deleted, :delta AS delta
FROM
{node_field_revision} entity_table
INNER JOIN {node_field_data} base_table ON entity_table.nid = base_table.nid
WHERE entity_table.some_field IS NOT NULL FOR UPDATE; Array
(
    [:deleted] => 1
    [:delta] => 0
)

```

Any idea why this is caused and how one might go about fixing it?

# Answer
> 1 votes
`drush entup` is the wrong tool (I hope you have a database backup from before you've executed this command). After uninstalling the module containing the node base field, wait until cron has gradually purged the existing field data, see the change record Base fields with existing data can now be uninstalled.

# Answer
> 1 votes
I was able to remove the base field without uninstalling the module after looking at some core examples. Note this need to be used carefully as it may have unintended consequences:

I first added a hook update:

```
/**
 * Remove my_field
 */
function my_module_update_8107() {
  $field_name = 'my_field';

  $tables_to_update = [
    'node_field_data',
    'node_field_revision'
  ];

  $database = Drupal::database();
  $entity_definition_update_manager = Drupal::entityDefinitionUpdateManager();

  // Ensure that the data from the  field is deleted
  // so that the field can safely be deleted.
  foreach ($tables_to_update as $table_to_update) {
    if ($database->schema()->fieldExists($table_to_update, $field_name)) {
      $database->update($table_to_update)
        ->fields([$field_name => NULL])
        ->execute();
    }
  }

  // Delete the storage definition if it was defined before.
  $storage_definition = $entity_definition_update_manager->getFieldStorageDefinition($field_name, 'node');
  if ($storage_definition) {
    $entity_definition_update_manager->uninstallFieldStorageDefinition($storage_definition);
  }
}

```

Then I removed the all the `core.base_field_override.node.[TYPE].my_field` yaml files. This caused the configuration import to fail with an error reported to d.o. I applied the patch at the link and configuration import now work correctly. And finally I removed the field settings from all the display yaml files.

---
Tags: 8, entities
---


title: How alter submit user_pass_reset?

text:
# Question
Title: How alter submit user_pass_reset?
I can alter every form submit in Drupal with this hook:

> hook\_form\_alter

On the `user_pass_reset` form there is a button for auto-login from a link.

I need to add some custom logic just after the user click on the button "Login".

Here's how I tried to do that :

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

   if($form_id == 'user_pass_reset')
    {
        $form['actions']['submit']['#submit'][] = 'tools_compte_mot_de_passe_reset_submit';
        $form['#submit'][] = 'tools_compte_mot_de_passe_reset_submit';
    }
}

```

I have set the 2 form methods because I trying to understand which is called.

> My custom submit :

```
function tools_compte_mot_de_passe_reset_submit($form, \Drupal\Core\Form\FormStateInterface &$form_state)
{
    exit();
}

```

My custom submit is never called... if I try on a different form, that works, but not on this one.

Where i am wrong ?

# Answer
From \Drupal\user\Form\UserPasswordResetForm::buildForm:

```
<?php
$form['#action'] = Url::fromRoute('user.reset.login', [
  'uid' => $user->id(),
  'timestamp' => $timestamp,
  'hash' => $hash,
])->toString();
?>

```

If you look at the form in your browser, you can see that it directly POSTS to that other route. as a result of that, your submit isn't called because for that, it would need to actually submit to itself again.

That then points to \Drupal\user\Controller\UserController::resetPassLogin(), which calls user\_login\_finalize(), which calls user\_login().

Depending on what you want to do on submit, you can either do in hook\_user\_login() or by altering that route.
> 1 votes

---
Tags: 8, forms
---


title: How to check Drush version?

text:
# Question
Title: How to check Drush version?
How can I identify what version of Drush is installed on a given system?

# Answer
Assuming you have Drush installed and working properly, just type `drush status` in your command prompt. It will give you drush version as well as Drupal version info. If you have aliases set up for remote (or local) sites, you can run `drush @alias status` and it will give you the status info for that remote system.
> 49 votes

# Answer
`drush --version` works in Drush 4 too.
> 21 votes

# Answer
You can also use `drush st` as a shortcut (alias) for `drush status`

Cheers.
> 5 votes

# Answer
If your Drush installation is not working and you have an older version of drush, then neither `drush status` nor `drush --version` will help. In that case go to the directory where drush is installed (~/.drush/drush on my system) and look at the drush.info file. There you will see a line that says `version=3.0` (or whatever)
> 2 votes

# Answer
You can check Drush version with "drush status" command inside your application directory or outside your application directory, the difference will be when you are inside application directory you will get more information,

Check below links for better understanding on Drush commands,

http://mydons.com/commonly-used-drush-commands-drupal-developers-must-know/ http://mydons.com/install-and-upgrade-drush-version-in-linux/
> 0 votes

# Answer
```
drush --version

```

Works for Drush 8 and Drush 7 too.

You can also see the other global options by

```
drush topic core-global-options

```
> 0 votes

---
Tags: drush
---


title: Update website from 8.0.0 to 8.6.1

text:
# Question
Title: Update website from 8.0.0 to 8.6.1
I'm pretty new to Drupal and I'm trying to update a website from **8.0.0** to **8.6.1**.

I've followed the guide here: https://www.drupal.org/docs/8/update/update-core-via-composer

The composer part went pretty well. However, when I run the command:

```
drush updatedb

```

I get the following error:

```
Command updatedb needs a higher bootstrap level to run - you will need to invoke drush from a more functional Drupal environment to run this command.
The drush command 'updatedb' could not be executed.

```

I've read online that I had to use `cc all` first, but when I do:

```
drush cc all

```

I get the following:

```
No Drupal site found, only 'drush' cache was cleared.

```

I thought that I might have to update my Drush version since I was running on **8.1.17** because version 9.x was not supporting Drupal 8.0.0. Therefore, I updated to **9.4.0**.

Now when I execute the **updatedb** command, I get the following:

```
Bootstrap failed. Run your command with -vvv for more information.

```

And the stacktrace:

```
Exception trace:
 Drush\Boot\BootstrapHook->initialize() at /root/.composer/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php:34
 Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->callInitializeHook() at /root/.composer/vendor/consolidation/annotated-command/src/Hooks/Dispatchers/InitializeHookDispatcher.php:27
 Consolidation\AnnotatedCommand\Hooks\Dispatchers\InitializeHookDispatcher->initialize() at /root/.composer/vendor/consolidation/annotated-command/src/CommandProcessor.php:117
 Consolidation\AnnotatedCommand\CommandProcessor->initializeHook() at /root/.composer/vendor/consolidation/annotated-command/src/AnnotatedCommand.php:391
 Consolidation\AnnotatedCommand\AnnotatedCommand->initialize() at /root/.composer/vendor/symfony/console/Command/Command.php:217
 Symfony\Component\Console\Command\Command->run() at /root/.composer/vendor/symfony/console/Application.php:964
 Symfony\Component\Console\Application->doRunCommand() at /root/.composer/vendor/symfony/console/Application.php:248
 Symfony\Component\Console\Application->doRun() at /root/.composer/vendor/symfony/console/Application.php:148
 Symfony\Component\Console\Application->run() at /root/.composer/vendor/drush/drush/src/Runtime/Runtime.php:112
 Drush\Runtime\Runtime->doRun() at /root/.composer/vendor/drush/drush/src/Runtime/Runtime.php:41
 Drush\Runtime\Runtime->run() at /root/.composer/vendor/drush/drush/drush.php:66
 require() at /root/.composer/vendor/drush/drush/drush:4

```

And if I open my drupal website, I'm getting a fatal error:

> Fatal error: Class 'Drupal\Component\Utility\String' not found in /home/username/public\_html/themes/name/name.theme on line 548

I'm executing all commands from the root of my drupal website. I've also tried to execute it from `sites/default/`.

---

# Update

I've restored to the version before the update, then performed the following steps in order:

1. Updated composer.json to `"drupal/core": "8.6.1"`
2. Executed the command: `composer update drupal/core --with-dependencies`
3. Changed directory into the `core/` folder
4. Executed the command: `composer install` in the subdirectory
5. Opened **domain.com/update.php**.

If I don't perform step 3 & 4, I get an error when trying to load my website saying that it cannot load the file `core/vendor/autoload.php`.

Then I'm still getting the same fatal error as mentioned above.

## composer.json

This is the original composer.json before the update.

```
{
  "name": "drupal/drupal",
  "description": "Drupal is an open source content management platform powering millions of websites and applications.",
  "type": "project",
  "license": "GPL-2.0+",
  "require": {
    "composer/installers": "^1.0.20",
    "drupal/core": "8.0.0-beta6"
  },
  "minimum-stability": "dev",
  "prefer-stable": true,
  "repositories": [],
  "config": {
    "preferred-install": "dist",
    "autoloader-suffix": "Drupal8"
  },
  "extra": {
    "_readme": [
      "This is an example file to show how a Drupal website can be managed via",
      "Composer. It does not work out of the box but requires a Git subtree",
      "split of the core directory to be added to the repositories",
      "section above."
    ]
  }
}

```

# Answer
I tried to replicate the steps you've done.

1. I installed Drupal v8.0.0
2. I installed Bootstrap Theme
3. I installed some modules
4. I used the `composerize-drupal` plugin to create a composer.json file

And from now, things started to get nasty. First of all, I ran the command in the plugin README:
`composer composerize-drupal --composer-root=. --drupal-root=.`
It successfully created a compsoer.json file, however:
\- It updated Drupal core to 8.6.1 (without confirmation)
\- It didn't add the contributed modules or themes that I've manually installed and enabled through Drupal's admin
So, I tried to run my old friend `update.php` script, but it broke in the middle, because one of the modules I installed was using obsolete code.
So, I ran `composer require drush/drush` to install Drush 9 locally, and then I uninstalled it via drush then ran `drush updbatedb` which went smoothly afterwards.
My point is: This process is very buggy and can lead to disasters.
Many things can go wrong in the middle due to PHP version, current contributed modules version, etc.
My suggestion to you is to restore your installation from backup, create a local copy, and do the whole process again. Also, you can try to run `your_site_domain/update.php` script on your current installation.
> 0 votes

# Answer
For Drush to be able to understand your site it has to be run from a location within the site. So from the root web directory, for example: /home/user123/public\_html/

Run Drush commands in the user (/home/user123/)or system (/) root directories will not work.
> 0 votes

---
Tags: 8, drush
---


# Question
Title: How can I update Drupal core and all modules / themes in one go from the command line?
On a LAMP environment, I have a Drupal site which uses the default theme and a few stable contributed modules. Nothing is customized, and I have daily backups so I don't "fear" of updating.

How could I update core, modules, and themes in one go from the command line when `drush up` no longer is an option?

# Answer
Assuming you are using Composer to maintain your Drupal 8 installation, you can use the following command to update core and all modules (and dependencies).

```
composer update drupal/* --with-dependencies

```

If you started the project from drupal-composer/drupal-project, the command becomes the following.

```
composer update drupal/* webflo/drupal-core-require-dev --with-dependencies

```

I recommend reading Updating Drupal core via Composer and Updating Modules and Themes using Composer.

After updating, don't forget to run the updates and rebuild the cache.

```
drush updatedb
drush cache:rebuild

```

If you started the project from *drupal/drupal* as the user guide says, you are in trouble, since *drupal/core* isn't listed as installed. You could try to use Composerize Drupal to fix the problem.
If you started your project from a tar-ball, you also need use Composerize Drupal if you don't plan to manually update forever.

Drush 9 and later doesn't support updating core or modules. It will tell you to use Composer. Reading the Drush docs is very useful.
> 17 votes

# Answer
Using Composer as described in Using Composer to Install Drupal and Manage Dependencies, it's three steps.

```
composer update drupal/core --with-dependencies
drush updb -y
drush cr

```

See also Updating Drupal core via Composer for more details.
> 1 votes

---
Tags: 8, updating
---


# Question
Title: Adding an image base field to custom content entity
consider the following situation: I have created a custom content entity with several base fields (string and string\_long fields) and it works flawlessly. In addition I want the entity to hold an image field which I defined the same way I did with the other fields:

```
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

    …

    $form_options = array(
        'type' => 'string',
        'weight' => $key,
    );

    $view_options = array(
        'label' => 'hidden',
        'type' => 'string',
        'weight' => $key,
    );

    …

    $type = 'image';
    $settings = array();
    $form_options['type'] = 'image_image';
    $view_options['type'] = 'image_image';

    …

    $fields[$fieldname] = BaseFieldDefinition::create($type)
        ->setLabel(t($sections['labels'][$key]))
        ->setDescription(t($sections['descriptions'][$key]))
        ->setSettings($settings)
        ->setDisplayOptions('view', $view_options)
        ->setDisplayOptions('form', $form_options);
}

```

Now, why would I get the errors `Notice: Undefined index: target_type in Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::propertyDefinitions() (line 70 of core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php).` and `Drupal\Component\Plugin\Exception\PluginNotFoundException: The "" entity type does not exist. in Drupal\Core\Entity\EntityManager->getDefinition() (line 256 of core/lib/Drupal/Core/Entity/EntityManager.php).`?

Anyone has a hint? Thank you in advance!

# Answer
> 4 votes
Looks like you need to specify the target\_type.

It should get the default from FileItem::defaultStorageSettings(), I am not sure why that doesn't work.

Unrelated, but note that you should not call t() like that, as it makes it impossible for potx to extract translatable strings from your code. Also, watch out for https://www.drupal.org/node/2363099, you need to update it to use nt() then.

Edit: Turns out, the problem is that the code was using setSettings(), which is considered problematic because it replaces all existing settings, including defaults. Switching to setSetting() for specific settings should solve it.

# Answer
> -1 votes
You are using wrong formatter type, these is no "image\_image" formatter so

```
$view_options['type'] = 'image_image';

```

should be

```
$view_options['type'] = 'image';

```

for more on how to get proper formatters ids look here https://www.drupaldump.com/custom-entities-and-how-get-setdisplayoptions-types

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


# Question
Title: The database is not bootstrapped in another docker container
The following problem occurs when running certain Drush commands, such as `drush en features` which outputs:

> Command pm-enable needs a higher bootstrap level to run - you will need to invoke drush from a more functional Drupal environment to run this command.
> The drush command 'en features' could not be executed.
> Drush was not able to start (bootstrap) the Drupal database.
> Hint: This may occur when Drush is trying to:
>
> * bootstrap a site that has not been installed or does not have a configured database. In this case you can select another site with a working database setup by specifying the URI to use with the --uri parameter on the command line. See `drush topic docs-aliases` for details.
> * connect the database through a socket. The socket file may be wrong or the php-cli may have no access to it in a jailed shell. See http://drupal.org/node/1428638 for details.
>
> Drush was attempting to connect to:
>
> Drupal version: 7.58
> Site URI: http://default
> Database driver: mysql
> Database hostname: mysql
> Database port: Database username: default
> Database name: default
> PHP executable: /usr/bin/php PHP configuration: /etc/php/7.2/cli/php.ini
> PHP OS: Linux
> Drush script: /var/www/vendor/drush/drush/drush.php
> Drush version: 8.1.17
> Drush temp directory: /tmp
> Drush configuration:
> Drush alias files:
> Drupal root: /var/www
> Drupal Settings File: sites/default/settings.php
> Site path: sites/default

This problem has been reported previously, but in different contexts, not in the specific setup I am working with, which consists of separate docker containers on a linux hosting server.

* Apache 2
* ElasticSearch
* Workspace
* PHP
* MySQL

All the docker containers are running, as well as the (development) website that is built with drupal, which does connect to the database. Drush had previously been used for setting things up, but something seems to have broken during the development process. Drush had been added to the project using composer, as suggested on Install a site-local Drush and Drush Launcher.

The error seems independent of the directory where the command is executed. Moreover, the settings.php file exists at the path mentioned in the output above and contains the correct database configuration.

Finally, `drush sql-cli` returns the following message.

> sh: 1: mysql: not found
> SQL client error occurred.

Do you have any idea on what the problem might be?

# Answer
Ok, this is solved now, thanks to leymannx and hansfn. I had to also install mysql-client in the workspace container, where drush was being executed from, in addition to the mysql-server running in its own container; mysql-client must have previously been present in the workspace container for a different reason, but some containers were stopped and restarted at some point, so any container-specific installations must have disappeared.
> 0 votes

---
Tags: drush
---


title: How can I bootstrap?

text:
# Question
Title: How can I bootstrap?
How can I bootstrap Drupal 8 from an external script?

This an example script from the RabbitMQ Work Queues tutorial.

```
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('task_queue', false, true, false, false);
echo " [*] Waiting for messages. To exit press CTRL+C\n";
$callback = function ($msg) {
  echo ' [x] Received ', $msg->body, "\n";
  sleep(substr_count($msg->body, '.'));
  echo " [x] Done\n";
  $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};

$channel->basic_qos(null, 1, null);
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);

while (count($channel->callbacks)) {
  $channel->wait();
}

$channel->close();
$connection->close();

```

Within a worker script like this, I need to be able to create nodes.

How can I bootstrap Drupal 8 in this script?

Php Access User Data from external script? and Bootstrap from external script bootstraps passing a fake request to the kernel, which to me looks like a work-around.

In Drupal 7 you could do something like this, apparently.

```
// Bootstrap Drupal.
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

```

# Answer
I ended up inheriting the kernel and will adjust it as needed be.

Something like:

```
namespace Drupal\Core;

use Drupal\Core\Site\Settings;

class DrupalCliKernel extends DrupalKernel {

  public function bootstrap() {
    static::bootEnvironment();
    $this->setSitePath('sites/default');
    Settings::initialize($this->root, 'sites/default', $this->classLoader);
    $this->boot();
  }

}

```

And then:

```
use Drupal\Core\DrupalCliKernel;

$autoloader = require_once 'autoload.php';

$kernel = new DrupalCliKernel('prod', $autoloader);
$kernel->bootstrap();

// Drupal is bootstrapped now.

```

Not yet sure if I miss something important, but I am most likely not using this, but instead relying on using HTTP requests that the worker will use as Drupal is too coupled to the HTTP request. Just putting it out if someone come here to try to accomplish something similar and want a jump-start.
> 1 votes

---
Tags: 8, bootstrapping, external-scripts
---


title: Custom form set custom template

text:
# Question
Title: Custom form set custom template
I have created a custom module for **custom form**, form is created successfully. But when I open this form then it's open under **MYTHEME/template/layout/page.html.twig** I just need to open this form in other template.

Please help me.

# Answer
Actually your form would be in `core/modules/system/templates/form.html.twig`: if you want to override it to twig in your module try the following :

1. Implement hook\_theme\_suggestions\_alter

```

    function YourModuleName_theme_suggestions_alter(array &$suggestions, array $variables, $hook)
    {
        if (isset($variables['element']) && isset($variables['element']['#type']) && $variables['element']['#type'] == 'form') {
            $original_theme_hook = $variables['theme_hook_original'];
            array_unshift($suggestions, $original_theme_hook . '__' . str_replace('-', '_', $variables['element']['#id']));
        }
    }

```
2. Implement hook\_theme

```

function YpurModuleName_theme($existing, $type, $theme, $path) {
    return [
       'form__YouFormId_form' => [
            'base hook' => 'form',
        ],
    ];
}

```
3. Create a folder Called `templates`.
4. Copy and past `core/modules/system/templates/form.html.twig` to your `templates` folder.
5. Rename `form.html.twig` to `form--YourFormId-form.html.twig` .
6. Rebuild Cache.
> 1 votes

---
Tags: 8, forms
---


# Question
Title: How to remove backup folders from the sites directory following a site restore
When I break my site I create a new one from a backup and give it a different name from the original, for example:

I do a fresh install of drupal and call the site 'mysite' then a week later I break it. I then restore a backup and call it 'mysiteRevA' when this one breaks I use a backup of 'mysiteRevA' and create 'mysiteRevB' and so on. I'm not very good at fixing errors so I do this a lot!

The issue is that say I'm working on 'mysiteRevC',if I look in the sites folder there are folders called 'mysite' and 'mysiteRevA' and 'mysiteRevB' and 'mysiteRevC' reflecting all the restorations I have done. My first question is how can I remove these additional folders and question 2 is what should I do to avoid this in the future.

It might be that every restore has to use the original name, but wouldn't this mean overwriting the original site? I don't want to do this because I worry that if the restore doesn't work and I've deleted the original I'll have lost everything.

# Answer
> -2 votes
I went into the sites folder and just deleted the folders which reference a previous restore point and everything still works fine.

---
Tags: backups
---


title: Custom sort with search api

text:
# Question
Title: Custom sort with search api
I have created a ViewsSort plugin that works on a normal view (like *taxonomy\_term*) but not on a view based on **Search API** : it is not present when I click on "Add sort" in BO. This sort is used to create a custom order of content types, and I use hook\_views\_data\_alter() to provide it to views :

```
/**
 * Implements hook_views_data_alter().
 */
function mymodule_views_data_alter(array &$data) {

  // works on classic view
  $data['node_field_data']['inspiration_first'] = array(
    'title' => t('Custom search sort in page tags with inspiration first'),
    'group' => t('Search'),
    'help' => t('Sort content types in this order : dossier_inspiration, dossier_conseil, produit.'),
    'sort' => array(
      'field' => 'type',
      'id' => 'inspiration_first',
    ),
  );

  // doesn't work on search api view
  $data['search_api_db_default_search_content_index_content_type']['inspiration_first'] = array(
    'title' => t('Place inspiration first for custom search'),
    'group' => t('Search'),
    'help' => t('Sort content types in this order : dossier_inspiration, dossier_conseil, produit.'),
    'sort' => array(
      'field' => 'value',
      'id' => 'inspiration_first',
    ),
  );

}

```

Any idea ? Some sorts like Random work also on search api and I've provided the good table, I think (search\_api\_db\_default\_search\_content\_index\_content\_type).

# Answer
> 2 votes
Go to

**Home -\> Administration -\> Configuration -\> Search and metadata -\> Search API**

& Edit your Index Search. Then your URL will be like below. In my case it's

**Content Search**

/admin/config/search/search-api/index/content\_search/

So I'm using

`$data['search_api_index_content_search']['inspiration_first']`

I think in ur case it will be

`$data['search_api_index_search_content_index']['inspiration_first']`

Please share your URL if didn't worked.

---
Tags: 8, search
---


# Question
Title: How to use dependency injection to apply a class static method?
I'm building a custom form (extending ConfigFormBase) and using static method File::load($fid). How to use dependency injection to call this method? Thank you!

# Answer
> 3 votes
In **\__construct()** you can implement like this:

```
use Drupal\Core\Entity\EntityTypeManagerInterface;

public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
}

```

and **create()** method

```
public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
    );
}

```

You can use this service to get the file storage:

```
$file_storage = $this->entityTypeManager()->getStorage('file');

```

and then load the file:

```
$file = $file_storage->load($fid);

```

# Answer
> 1 votes
This is my final code implementation as I was having this sort of warning:

> Expected \Drupal\file\FileStorageInterface, got object Invocation parameter types are not compatible with declared.

So I updated create method to get the file storage directly:

```
class MyClassForm extends ConfigFormBase {

  /**
   * File storage for files.
   *
   * @var \Drupal\file\FileStorageInterface
   */
  protected $fileStorage;

  /**
   * SiteSettingsForm constructor.
   *
   * @param \Drupal\file\FileStorageInterface $file_storage
   *   File storage for files.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory) {
    parent::__construct($config_factory);
    $this->fileStorage = $entity_type_manager->getStorage('file');
  }

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

```

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


title: Import a date from CSV to Date field

text:
# Question
Title: Import a date from CSV to Date field
I'm working on a Druapl 8 project and I'm trying to execute a migration which serve to import content of a basic content type, the content type has a field of type Date and the associated field in my CSV source file has the format "dd-mm-yyyy", I used the 'format\_date' plugin to migrate the date as bellow:

```
process:
  field_date:
    plugin: format_date
    from_format: 'd-m-Y'
    to_format: 'd/m/Y'
    source: Date

```

with `field_date` is the machine name of my content type date field, and Date is the field name in my csv file: source.csv

```
title,Date
title 1,12-01-2017
title 2,13-03-2018

```

After migration the content has been created as it should but with date value as bellow:

Any help please!

# Answer
You need to convert source date from **d-m-Y** to **Y-m-d**

```
process:
  field_date:
    plugin: format_date
    from_format: 'd-m-Y'
    to_format: 'Y-m-d'
    source: Date

```

because default field Date use format **Y-m-d** to store date. and **Y-m-d\TH:i:s** to store datatime.

Form display just show default pattern (mm-dd-yyyy) of html5 input date
> 3 votes

---
Tags: 8, migrations
---


# Question
Title: How to fix menu links going below the fold?
How do you fix menu links in the admin toolbar (drop down menus) from going below the fold when you have many different bundles?

For example, the "Paragraph Types" submenus often go below the fold because they sit alphabetically low on the "Configuration" drop-down. If you have many paragraph types, it's hard to access them from the drop-down submenus.

# Answer
You can create a new dropdown under the entity type ("Paragraphs types") that groups the links by first letter. Also, you can can change the weight of your item, and even move it out of being nested under configuration.

In the following example, we look for all the children of 'entity.paragraphs\_type.collection' and we nest them under a copy of 'entity.paragraphs\_type.collection' labeled with the first letter of the paragraphs underneath it.

```
function mymodule_menu_links_discovered_alter(&$links) {

  $links['entity.paragraphs_type.collection']['weight'] = 8;
  $links['entity.paragraphs_type.collection']['parent'] = 'system.admin';

  foreach($links as $key => $link) {
    if (!empty($link['parent']) && $link['parent'] == 'entity.paragraphs_type.collection') {
      $first_letter = substr($link['title']->render(),0, 1);
      $links['entity.paragraphs_type.collection.' . $first_letter] = [
        'title' => $first_letter,
        'route_name' => 'entity.paragraphs_type.collection',
        'menu_name' => 'admin',
        'parent' => 'entity.paragraphs_type.collection'
      ];
      $links[$key]['parent'] = 'entity.paragraphs_type.collection.' . $first_letter;
    }
  }
}

```

Here's the same alphabetical grouping technique on vocabularies:

```
    foreach($links as $key => $link) {
      if (!empty($link['parent']) && $link['parent'] == 'entity.taxonomy_vocabulary.collection') {
        $first_letter = substr($link['title']->render(),0, 1);
        $links['entity.taxonomy_vocabulary.collection.' . $first_letter] = [
          'title' => $first_letter,
          'route_name' => 'entity.taxonomy_vocabulary.collection',
          'menu_name' => 'admin',
          'parent' => 'entity.taxonomy_vocabulary.collection'
        ];
        $links[$key]['parent'] = 'entity.taxonomy_vocabulary.collection.' . $first_letter;
      }
    }

```

If you move the paragraph types to it's own drop-down, as in the example above, you'll want to style an icon for it.

```
.toolbar-icon-entity-paragraphs-type-collection:before,
.toolbar-icon-entity-paragraphs-type-collection:active:before,
.toolbar-icon-entity-paragraphs-type-collection.is-active:before {
  background-image: url(../../../../core/themes/stable/images/core/icons/787878/wrench.svg);
}

```

Here's my current version, which adds an "Add Paragraph Type" link:

```
/**
 * Implements hook_menu_links_discovered_alter().
 */
function mymodule_menu_links_discovered_alter(&$links) {

  // Move paragraphs to its own drop down.
  $links['entity.paragraphs_type.collection']['weight'] = -7;
  $links['entity.paragraphs_type.collection']['parent'] = 'system.admin';
  $links['entity.paragraphs_type.collection']['title'] = 'Paragraphs';

  // Move taxonomy to its own drop down.
  $links['entity.taxonomy_vocabulary.collection']['weight'] = -7;
  $links['entity.taxonomy_vocabulary.collection']['parent'] = 'system.admin';
  $links['entity.taxonomy_vocabulary.collection']['title'] = 'Taxonomy';

  $links['entity.paragraphs_type.collection.add'] = [
    'title' => new TranslatableMarkup('Add Paragraph Type'),
    'route_name' => 'paragraphs.type_add',
    'menu_name' => 'admin',
    'parent' => 'entity.paragraphs_type.collection',
    'weight' => -100,
  ];

  // Break paragraphs into groups by starting letter.
  foreach ($links as $key => $link) {
    if (!empty($link['parent']) && $link['parent'] == 'entity.paragraphs_type.collection') {
      $first_letter = substr($link['title']->render(), 0, 1);

      $links['entity.paragraphs_type.collection.' . $first_letter] = [
        'title' => $first_letter,
        'route_name' => 'entity.paragraphs_type.collection',
        'menu_name' => 'admin',
        'parent' => 'entity.paragraphs_type.collection',
      ];
      $links[$key]['parent'] = 'entity.paragraphs_type.collection.' . $first_letter;
    }
  }

  foreach ($links as $key => $link) {
    if (!empty($link['parent']) && $link['parent'] == 'entity.taxonomy_vocabulary.collection') {
      $first_letter = substr($link['title']->render(), 0, 1);
      $links['entity.taxonomy_vocabulary.collection.' . $first_letter] = [
        'title' => $first_letter,
        'route_name' => 'entity.taxonomy_vocabulary.collection',
        'menu_name' => 'admin',
        'parent' => 'entity.taxonomy_vocabulary.collection',
      ];
      $links[$key]['parent'] = 'entity.taxonomy_vocabulary.collection.' . $first_letter;
    }
  }

}

```
> 3 votes

# Answer
I want to add a second answer, because I've been adjusting my code above, and discovered you can create a custom toolbar to house your paragraph links. I have created a custom module that does it for you:

https://www.drupal.org/project/entity\_toolbar
> 0 votes

---
Tags: 8, navigation
---


# Question
Title: Error in Italian localization for datepicker
Well, this is very funny :)

I have a datepicker localized in Italian. It works correctly, except that, apparently, the abbreviation for Wednesday was translated as it were a personal pronoun, since *noi* is the Italian translation for *we*.

>

The abbreviation for Wednesday is correctly set in *core/assets/vendor/jquery.ui/ui/i18n/datepicker-it.js*, but this file is not inserted in the HTML, so I suppose the translation is taken somewhere else.

In my libraries dependencies I have the following code.

```
dependencies:
  - core/jquery
  - core/jquery.once
  - core/jquery.ui.datepicker
  - core/drupal.locale.datepicker

```

Without the last line, the date picker is in English.

Am I doing something wrong?

# Answer
> 0 votes
I think you should download Italian initialisation jQuery UI js file and attached to your concerned page in your module or theme.

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


# Question
Title: Is the Workflow module a Symfony component?
In Drupal 8.5, is the Workflow module a component from Symfony?

I ask because I thought it might help me to learn the basics from the Symfony Workflow component, but looking at the core directory and the composer.json file I saw this.

```
"symfony/class-loader": "~3.4.0",
"symfony/console": "~3.4.0",
"symfony/dependency-injection": "~3.4.0",
"symfony/event-dispatcher": "~3.4.0",
"symfony/http-foundation": "~3.4.14",
"symfony/http-kernel": "~3.4.14",
"symfony/routing": "~3.4.0",
"symfony/serializer": "~3.4.0",
"symfony/translation": "~3.4.0",
"symfony/validator": "~3.4.0",
"symfony/process": "~3.4.0",
"symfony/polyfill-iconv": "^1.0",
"symfony/yaml": "~3.4.5",

```

In the *replace* section, I noticed the following line.

```
"drupal/workflows": "self.version",

```

# Answer
No, the Workflow module is not a Symfony component.

As for what you found, the first list are the Drupal core dependencies, which include its dependencies from Symfony components.
Under the *replace* section, you just find a list of Drupal core modules. You can understand they are modules because they are listed as `drupal/<module machine name>`, while the Workflow component would be listed as *symfony/workflow*.
> 2 votes

---
Tags: 8, workflows
---


# Question
Title: Manually removing database records of a module
I inherited a Drupal 7 site that appears to have a history.

I'm receiving the following error when updating modules or clearing the cache:

> PDOException: SQLSTATE\[42S02\]: Base table or view not found: 1146 Table 'website\_staging.search\_api\_server' doesn't exist: SELECT base.id AS id, base.name AS name, base.machine\_name AS machine\_name, base.description AS description, base.class AS class, base.options AS options, base.enabled AS enabled, base.status AS status, base.module AS module FROM {search\_api\_server} base WHERE (base.status IN (:db\_condition\_placeholder\_0, :db\_condition\_placeholder\_1, :db\_condition\_placeholder\_2)) ; Array ( \[:db\_condition\_placeholder\_0\] =\> 3 \[:db\_condition\_placeholder\_1\] =\> 2 \[:db\_condition\_placeholder\_2\] =\> 6 ) in EntityAPIController-\>query() (line 187 of /home/website/apps/api/docroot/sites/all/modules/entity/includes/entity.controller.inc).

**The question is: where in the database do I need to remove any and all traces that point to this table?**

Background:

I figured this was just a module that somehow did not install its tables right somehow. Uninstall, reinstall and done, right?

Two problems:

1. Uninstalling a module also yields this error, and does not work
2. The Search API module (http://drupal.org/project/search\_api) never was installed at all

It appears the previous developers created a custom module, and named it 'search\_api'. My guess is that later they went and did a blanket update of the site modules using drush, and starting updating the custom module far enough to install something to the database. Then they realized their mistake, and replaced the custom module in its original location (but did not rename it).

Nowhere in my modules is there a pointer to the search\_api\_server table, so it must be somewhere in the database.

So my plan as it stands is:

1. Somehow fix the error
2. Uninstall the custom search\_api module
3. Rename the custom search\_api module and reinstall

And I need some help with step 1

# Answer
I second the voices above.

My recent experience to get out of the pdoexception is crude and more akin to a 'big hammer' rather than anything elegant.

1. make a backup of your database and the code
2. either use a UI like phpmyadmin OR sql if you feel more comfortable with code
3. create the table it says is missing (website\_staging.search\_api\_server)
4. add at least 1 variable (id)... take the defaults of integer
5. you don't have to add a value to the table, just create it and add the definition for the id variable
6. try your uninstall again

In my case for my custom module practice development, I also had to add a second variable because there were two 'keys' on the table. But I'd try this with just the one variable (id)... hopefully it will be enough to get you out of the PDOexception and onward to module/code review.

The concept here is to give Drupal the minimum info it needs via manual PHP/SQL creation so it can 'connect the dots' and move forward to execute your commands (uninstall). JW
> 2 votes

---
Tags: 7, installation
---


# Question
Title: Are the revision settings on a content type respected when the content is changed programatically?
I want to practice making some bulk updates via code, but I also want the option of reverting back to an earlier versions in case some of the changes are incorrect.

Are the revision settings respected when revisioning by default is enabled for a content type?

# Answer
No, not by default, if you're using `node_load()` & `node_save()`, without any other code, it will not retrieve the content type's revision setting. For example:

```
$my_node = node_load(123);
$my_node->title = 'new title';
node_save($my_node);

```

`node_save()` uses the `$my_node->revision` property to determine if it's creating a new revision. In the above example, `$my_node` will not have the `revision` flag set from a `node_load()` retrieval.

If you manually set the `$my_node->revision` to `TRUE` it will do this:

```
$my_node = node_load(123);
$my_node->revision = TRUE;
$my_node->title = 'new title';
node_save($my_node);

```
> 3 votes

---
Tags: 7, nodes
---


# Question
Title: How can I get the first character of the node title?
In the node--my-content-type.html.twig, I want to add the French indefinite article to the title, which depends on the first letter of the word to which the article is added.

* Banane =\> de Banane
* Orange =\> d'Orange

So based on the Twig documentation, I'm trying to use one of the following code lines.

```
{% if label|first|lower == o %}

```

```
{% if label|slice(0, 1)|lower == o %}

```

```
{% if label[:1]|lower == o %}

```

None of them work.

How can I get the first character of the node title?

# Answer
> 1 votes
You could try this code:

```
/**
 * Implements hook_preprocess_HOOK().
 * @param $variables array
 */
function TEMPLATE_preprocess_node(&$variables)
{
  /** @var \Drupal\node\Entity\Node $node */
  $node = $variables['node'];
  $title = $node->getTitle();
  if(_isFirstCharIsVowel($title)){
    $variables['title_addition'] = "D'";
  }else {
    $variables['title_addition'] = "De ";
  }
}

/**
 * Check if the first character is a vowel
 * @param $string string
 * @return bool
 */
function _isFirstCharIsVowel($string){
  $vowels =
    'aàáâãāăȧäảåǎȁąạḁẚầấẫẩằắẵẳǡǟǻậặæǽǣ' .
    'AÀÁÂÃĀĂȦÄẢÅǍȀȂĄẠḀẦẤẪẨẰẮẴẲǠǞǺẬẶÆǼǢ' .
    'EÈÉÊẼĒĔĖËẺĚȄȆẸȨĘḘḚỀẾỄỂḔḖỆḜ' .
    'eèéêẽēĕėëẻěȅȇẹȩęḙḛềếễểḕḗệḝ' .
    'IÌÍÎĨĪĬİÏỈǏỊĮȈȊḬḮ' .
    'iìíîĩīĭıïỉǐịįȉȋḭḯ' .
    'OÒÓÔÕŌŎȮÖỎŐǑȌȎƠǪỌØỒỐỖỔȰȪȬṌṐṒỜỚỠỞỢǬỘǾŒ' .
    'oòóôõōŏȯöỏőǒȍȏơǫọøồốỗổȱȫȭṍṏṑṓờớỡởợǭộǿœ' .
    'UÙÚÛŨŪŬÜỦŮŰǓȔȖƯỤṲŲṶṴṸṺǛǗǕǙỪỨỮỬỰ' .
    'uùúûũūŭüủůűǔȕȗưụṳųṷṵṹṻǖǜǘǖǚừứữửự'
  ;
  // set necessary encodings
  mb_internal_encoding('UTF-8');
  mb_regex_encoding('UTF-8');
  $first = mb_substr($string, 0, 1);
  $vow = mb_ereg_replace('[^'.$vowels.']','',  $first);
  return !empty($vow);
}

```

This can be used in your `.theme` or `.module` file.
This of course will act on all nodes, so you need to add your type checking.
The `_isFirstCharIsVowel` function can be in a service, I placed it here for simplicity

---

UPDATE Credits for vowwl detectioon goes to this https://stackoverflow.com/questions/14268970/how-to-detect-and-echo-the-last-vowel-in-a-word

# Answer
> 1 votes
A preprocess function is better suited for this task, and I would use the following code. I am using *custom-type* as machine name for the content type; replace it with the one you are using, and for which you want to change the title.

```
function mymodule_preprocess_node(&$variables) {
  if ($node = $variables['node'] && $node->bundle() == 'custom-type') {
    $title = $variables['label'];
    $translitted_title = iconv("UTF-8", "ASCII//TRANSLIT", $title);
    $article = (in_array($translitted_title[0], ['a', 'e', 'i', 'o', 'u']) ? "D'" : 'De ');
    $variables['label'] = $article . $title;
  }
}

```

In the template file, using `{{ label }}` you will get the changed title.

If you want to still be able to use `{{ label }}` for the original title, I would use the following code.

```
function mymodule_preprocess_node(&$variables) {
  if ($node = $variables['node'] && $node->bundle() == 'custom-type') {
    $title = $variables['label'];
    $translitted_title = iconv("UTF-8", "ASCII//TRANSLIT", $title);
    $article = (in_array($translitted_title[0], ['a', 'e', 'i', 'o', 'u']) ? "D'" : 'De ');
    $variables['changed_label'] = $article . $title;
  }
}

```

In the template, you can now use `{{ changed_label }}` for the new title, and `{{ label }}` for the original title.

Replace *mymodule* with the machine name of the module, or theme, where the code is being added.

As said in the documentation for the iconv extension, the extension is enabled by default. If the code I shown doesn't work, the extension has been disabled on the server.

---
Tags: 8, theming
---


# Question
Title: How can I translate the label of a vocabulary?
I load the vocabulary with `taxonomy_vocabulary_load($vocabulary_id)`.

How can I can translate its label in the language currently used?

# Answer
> 1 votes
It will be default by the current language.

There are only two ways to get something else, unfortunately:

a) Use ConfigEntityStorage::loadOverrideFree to load a config entity without overrides, then it is in the default language of that entity, which is what language() returns.

b) You can set the current config language and then load the entity. See for example user\_mail function:

```
  <?php
  // Get the current language and override it.
  $language_manager = \Drupal::languageManager();
  $language = $language_manager->getLanguage($desired_langcode);
  $original_language = $language_manager->getConfigOverrideLanguage();
  $language_manager->setConfigOverrideLanguage($language);

  // Do your thing here.

  // Restore the config language.
  $language_manager->setConfigOverrideLanguage($original_language);

```

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


# Question
Title: Local vs CDN libraries and how to check for available updates
For contributed Drupal modules, you can check whether you are using the latest version release of the module or not, by using any of the available methods such as Drush, Drupal console, Composer and UI.

What about the libraries used by those modules !?

How do I know if some of the libraries i have on my website are outdated and need to be updated ?!

To name a few, libraries for:

* Webform.
* Business Rules.
* Font Awesome.

**Note:** I am asking about the libraires used locally and not via CDN.

I am aware of the "one question" policy to simplify the questions asked, but since my other question is related to the first one so:

I don't like to use the CDN version of any library because when switch to the development website on my **offline localhost**, the CDN won't work and I must anyway to download the Libraires locally on my machine.

**So my second question is:**

What is the best in term of performance, using the **CDN version** or the **Local version** of libraries ?

Maybe, not sure, for development website running on localhost we could use the local version of libraries and add those folders/files to the .gitignore file so they will be not added to the Git repo

Thank you,

# Answer
We are using https://asset-packagist.org/ and manage our javascript dependencies just like any other, a composer update keeps those up to date as well then.

https://github.com/drupal-composer/drupal-project/pull/286 is a PR to add that to the drupal-project project by default.
> 4 votes

---
Tags: 8, cdn
---


# Question
Title: How do I programmatically install a module?
For Drupal 7, I found How do I programmatically install and enable a module?

What is the equivalent code for Drupal 8?

UPD: here Configuration Manager or hook\_update() to enable modules I found the case when you can use the code during deployments, specially when your module has updates in own dependencies.

# Answer
> 8 votes
Use "**module\_installer**" service.

```
$installer = \Drupal::service('module_installer');
// Or from the container.
$installer = $container->get('module_installer');

// Install single module.
$installer->install(['module_name']);
// Install multiple modules.
$installer->install(['module_name_1','module_name_2']);

```

Also for uninstallation of the module use the next example:

```
$installer->uninstall(['module_name']);

```

---
Tags: 8, installation
---


# Question
Title: Right way to create Yes/No boolean fields
I want to add fields in my node which will contain boolean values only : Yes/No. Selecting boolean as field type will cause the field to show up as single check box and in the node edit form I've difficulty in locating boolean type field.

Currently I'm using List(Text) and giving values as 1|Yes & 0|No.

What is the right way to use boolean values?

# Answer
As follows:

* Field type: **List (integer)** & Widget: **Check boxes/radio buttons**
* Values: **1|Yes**
* Number of values: **unlimited**

See drupal.org
> 1 votes

# Answer
I would create:

1. **List (Text)** with the **Check boxes/radio buttons** widget
2. Make two options: **1|Yes** and **2|No**
3. Number of values: **1**
4. **Most importantly**: put the field on Required. This way you get radio buttons where only one option can and must be selected.
> 0 votes

---
Tags: 7, entities
---


# Question
Title: Export custom module strings for translation
I've developed some custom modules for a client and implemented the `$this->t()` method to enable translations on static strings, like table headers. Is there a way to export only the translatable strings from my custom module into a .po file that I can handoff to someone for translation? I ideally want to export each modules translations separately so each module can be self contained.

# Answer
You can give Translation template extractor a spin. While there is no official release for Drupal 8 available (yet), there already is a development version that seems to work for your use case when using the GUI:

https://www.drupal.org/project/potx/releases

Using composer, just install it like

```
composer require drupal/potx

```

After enabling the module, you'll have a new menu entry *Configuration \> Regional and language \> User interface translation \> Extract* *(/admin/config/regional/translate/extract)*

There you can extract language and module specific translation templates from your custom module's PHP files.

*Disclaimer: As mentioned, this module's Drupal 8 version has not been released yet. It may contain bugs and is not feature complete/en par with the 7.x version. Better use it in your development environment only.*
> 4 votes

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


# Question
Title: Count words of a body field using PHP views field
I'm looking for a way to count the amount of words in my body fields, using Views PHP. I am totally new to PHP and this looks so easy, but I must be missing something.

So I have a View for Content, containing a body field (hide display, HTML trimmed) and a Global: PHP field.

I have this in my "Value Code"-field inside the Global: PHP field settings:

```
$count = print $row->body;
$result = str_word_count("$count");

```

And this in my Output:

```
<?php echo $result ?>

```

Seems I must be missing something, but I get no error, nor any result. Just nothing happens.

# Answer
So, after a long research, I stumbled at this issue post. It seems that field data are not present in the result set of Views PHP, so instead of `print $row->body`I needed to use `print $data->_field_data['nid']['entity']->body['nl'][0]['value']` to access the data. This solved my problem.
> 1 votes

---
Tags: 7, views
---


# Question
Title: Why doesn't the token for the node title work?
In Drupal 8, I activated the Message module and the Message Example sub-module.

These are the fields I added to the template to create a message when a new comment is created.

>

This is the content of the message.

> 1) \[message:node-title\]
> 2) \[message:field\_node\_reference:entity:title\]

These are the tokens that are listed as available.

>

`[message:node-title]` is replaced from the title of the parent node, but `[message:field_node_reference:entity:title]` is not replaced. Why?

>

# Answer
> 2 votes
`[message:field_node_reference:entity:title]` is not replaced with the node title because, for a *example\_create\_comment* message template, the *field\_node\_reference* field doesn't contain any valid node reference.

In fact, the *Message example* module uses the following code to return the value of the `[message:node-title]` token. (See message\_example\_tokens().)

```
    case 'node-title':
      if ($message->bundle() == 'example_create_comment') {
        $replacements[$original] = $message->field_comment_reference->entity->getCommentedEntity()->label();
      }
      else {
        $replacements[$original] = $message->field_node_reference->get(0)->entity->label();
      }
      break;

```

When the message bundle (the message template) is *example\_create\_comment*, it gets the node title using the *field\_comment\_reference* field (`$message->field_comment_reference->entity->getCommentedEntity()->label()`), not the *field\_node\_reference* field that is used for the other message templates.

The `[message:field_node_reference:entity:title]` token is added from the Token module, which adds a token for each field a content entity has. (*Message* is a content entity, and *Message template* is its bundle.) The Token module doesn't know if there is another field to use when the *field\_node\_reference* field doesn't contain any valid reference, so the token is not replaced.

If you want to get the node title in any case, you need to use the `[message:node-title]` token.

---
Tags: 8, nodes, comments, tokens, message-subscribe
---


title: Render only one field of an entity

text:
# Question
Title: Render only one field of an entity
On my controller for a custom page I've loaded an entity and I want to render, on the template for this custom page, only a field of the loaded entity. I would like to get the render array for this field.

Is it possible? I don't want to create a template for this content type only for this

# Answer
This is an example for D8:

```
$node = Node::load('1');
$display_settings = array(
  'label' => 'inline',
);
$build = $node->body->view($display_settings);

```
> 9 votes

# Answer
I would use the following code.

```
$field_to_render = field_view_field('model', $model, 'field_headerimage_image', 'full');
$field_to_render[$active_image]['#image_style'] = 'header_style';
$output = render($field_to_render[$active_image]);

```
> 1 votes

# Answer
I can't comment yet, otherwise I'd add this to the answer (https://drupal.stackexchange.com/a/206821/71534) but it's also helpful to know how to get the `$display_settings` for your field.

1. Setup the field with Manage Display the way you want
2. Then you can check the config (e.g. `core.entity_view_display.node.page.teaser.yml`
3. Find the field you want under the `content` key in the root of the yml file, which may look like this:

```
content:
  body:
    label: hidden
    type: text_default
    weight: 22
    settings: {  }
    third_party_settings: {  }
    region: content

```
4. So in PHP you could set `$display_settings` to:

```
$display_settings = array(
  'label' => 'hidden',
  'type' => 'text_default',
  'weight' => 22,
  'settings' => array(),
  'third_party_settings' => array(),
  'region' => 'content'
);

```
> 1 votes

---
Tags: entities, 8
---


# Question
Title: Showing a message for specific content type
I'm trying to show a message for specific content type through a new module, on Drupal 8.3.0. (I'm a beginner.)

This is part of the code I am using.

### File test\_module.module (updated code, still not working)

```
/**
 * @file
 * Implementation of hook_node_view();
 */

function test_module_node_view($node, $view_mode) {
  if ($view_mode == 'full' && $node->type == 'test_content') {
      /*Message with current date and time*/
      $current_time = time();
      drupal_set_message(t('Hello! Today is '.format_date($current_time,'medium')));
    }
  }

```

As far as I know, this should work, but it doesn't and I don't know why. The message is not showing for a node of content type "test\_content". How can I fix this? Is there another way to alter nodes of custom content types?

>

>

(Test\_content\_example is a node of type 'test\_content', so there should be a system message displayed, but there's none.)

# Answer
> 1 votes
`$node->type` is a reference to the node type config entity - it's not a string.

You can use `NodeInterface::getType()` instead, e.g.:

```
if ($view_mode == 'full' && $node->getType() == 'test_content') {

}

```

Incidentally you could also use `$node->bundle()`, or even `$node->type->entity->id()`. But `getType()` is probably most appropriate for your specific needs.

You also have the function signature wrong - it should be:

```
function test_module_node_view(array &$build, \Drupal\node\NodeInterface $node, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode)

```

---
Tags: nodes, hooks, status-messages
---


# Question
Title: Redirect logged in (authenticated) users to a different frontpage using rules or php code
I need to always redirect authenticated users to a different page (to serve as their own frontpage) whenever they try to access the default (anonymous) frontpage. I want to achieve this using rules or through some custom php code in my template.php or settings.php file, NOT by enabling a new module. Thanks.

Added: i created the frontpage using Page Manager (packaged with ctools)

# Answer
I have been able to resolve this using rules bonus pack: https://drupal.org/project/rb

The module to enable is Rules bonus: miscellaneous.

Each panel page now gets an extra tab below other tabs (like Layout, content, Preview) called "Reactions" =\> "Create a rules event for this variant". After enabling this and saving, Go to your rules events, a new rules event will be added "Rules Bonus: Miscellaneous" =\> "variant panel is rendered". Select this and save.

Conditions: User has roles (authenticated)

Actions: Page redirect: enter the path to the page e.g. "newpage" (without quotes).
> 0 votes

# Answer
If you are using a particular node as your front page:

1. Create a new rule, event: content is viewed
2. Condition: data comparison -\> `node:nid` equals to the `nid` of your front page node.
3. Add your conditions for user roles here.
4. Action: page redirect -\> enter the path where you want to redirect the users

If you have PHP code module enabled already:

1. Create a new rule, event: content is viewed
2. Condition: execute custom PHP code -\> `return drupal_is_front_page();`
3. Add your conditions for user roles here.
4. Action: page redirect -\> enter the path where you want to redirect the users
> 0 votes

# Answer
For me, "Content is viewed" would not work because I use the default front page, which is not a content node. It probably works if you are using a particular content node as front page.

For me, this worked on Drupal 7.59, Rules 7.x-2.9:

1. Create a new rule, event: Drupal is initializing
2. Condition: Text comparison between data selector \[site:current-page:url\] and matching text (here I used PHP):

$front\_url = 'https://example.org' . url();

echo $front\_url

The text comparison evaluates to TRUE when Drupal is initalizing the default front page, because my home url is 'https://example.org/drupaldirectory/'

3. Add your conditions for user roles here
4. Action: page redirect: enter the path where you want to redirect users
> 0 votes

---
Tags: 7, uri, redirection
---