# Question
Title: How to list entities and sort them by delta?
I have a "stations" and "railways" node types and a custom "notification" entity type. In "railways" node type I have an entity reference field ("field\_stations") where I can select "stations" nodes which is good. In "notification" entity type I have an entity reference field where I can select related stations. (entity reference to "stations" nodes) I would like to create a view to list "stations" nodes with grouping and sorting. I would like to group them by "railways" and sort them by delta ("field\_stations").

I tried it but I could not get the right order and get a lot of duplications. I have tried views\_order\_by\_delta module as well with no luck.

Do you have any recommendations?

# Answer
> 0 votes
I think you're overcomplicating things here. From my reading, you really should be creating your view to:

**Show content of type: Railway**

This will be your "grouping". You don't want to using the Views grouping option here - that option is more useful when you want to group the result content by a field on each result, i.e. if your stations node type had a reference to Railways.

**Fields to Display: Title, field\_stations** (or, preferable imo, configure a view mode for the Railway node that displays the fields you want to show).

Since we have a view of Railways, your results are naturally "grouped" by Railway. If you just display the stations field from the railway, you'll get the stations listed in the order on the field (its delta).

**(optional) Contextual Filter: field\_stations**

I'm not sure if you actually need this from your description. You can configure a contextual filter for the `field_stations` field to allow you to show only the Railways (and their stations) if a Railway references a station you pass as an argument.

---
Tags: 8, views
---


title: How do I join two tables?

text:
# Question
Title: How do I join two tables?
I was following this tutorial on Drupal module development. It talks about database query joins in module development. The tutorial is made for Drupal 8 and I'm using Drupal 9.

Then I made this (look at the join part):

```
  protected function load () {
    $select = Database::getConnection()->select('rsvplist', 'r');
    $select.join('users_field_data', 'u', 'r.uid = u.uid');
    $select->join('node_field_data', 'n', 'r.nid = n.nid');
    $select->addField('u', 'name');
    $select->addField('n', 'title');
    $select->addField('r', 'mail');
    $entries = $select->execute()->fetchAll(\PDO::FETCH_ASSOC);
    return $entries;
  }

```

But get this error:

```
warning: join() expects at most 2 parameters, 3 given in Drupal\rsvplist\Controller\ReportController->load() (line 24 of /var/www/htdocs/drupal-modules/modules/custom/rsvplist/src/Controller/ReportController.php)
#0 /var/www/htdocs/drupal-modules/core/includes/bootstrap.inc(305): _drupal_error_handler_real(2, 'join() expects ...', '/var/www/htdocs...', 24)
#1 [internal function]: _drupal_error_handler(2, 'join() expects ...', '/var/www/htdocs...', 24, Array)
#2 /var/www/htdocs/drupal-modules/modules/custom/rsvplist/src/Controller/ReportController.php(24): join('users_field_dat...', 'u', 'r.uid = u.uid')
#3 /var/www/htdocs/drupal-modules/modules/custom/rsvplist/src/Controller/ReportController.php(52): Drupal\rsvplist\Controller\ReportController->load()
#4 [internal function]: Drupal\rsvplist\Controller\ReportController->report()
#5 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#6 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#7 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#8 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#9 /var/www/htdocs/drupal-modules/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#10 /var/www/htdocs/drupal-modules/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#11 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /var/www/htdocs/drupal-modules/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/htdocs/drupal-modules/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/htdocs/drupal-modules/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/htdocs/drupal-modules/core/lib/Drupal/Core/DrupalKernel.php(706): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/htdocs/drupal-modules/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#20 {main}

```

Drupal 9's join don't accepts the third argument:

```
'r.uid = u.uid'

```

A made some research but I was not able to find an equivalent example about how to use join this way in Drupap 9 documentation and other sources.

How can I add joins to a query in Drupal 9?

# Answer
> 2 votes
In PHP:

* `.` is the string concatenation operator, not the one to call an object method
* `join()` is an alias for the `implode()` function, which effectively requires 2 arguments, not 3

This means that `$select.join('users_field_data', 'u', 'r.uid = u.uid')` (which PHP reads as `$select . join('users_field_data', 'u', 'r.uid = u.uid')`) is:

* Converting the value contained in `$select` to a string
* Concatenating that string with the string returned by `implode()`

The arguments accepted by `implode()` has been changed in the latest PHP versions, but the function has never accepted three arguments, and the first two arguments has never been two strings.

This explains the error you are getting.

In Drupal 9, if `$select` is an object implementing `SelectInterface`, `$select->join()` is an available method.

```
public function join($table, $alias = NULL, $condition = NULL, $arguments = []) {
  return $this->addJoin('INNER', $table, $alias, $condition, $arguments);
}

```

Instead of `$select->join()`, you could call `$select->addJoin()`.
The first method doesn't require to specify the first or the last argument of `$select->addJoin()`, and it's the normally called method.

As side note, instead of using `$select` on database tables used for entity data, it's generally preferable to use the class returned from `Drupal::entityQuery()`.

# Answer
> 0 votes
Solution:

In Drupal 9, I needed to replace joins so it works:

```
//$select.join('users_field_data', 'u', 'r.uid = u.uid');
$select->addJoin('inner','users_field_data','u','r.uid = u.uid');
//$select->join('node_field_data', 'n', 'r.nid = n.nid');
$select->addJoin('inner','node_field_data','n','r.nid = n.nid');

```

---
Tags: database, 9
---


title: How do I change option name?

text:
# Question
Title: How do I change option name?
I have sort link 'Best' in exposed form. I want after user click this link, link title changes to 'New'

I'm try this, but it don't work:

```
function helper_form_views_exposed_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
    if($form['#id']== 'views-exposed-form-pozdravleniya-taxonomy-term-page-1') {
      $form['sort_by']['#title'] = '';
      $form['sort_by']['#options']['created'] = '';
      if ($form['sort_by']['#value'] == 'count') {
        $form['sort_by']['#options']['count'] = 'New';
      }
    }
}

```

Also I'm try this, it don't work too:

```
function helper_form_views_exposed_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
    if($form['#id']== 'views-exposed-form-pozdravleniya-taxonomy-term-page-1') {
      $form['sort_by']['#title'] = '';
      $form['sort_by']['#options']['created'] = '';
      if ($form_state->getValue('sort_by') == 'count') {
        $form['sort_by']['#options']['count'] = 'New';
      }
    }
}

```

# Answer
I get answer here https://stackoverflow.com/a/65888182/13738862

```
function helper_form_views_exposed_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
    if($form['#id']== 'views-exposed-form-pozdravleniya-taxonomy-term-page-1') {
      $form['sort_by']['#title'] = '';
      $form['sort_by']['#options']['created'] = '';
      if ($form_state->getUserInput()['sort_by'] == 'count') {
        $form['sort_by']['#options']['count'] = 'New';
      }
    }
}

```
> 0 votes

---
Tags: 8, forms
---


# Question
Title: Using a custom field as a sub-field in another custom field
I posted a while back and have now successfully implemented a custom field (this was an extension of the DateRange field type to add control over presentation etc...)

I have a few other use cases where I could do with having a modified daterange field as a sub-field in another custom field type, now I know I could implement in the same way in each new custom field type, however, it would be much simpler if I could just drop in my custom daterange field. If this is not possible, is it best just to make my custom daterange the base type and extend this for each field type I need to create? Or is there another solution (I don't want to use paragraphs as I can't get the degree of customisation I want)

# Answer
> 0 votes
Basically, the question is how to use a custom field in another field **as a property**.

In an entity a custom field is added by using `BaseFieldDefinition::create()`. However a property of a field type is added by `DataDefintion::create()` or `MapDefinition::create()` and only basic types are defined (in DataDefintion class) to be used as `DataDefintion`. So It doesn't look like it is possible to have a custom field in another custom field.

**References**:

1. Fieldable field explains the problem of having a field inside a field
2. Entity API explains how each data type and field type are defined.
3. Same issue filed in d.o at #2874458

---
Tags: 8
---


# Question
Title: How to put the Bootswatch theme locally?
I am using this sub-theme and I can't find any help.

I am currently using Bootswatch Flatly in CDN mode. I want to put everything locally.

Here is what I did:

1. I ran the following 2 commands on my server :

```
mkdir -p web/libraries/bootstrap
cp -R vendor/twbs/bootstrap/dist web/libraries/bootstrap

```
2. I modified the `bootstrap_subtheme_front_office.info.yml` file :

```
name: Bootstrap Subtheme Front Office
type: theme
description: 'SASS starter kit for a Bootstrap Barrio SubTheme.'
# version: VERSION
core: 8.x
core_version_requirement: ^8 || ^9
base theme: bootstrap_barrio

libraries:
  - bootstrap_subtheme_front_office/bootstrap
  - bootstrap_subtheme_front_office/global-styling
libraries-override:
  bootstrap_barrio/global-styling: true
  bootstrap_barrio/file: true
regions:
  navigation_collapsible_first: 'Navigation (Collapsible first)'
  navigation_collapsible_left: 'Navigation (Collapsible left)'
  navigation: 'Navigation'
  navigation_collapsible_right: 'Navigation (Collapsible right)'
  navigation_collapsible_second: 'Navigation (Collapsible second)'
  breadcrumb: 'Breadcrumb'
  header: 'Top Bar'
  sidebar_first: 'Primary'
  highlighted: 'Highlighted'
  help: 'Help'
  content: 'Content'
  sidebar_second: 'Secondary'
  footer: 'Footer'

# Information added by Drupal.org packaging script on 2020-10-11
version: '5.0.2'
project: 'bootstrap_subtheme_front_office'
datestamp: 1602444143

```

And I modified the `bootstrap_subtheme_front_office.libraries.yml` file :

```
global-styling:
  version: VERSION
  js:
    js/popper.min.js: {}
    js/bootstrap.min.js: {}
    js/barrio.js: {}
    js/custom.js: {}
    js/back-to-top.js: {}
    js/copy-to-clipboard.js: {}
  css:
    component:
      css/style.min.css: {}
  dependencies:
    - core/jquery
    - core/drupal
bootstrap:
  js:
    /libraries/bootstrap/dist/js/bootstrap.bundle.min.js: {}
  css:
    component:
      /libraries/bootstrap/dist/css/bootstrap.min.css: {}

```
3. I downloaded the 4 Bootswatch Flatly files to my computer:

I copied the 4 files in the folder

```
/libraries/bootswatch/dist/flatly

```
4. I executed the gulp and drush cr command.

**MY PROBLEM**

How to declare Bootswatch? Where to put the files?

# Answer
The theme can not read the SCSS file. You have to covert them to CSS. To do this, follow the following instruction.

1. Create a new SCSS(Let's name it the "custom.scss") and import all the SCSS to this file. and convert it to CSS."
In the new "custom.scss" file, import the "\_bootswatch.scss" and "\_variables.scss". To do this, use the @import function. Add the following code to your "custom.scss".

`@import 'bootswatch', 'variables';`
2. Use a **SCSS compiler** to covert the SCSS to CSS.
Covert the "custom.scss" file to "custom.css", then minify the file to "custom.min.css".
3. On your "bootstrap\_subtheme\_front\_office.libraries.yml" file, include the "custom.min.css". Add the following code below the "`css/style.min.css: {}`"

`css/custom.min.css: {}`
> 0 votes

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


title: "Global: Custom text" field translation

text:
# Question
Title: "Global: Custom text" field translation
Is it possible to translate this type of view field, Or use `t()` in this field for single words?

I'm using the Internationalization and the Internationalization Views modules, but I can't translate these fields.

# Answer
In Drupal 8 and 9, use `t` ( or `trans`) filter in twig element in your Global: Custom text”.

for example, create a `Global: custom text` field and paste

```
 {{ 'this text will be available in translate interface'|t }}

```

Ref for reading more: https://www.drupal.org/docs/theming-drupal/twig-in-drupal/filters-modifying-variables-in-twig-templates
> 0 votes

---
Tags: 7, views, i18n-l10n
---


title: Change page title

text:
# Question
Title: Change page title
I've created a view to display products based on the taxonomy vocabulary Categories. I followed a few how tos and check for answers on drupal.org, here & other websites but none is working.

I would like the title of the view to be the name of taxonomy term displayed.

The Path is : taxonomy/term/% Contextual filter: -- When the filter value is NOT in the URL \> Provide default value \> Taxonomy Term ID from URL -- When the filter value IS in the URL or a default is provided \> Specify validation criteria \> Taxonomy Term ID -- -- Vocabulary \> Categories

To overwrite the title, I have 2 Replacement patterns available :

```
{{ arguments.field_categories_target_id }} == Product: Catégories (field_categories) title
{{ raw_arguments.field_categories_target_id }} == Product: Catégories (field_categories) input

```

The both display the Taxonomy term ID, not the name.

I've tried with other replacement patterns, nothing is displayed.

I'm running Drupal 8.9.13.

Thanks for your help!

---

This is the .yml file.

```
uuid: cb266220-13c8-434d-8371-cabb6d7af36f
langcode: fr
status: true
dependencies:
  config:
    - commerce_product.commerce_product_type.dropixx
    - core.entity_view_mode.commerce_product.vignette
    - field.storage.commerce_product.field_categories
    - taxonomy.vocabulary.categories
    - taxonomy.vocabulary.marques_cat
  module:
    - commerce
    - commerce_product
    - ds
    - taxonomy
id: taxonomy
label: Taxonomy
module: views
description: ''
tag: ''
base_table: commerce_product_field_data
base_field: product_id
display:
  default:
    display_plugin: default
    id: default
    display_title: Master
    position: 0
    display_options:
      access:
        type: none
        options: {  }
      cache:
        type: tag
        options: {  }
      query:
        type: views_query
        options:
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_comment: ''
          query_tags: {  }
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      pager:
        type: full
        options:
          items_per_page: 12
          offset: 0
          id: 0
          total_pages: null
          tags:
            previous: ‹‹
            next: ››
            first: ««
            last: »»
          expose:
            items_per_page: false
            items_per_page_label: 'Items per page'
            items_per_page_options: '5, 10, 25, 50'
            items_per_page_options_all: false
            items_per_page_options_all_label: '- All -'
            offset: false
            offset_label: Offset
          quantity: 5
      style:
        type: default
        options:
          row_class: 'col-xs-12 col-sm-6 col-md-6 col-lg-4 col-xl-3 vg-box'
          default_row_class: true
          uses_fields: false
      row:
        type: 'ds_entity:commerce_product'
        options:
          relationship: none
          view_mode: vignette
          alternating_fieldset:
            alternating: false
            allpages: false
            item_0: default
            item_1: default
            item_2: default
            item_3: default
            item_4: default
            item_5: default
            item_6: default
            item_7: default
            item_8: default
            item_9: default
          grouping_fieldset:
            group: false
          advanced_fieldset:
            advanced: false
      fields:
        title:
          table: commerce_product_field_data
          field: title
          id: title
          entity_type: null
          entity_field: title
          plugin_id: field
          relationship: none
          group_type: group
          admin_label: ''
          label: ''
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings: {  }
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        field_categories:
          id: field_categories
          table: commerce_product__field_categories
          field: field_categories
          relationship: none
          group_type: group
          admin_label: ''
          label: ''
          exclude: true
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: target_id
          type: entity_reference_label
          settings:
            link: true
          group_column: target_id
          group_columns: {  }
          group_rows: true
          delta_limit: 1
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
          plugin_id: field
        nothing:
          id: nothing
          table: views
          field: nothing
          relationship: none
          group_type: group
          admin_label: ''
          label: ''
          exclude: false
          alter:
            alter_text: true
            text: "<br>title {{ title }}\r\n<br>categories {{ field_categories }}\r\n<br>target id {{ arguments.field_categories_target_id }} "
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: false
          plugin_id: custom
      filters:
        status:
          value: '1'
          table: commerce_product_field_data
          field: status
          plugin_id: boolean
          entity_type: commerce_product
          entity_field: status
          id: status
          expose:
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
          group: 1
        type:
          id: type
          table: commerce_product_field_data
          field: type
          value:
            dropixx: dropixx
          entity_type: commerce_product
          entity_field: type
          plugin_id: commerce_entity_bundle
          expose:
            operator_limit_selection: false
            operator_list: {  }
        field_stock_qty_value:
          id: field_stock_qty_value
          table: commerce_product__field_stock_qty
          field: field_stock_qty_value
          relationship: none
          group_type: group
          admin_label: ''
          operator: '!='
          value:
            min: ''
            max: ''
            value: '0'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
            placeholder: ''
            min_placeholder: ''
            max_placeholder: ''
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
          plugin_id: numeric
        field_marque_target_id:
          id: field_marque_target_id
          table: commerce_product__field_marque
          field: field_marque_target_id
          relationship: none
          group_type: group
          admin_label: ''
          operator: or
          value: {  }
          group: 1
          exposed: true
          expose:
            operator_id: field_marque_target_id_op
            label: 'Marques :'
            description: ''
            use_operator: false
            operator: field_marque_target_id_op
            operator_limit_selection: false
            operator_list: {  }
            identifier: field_marque_target_id
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
              anonymous: '0'
              administrator: '0'
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
          reduce_duplicates: false
          type: select
          limit: true
          vid: marques_cat
          hierarchy: false
          error_message: true
          plugin_id: taxonomy_index_tid
      sorts: {  }
      title: '<none>'
      header: {  }
      footer: {  }
      empty: {  }
      relationships: {  }
      arguments:
        field_categories_target_id:
          id: field_categories_target_id
          table: commerce_product__field_categories
          field: field_categories_target_id
          relationship: none
          group_type: group
          admin_label: ''
          default_action: default
          exception:
            value: all
            title_enable: false
            title: '{{ arguments.field_marque_target_id }}'
          title_enable: true
          title: '{{ arguments.field_categories_target_title }}'
          default_argument_type: taxonomy_tid
          default_argument_options:
            term_page: '1'
            anyall: ','
            node: false
            limit: false
            vids: {  }
          default_argument_skip_url: false
          summary_options:
            base_path: ''
            count: true
            items_per_page: 25
            override: false
          summary:
            sort_order: asc
            number_of_records: 0
            format: default_summary
          specify_validation: true
          validate:
            type: 'entity:taxonomy_term'
            fail: 'not found'
          validate_options:
            bundles:
              categories: categories
            access: true
            operation: view
            multiple: 0
          break_phrase: false
          not: false
          plugin_id: numeric
      display_extenders: {  }
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - url
        - url.query_args
        - user
      tags:
        - 'config:field.storage.commerce_product.field_categories'
  taxonomy_category_contextual:
    display_plugin: page
    id: taxonomy_category_contextual
    display_title: Page
    position: 1
    display_options:
      display_extenders:
        metatag_display_extender: {  }
      path: taxonomy/term/%
      enabled: true
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - url
        - url.query_args
        - user
      tags:
        - 'config:field.storage.commerce_product.field_categories'

```

# Answer
Hey there is there any particular reason you are using that filter?

I believe that if you use the "Has Taxonomy Term ID" contextual filter , it will work as you intend it to.

Let me know if i did not understand your question correctly. Best Regards.
> 0 votes

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


title: Mask a dynamic URL

text:
# Question
Title: Mask a dynamic URL
Is there a way to mask a dynamic url in Drupal?

**Original URL:** site.com/user/%/orders

**Masked URL:** site.com/orders

# Answer
> 1 votes
Install **Page Manager** module. It is bundled with CTools which is a requirement for Views, so chances are it is on your system already.

Go to Structure-\>Pages-\>Add custom page:

* **Administrative title:** Masked Orders
* **Path:** orders
* **Variant Type:** HTTP response Code
* **Optional features:** Access control, Contexts
* Click Continue

**Next page is:** Basic settings » Access control » Contexts » Panel settings

* Select `Context exists`, click Add button. In modal select context: `Logged in User Exists` and click Save
* Click Continue

**Next page is:** Basic settings » Access control » Contexts » Panel settings

* Select `User` and click Add Context button. On modal **tick** `Logged in user` and click Finish.
* Click Continue

**Next page is:** Basic settings » Access control » Contexts » Panel settings

* Change Administrative title machine name to: http\_response\_code
* Select Response Code: 301 Redirect
* Add Redirect destination: `user/%user:uid/orders`
* Click Finish

On next page click: Update and save

Test the path `orders`

# Answer
> 0 votes
If you need to do masking you'd need to use .htaccess rules, which allows you do to that URL masking.

See for example: https://stackoverflow.com/questions/14928498/htaccess-url-masking-instead-of-redirecting

On your case it could look something like this:

```
# Various rewrite rules.
<IfModule mod_rewrite.c>
  RewriteEngine on

  RewriteCond %{REQUEST_URI} /orders/
  RewriteRule .* user/%1/orders [NC]

```

For your use case however you don't specify if your users are authenticated, hence seen their own orders, or if you want to mask the url for anonymous users (for which this example could be your path to follow)

---
Tags: path-aliases
---


# Question
Title: How can I get my module to see the current language my user is using?
When I use `Node::load(10)->toArray()` I see that my module thinks that the current language is English. I have the language key (fr) in the url and when I place `\Drupal::languageManager()->getCurrentLanguage()->getId()` in my code it says (fr). How can I get Node::load(10) to see the current language the user is using?

When I translate the content type into another language, all translations of the same page seem to have the same id to place into the load function.

# Answer
> 20 votes
You could try the following:

```
$lang_code = \Drupal::languageManager()->getCurrentLanguage()->getId();
Node::load(10)->getTranslation($lang_code)->toArray();

```

Good luck!

# Answer
> 4 votes
UPDATED ANSWER:

```
<?php
use Drupal\Core\Language\LanguageInterface;
use Drupal\node\Entity\Node;
$node = Node::load(10);
$langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT);
$translation = $node->getTranslation($langcode);
// Now deal with the right language from here on.
?>

```

Hope this works!

# Answer
> 3 votes
The easiest way to do it:

```
$entity_translated = \Drupal::service('entity.repository')->getTranslationFromContext($entity);

```

This will load according to the UI/content language as it was selected, can be fed with any type of entity (content type, comment, media, etc), and if there's no current language it will provide the fallback language content.

Please note if you use `getTranslation` it will fail (later on your code) if there's no translation, so you need to check always with `hasTranslation` and if returns true then and only then you use the `getTranslation`.

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


title: How do I theme a taxonomy term page?

text:
# Question
Title: How do I theme a taxonomy term page?
I am working on Drupal 8, trying to get a page template for each vocabulary. I have tried using `hook_theme_suggestions_HOOK_alter()` to achieve this, but I was not able to do it.

I tried using Devel with `kint()`, but no debugging information is shown on my screen.

How can I add a template suggestion for a vocabulary?

# Answer
You can suggest a new template file with the following code.

**Drupal 8**

```
use Drupal\taxonomy\Entity\Term;

function THEME_NAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
  if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
    $term = Term::load($tid);
    $suggestions[] = 'page__taxonomy__' . $term->getVocabularyId();
  }
}

```

**Drupal 9**

```
use Drupal\taxonomy\Entity\Term;

function THEME_NAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
  if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
    $term = Term::load($tid);
    $suggestions[] = 'page__taxonomy__' . $term->bundle();
  }
}

```

Then create the file: `page--taxonomy--VOCABULARYNAME.html.twig` and customise it as you wish.
> 16 votes

# Answer
In Drupal 9, the `getVocabularyId()` method is deprecated so we use `bundle()` instead.

Use this hook in Drupal 9:

```
use Drupal\taxonomy\Entity\Term;

/*
 * Implements hook_theme_suggestions_HOOK_alter()
 */

function THEMENAME_theme_suggestions_page_alter(&$suggestions, &$vars) {
  if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical' && $tid = \Drupal::routeMatch()->getRawParameter('taxonomy_term')) {
    $term = Term::load($tid);
    $suggestions[] = 'page__taxonomy__' . $term->bundle();
  }
}

```
> 2 votes

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


# Question
Title: Tree structure based on parent-child relationship among content types
I want to store `technical_specifications` of various products. As different product categories obviously have very different types of specifications, what I had in mind was a tree structure of content types, only to find out that Drupal's content types don't support parent - child relationship out of the box (ie. a content type cannot inherit fields from another one)

I'm thinking something along the lines of

```
- PRODUCT
- price
- weight
- url
    - COMPUTER
    - (inherits everything from product, plus)
    - processor
    - RAM
    - (...)
        - LAPTOP
        - (inherits everything from computer, plus)
        - battery
        - touchscreen?
        - screen size
        - (...)
    - TV
    - (inherits from product, then)
    - screen size
    - contrast ratio
    - resolution
    - refresh rate
    - (...)
    - BOOK
    - (inherits from product, plus)
    - author
    - title
    - genre
    - publication date

```

...you get the idea.

What is the *'Drupalish'* way to achieve this?

I could, of course, create separate content types for every product category (since you only create every content type once, and you can re-use existing fields, it's not a whole lot of extra work), but that wouldn't reflect the structure and hierarchy of the product categories

Or I could dump every field in one big content type, make them optional and only fill out what's relevant to that specific product (or category, rather)

Neither of these sound optimal. Any better ideas?

thanks!

(I'm running Drupal 8, btw, if that is of any importance)

# Answer
I think there is a lot more to unpack here than it seems at first sight.

Usually when we talk about inheriting things it's actual data referencing other data (sets of data), it's not structures inheriting structures automatically.

Just because a laptop shares properties with a computer doesn't mean that a laptop node will reference a particular computer node, so it's not data referencing data.

Although you can choose to implement things in different ways, and there are usually reasons why you should go with a chosen option, I think in this case it makes the most sense to create a separate structure for each data set that is "standalone".

Without any other info about your site, assuming from your current description and my past experience building sites I would structure it this way:

Content types and their fields:

```
COMPUTER
- processor
- RAM
- (...)
LAPTOP
- processor
- RAM
- battery
- touchscreen?
- screen size
- (...)
TV
- screen size
- contrast ratio
- resolution
- refresh rate
- (...)
BOOK
- author
- title
- genre
- publication date
PRODUCT
- price
- weight
- URL
- !! Entity Reference Field !!

```

Notice the computer fields in laptop that are the same as in computers are repeated under laptop. You can reuse existing fields, I recommend you do especially if you plan to do any comparisons between different nodes that may be different category product but share the same properties/fields. But there are no field references between computer and laptop, they are independent from each other, even if they share some properties.

Different product categories have different product properties, and it makes sense to keep them separate.

When selling products they all share the same properties with regards to selling, and when selling a product you're selling one set of data, not the structure. You're selling one specific computer, not category of computers in general.

That's why it makes sense to have the saleable entity as a separate structure, and you pull specific data from a particular node that exists of some product category.

Through the Entity Reference field you can show entire node information on the Product node that references it.

Structurally you could have a specific computer node, lets say node ID 5 with all the computer fields describing it (RAM, CPU).

Then you would have another node, of the Product type, node ID 6 for example, that would list the price and reference node 5. Node 6 would show everything on its page. Node 5 can even be hidden from public, better SEO whatnot...

With the module Inline Entity Form (which was created with excommerce in mind) or some similar solution you can solve the editors problems of having to first create the "computer" node before creating the "sell computer" node. With this module you will be able to create both at the same time, in one go.

This way you're fast when entering content and maintaining your site, while your structure is still flexible enough that it's easy to create different lists you might need with Views (using Paragraphs and keeping everything in the same type can hinder you there) and you can change things in one place because it's all kept in sane compartments.

For example if in the future you need to add some sales tax field you can do it on the Product type and it will appear for all saleable products, you won't have to edit many CTs (in case you have them all separate without ER to product) and you won't have to do complex Views to gather different Paragraph interconnections just because you have everything in one Conent Type.

If you've read it, I think it will help no matter what you decide because it at least gives you some other considerations to think about. If I've been clear enough that is :þ
> 1 votes

---
Tags: 8, nodes
---


# Question
Title: How can I get the checkbox element value from a submission handler?
I have a single checkbox field. When I try to get its value in a submission handler, the value I get is always 0 whether it has been selected or not.

```
/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state) {
  $form['item_specifics'] = [
    '#type' => 'checkbox',
    '#title' => t('Sync item specifics'),
    '#attributes' => [
      'name' => 'field_item_specifics',
    ]
  ];

  $form['fieldset_item_specifics'] = [
    '#type' => 'fieldset',
    '#title' => $this->t('Item Specifics'),
    '#attributes' => [
      'class' => ['form-wrapper', 'js-form-wrapper'],
    ],
    '#states' => [
      'visible' => [
        ':input[name="field_item_specifics"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Sync'),
  ];

  return $form;
}

```

How can I get the checkbox value from a submission handler?

# Answer
> 1 votes
Instead of setting `$form['item_specifics']['#attributes']['name']` to `'field_item_specifics'`, you need to set it to `'item_specifics'`.

```
/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state) {
  $form['item_specifics'] = [
    '#type' => 'checkbox',
    '#title' => t('Sync item specifics'),
    '#attributes' => [
      'name' => 'item_specifics',
    ]
  ];

  $form['fieldset_item_specifics'] = [
    '#type' => 'fieldset',
    '#title' => $this->t('Item Specifics'),
    '#attributes' => [
      'class' => ['form-wrapper', 'js-form-wrapper'],
    ],
    '#states' => [
      'visible' => [
        ':input[name="item_specifics"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Sync'),
  ];

  return $form;
}

```

---
Tags: 8, forms
---


# Question
Title: Cannot redirect to an empty URL. in Symfony\Component\HttpFoundation\RedirectResponse->setTargetUrl() when access the front page
After clearing the cache, the front page becomes inaccessible. When I visit it, I see this error message.

> Cannot redirect to an empty URL. in Symfony\Component\HttpFoundation\RedirectResponse-\>setTargetUrl() (line 86 of vendor/symfony/http-foundation/RedirectResponse.php).

Why does it happen?

Here is another update, after I open full backtrace, I find the related code all related to the drupal core, I find the code is all related to drupal core.

> Drupal\Component\HttpFoundation\SecuredRedirectResponse-\>setTargetUrl('') (Line: 39) Symfony\Component\HttpFoundation\RedirectResponse-\>\__construct('', 301, Array) (Line: 26) Drupal\Core\Routing\TrustedRedirectResponse-\>\__construct('', 301) (Line: 128) Drupal\redirect\EventSubscriber\RouteNormalizerRequestSubscriber-\>onKernelRequestRedirect(Object, 'kernel.request', Object) call\_user\_func(Array, Object, 'kernel.request', Object) (Line: 111) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher-\>dispatch('kernel.request', Object) (Line: 127) Symfony\Component\HttpKernel\HttpKernel-\>handleRaw(Object, 1) (Line: 68) Symfony\Component\HttpKernel\HttpKernel-\>handle(Object, 1, 1) (Line: 57) Drupal\Core\StackMiddleware\Session-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\KernelPreHandle-\>handle(Object, 1, 1) (Line: 106) Drupal\page\_cache\StackMiddleware\PageCache-\>pass(Object, 1, 1) (Line: 85) Drupal\page\_cache\StackMiddleware\PageCache-\>handle(Object, 1, 1) (Line: 50) Drupal\ban\BanMiddleware-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\ReverseProxyMiddleware-\>handle(Object, 1, 1) (Line: 52) Drupal\Core\StackMiddleware\NegotiationMiddleware-\>handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel-\>handle(Object, 1, 1) (Line: 708) Drupal\Core\DrupalKernel-\>handle(Object) (Line: 19)

# Answer
> Here is another update, after I open full backtrace, I find the related code all related to the drupal core, I find the code is all related to drupal core.

It's not core. This is the last line before the response object is constructed.

> Drupal\redirect\EventSubscriber\RouteNormalizerRequestSubscriber-\>onKernelRequestRedirect(Object, 'kernel.request', Object) call\_user\_func(Array, Object, 'kernel.request', Object) (Line: 111)

This is in the namespace of the contrib module Redirect, which by the way is using a cacheable redirect response in an event subscriber, so my comment about not using RedirectResponse in cacheable code doesn't apply here.

Try to disable *Enforce clean and canonical URLs* in the module's settings. If this issue is specific to a route you can disable it in the route definition by setting a default `_disable_route_normalizer: TRUE`.
> 1 votes

---
Tags: 8
---


# Question
Title: Form submission not saved when using a dynamic redirect
I have forms where I use a form alter to set various form fields on the fly. One of which is the Thank You page field that a user should go to after submitting. Example `$form['submitted']['thankyou_page']['#value'] = 'my_page';` I use the same form for multiple reasons so setting the thank you page to suit.

After setting these (which work fine) I then enter a function to do some processing of the form fields to a CRM.

The final section of this function is like this

```
try {
    $result = $client->CreateContact($data);
} catch (Exception $e) {
    $result = $e;
}
  my_submit_handler2($values['thankyou_page']); // redirect
}
}

```

The processing works fine to CRM but my problem is that the form submission (result) doesn't save in Drupal and the auto-emails after submit fail to send too. The redirect is done like this

```
function my_submit_handler2($f) {
  drupal_goto($f);
}

```

So I guess the submission is being interrupted?

How can I do these redirects without affecting the flow of the form submission?

# Answer
A form submission handler, as well a form validation handler or a hook to alter a form, should never call `drupal_goto()` since it outputs a HTTP header and interrupts what Drupal is doing.

The correct way to redirect a form from a form submission handler is setting `$form_state['redirect']` in Drupal 7, or calling `$form_state->setRedirect()` in Drupal 8. The alternative for Drupal 8 is calling `$form_state->setRedirectUrl()`.

For Drupal 7, the following code would redirect the users to node/123?foo=bar#baz.

```
$form_state['redirect'] = array(
  'node/123',
  array(
    'query' => array(
      'foo' => 'bar',
    ),
    'fragment' => 'baz',
  ),
);

```
> 2 votes

---
Tags: redirection
---


title: Image style not generated

text:
# Question
Title: Image style not generated
I'm runnig drupal on nginx my nginx config file is :

```
proxy_cache_path /data/nginx/cache keys_zone=my_zone:10m inactive=1d;
# Expires map
map $sent_http_content_type $expires {
    default                    off;
    text/html                  epoch;
    text/css                   max;
    application/javascript     max;
    ~image/                    max;
}

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate  xxxxxxxxxxxxxxxx;
        ssl_certificate_key xxxxxxxxxxxxxxxx;
        root /var/www/xxxxxxxxxxx/html;
        index index.php  index.html index.htm index.nginx-debian.html;
        server_name xxxxxxxxxxx.com www.xxxx.com;
        expires $expires;
    client_max_body_size 30M;
        keepalive_requests 100000;
        keepalive_timeout 65;

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;

     gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
        # Specify the minimum length of the response to compress (default 20)
        gzip_min_length 500;

 location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Very rarely should these ever be accessed outside of your lan
    location ~* \.(txt|log)$ {
        allow 192.168.0.0/16;
        deny all;
    }

    location ~ \..*/.*\.php$ {
        return 403;
    }

    location ~ ^/sites/.*/private/ {
        return 403;
    }

    # Block access to scripts in site files directory
    location ~ ^/sites/[^/]+/files/.*\.php$ {
        deny all;
    }

    # Allow "Well-Known URIs" as per RFC 5785
    location ~* ^/.well-known/ {
        allow all;
    }

    # Block access to "hidden" files and directories whose names begin with a
    # period. This includes directories used by version control systems such
    # as Subversion or Git to store control files.
    location ~ (^|/)\. {
        return 403;
    }

    location / {
        # try_files $uri @rewrite; # For Drupal <= 6
        try_files $uri /index.php?$query_string; # For Drupal >= 7
    }

    location @rewrite {
        #rewrite ^/(.*)$ /index.php?q=$1; # For Drupal <= 6
        rewrite ^ /index.php; # For Drupal >= 7
    }

    # Don't allow direct access to PHP files in the vendor directory.
    location ~ /vendor/.*\.php$ {
        deny all;
        return 404;
    }

    # Protect files and directories from prying eyes.
    location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|/(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {
        deny all;
        return 404;
    }

    # In Drupal 8, we must also match new paths where the '.php' appears in
    # the middle, such as update.php/selection. The rule we use is strict,
    # and only allows this pattern with the update.php front controller.
    # This allows legacy path aliases in the form of
    # blog/index.php/legacy-path to continue to route to Drupal nodes. If
    # you do not have any paths like that, then you might prefer to use a
    # laxer rule, such as:
    #   location ~ \.php(/|$) {
    # The laxer rule will continue to work if Drupal uses this new URL
    # pattern with front controllers other than update.php in a future
    # release.
    location ~ '\.php$|^/update.php' {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        # Ensure the php file exists. Mitigates CVE-2019-11043
        try_files $fastcgi_script_name =404;
        # Security note: If you're running a version of PHP older than the
        # latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
        # See http://serverfault.com/q/627903/94922 for details.
        include fastcgi_params;
        # Block httpoxy attacks. See https://httpoxy.org/.
        fastcgi_param HTTP_PROXY "";
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_intercept_errors on;
        # PHP 5 socket location.
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        # PHP 7 socket location.
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    }

   location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
       proxy_cache my_zone;
       proxy_cache_key "$host$request_uri$http_authorization";
       proxy_cache_valid 404, 302 1m;
       proxy_cache_valid 200 1d;
       add_header X-Cache-Status $upstream_cache_status;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        try_files $uri @rewrite;
        expires max;
        log_not_found off;
    }

    # Fighting with Styles? This little gem is amazing.
    # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
    location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
        try_files $uri @rewrite;
    }

    # Handle private files through Drupal. Private file's path can come
    # with a language prefix.
    location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
        try_files $uri /index.php?$query_string;
    }

    # Enforce clean URLs
    # Removes index.php from urls like www.example.com/index.php/my-page --> www.example.com/my-page
    # Could be done with 301 for permanent or other redirect codes.
    if ($request_uri ~* "^(.*/)index\.php/(.*)") {
        return 307 $1$2;
    }

}

```

when an image uploaded it's image style not generated.also when i check style folder that's not exist and not generated. this is my permission folders :

```
sites -----> 755
default ---- > 775
files --- > 775

```

owner/group of my site file is **www-data www-data**

also I added two lines to **settings.php**:

```
$config['image.settings']['suppress_itok_output'] = TRUE;
$config['image.settings']['allow_insecure_derivatives'] = TRUE;

```

even I used **"drush image-flush"** and my image style flushed but styles not regenerated.

# Answer
> 1 votes
The image derivative is created when it's requested, not when the image to which the image style is applied is uploaded.

When the URL for an image derivative is accessed, `ImageStyleDownloadController::deliver()` is invoked, and the image derivative is created, if it doesn't already exist.

# Answer
> 0 votes
1. create sites/default/files/styles folder manually
2. set its permissions to 775
3. create .htaccess file with following content:

```
    <Files *>
      SetHandler none
    </Files>

```

Source

---
Tags: 8
---


# Question
Title: Why is my custom block template not being picked up?
I am working on a custom slider programmatically. I create a custom module (block\_example) and make a block (BlockExample.php) and a twig file (blockexample.html.twig) and also a module file (block\_example.module). I want to place some code in twig file and call it in block file.

This is build function from block file (BlockExample.php)

```
public function build() {

  $renderable = [
    '#theme' => 'blockexample',
  ];

  return $renderable;
}

```

This is (blockexample.html.twig) file code

```
<div class="col-sm-3">
  <h1>This is Title</h1>
  <p>Description Coming From Twig File</p>
</div>

```

This is (block\_example.module) file code

```
function block_example_theme() {
  return [
    'block_example' => [
      'variables' => ['test_var' => NULL],
    ],
  ];
}

```

Now main question is how to print twig file in BlockExample.php

# Answer
> 0 votes
The theme key you use in you build funtions should be the same with the one you are using in your hook\_theme.

In that case you code should look like so

```
public function build() {

  $renderable = [
    '#theme' => 'block_example',
  ];

  return $renderable;
}

```

Keep in mind to avoid dashes in those values, since they are used for the template naming.

Best regards.

---
Tags: 8, theming, blocks
---


# Question
Title: How to I trigger Xdebug 3.x with Drush in PHPStorm
Has anyone has success with getting CLI debugging (**drush**) working with Xdebug 3.x? There are several obsolete posts here... but all obsolete with the new version of Xdebug.

**Expected behavior**

After setting a breakpoint in a PHP class or module, that I know is executed when a specific Drush command is run, I would like PHPStorm to stop at the breakpoint.

Debugging when initiated from the browser works beautifully. Drush - nothing. Though it used to before I;

1. upgraded to Catalina
2. upgraded Xdebug from 2.x to 3.x

**Environment:**

Local MAMP Drupal 8 / Drush 9.7.2

**PHP**

PHP 7.4.13 (cli) (built: Nov 30 2020 14:46:04) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.13, Copyright (c), by Zend Technologies

# Answer
> 2 votes
I am guessing that you have changed your xdebug.ini according to the new standards. (Port changed from 9000 to 9003 etc...)

If not you should do that first. Check this link for additional information on the matter.

Besides that considering that you are using phpstorm, you should simply run

```
export XDEBUG_SESSION=PHPSTORM

```

before running the drush command. This must be done once every time you open a new terminal session. (Not sure if there is a way to have it permanently and if there is i am not sure you want it.) Nevertheless, if your configurations are ok, this should work.

Best Regards.

---
Tags: drush, debugging
---


# Question
Title: Can't submit entityform after ajax callback on select element
I followed the advice from this link and migrated the code populating my ajax into buildForm(), and all is well. Select list is populated by ajax and elements are preserved even after form submit. Problem is that I get the following error when I try to submit the form -

```
The value you selected is not a valid choice

```

I've tried adding the popular `'#validated'=TRUE` option to my ajax select, but this causes 2 things to happen

1. My ajax callback only successfully replaces the content of the select once, subsequent calls have no effect whatsoever, the old content of the select remains
2. I get a really bad error when I try to submit the form `"Website encountered an error"`. Checking the logs shows the following:

> \[client ::1:40776\] TypeError: Argument 1 passed to Drupal\Core\Field\WidgetBase::massageFormValues() must be of the type array, string given, called in /home/chibuzo/Software/Dev/Src/Web/tpl\_website/web/core/lib/Drupal/Core/Field/WidgetBase.php on line 390 in /home/chibuzo/Software/Dev/Src/Web/tpl\_website/web/core/lib/Drupal/Core/Field/WidgetBase.php on line 537 #0 /home/chibuzo/Software/Dev/Src/Web/tpl\_website/web/core/lib/Drupal/Core/Field/WidgetBase.php(390): Drupal\Core\Field\WidgetBase-\>massageFormValues()\n#1 /home/chibuzo/Software/Dev/Src/Web/tpl\_website/web/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php(232): Drupal\Core\Field\WidgetBase-\>extractFormValues()\`\`\`

So if I use `'#validated' = TRUE`, my ajax callback runs only once and shows the error above on form submit, And if I remove `'#validated'=TRUE`, my form fails to submit and shows `"You have selected an invalid choice" error"`. I even tried to update the `$form_state` variable to contain the same `#options` values populated by my ajax callback and nothing changes, also `$form_state->setRebuild(TRUE)` does nothing.

I'm almost giving up the idea of using ajax at all, since I've spent more than a week debugging just an ajax select element. First, the ajax callback wasnt being reached at all, now ajax populate happens, but cant submit form. It's just that I have this feeling that I've done 90% of the work involved, its just remaining 1 thing which I dont know. That remaining 10% is what I decided to throw this to the community. I'm sure someone else must know! Thanks for your help, guys...

# Answer
> 0 votes
It would be useful to have the actual code you wrote to check if there are some errors. If you check my relative question you can crossreference your code to check if there's something wrong (mine is currently working).

I'd suggest to:

1. apply the patch of this issue
2. if still not working do the same workaround I've used: check the $triggering\_element to populate the select options only in the opportune moments of the form build.

---
Tags: 8, ajax
---


# Question
Title: How can I send an HTML email from an Ajax callback?
I want to send an email to the user who forget username.

I created a functionality that handle with Ajax like send request to controller where I using a query to check whether user exist or not. if user exist I want to send email to used with his user name.

Is there any module that i can use to send email in this way

```
public function ForgotUsername() {
  $mail = \Drupal::request()->query->get('mail');
  $database = \Drupal::database();
  $username = $database->query("SELECT name from users_field_data where mail='$mail'")->fetchField();

  if (!empty($username)) {
    $module = 'modulename';
    $key = 'forgotusernamerecovery';
    $to = 'example@example.com';
    $langcode = '';
    $params = ['username' => 'Abc'];
    drupal_mail($module, $key, $to, $langcode, $params = [], $reply = NULL, $send = TRUE);

    $message = "<div class='matched'>Successs</div>";
  }
  else {
    $message = "<div class='notmatched'>notmatched</div>";
  }
  $response = new AjaxResponse();
  $response->addCommand(new HtmlCommand('.selector', $message));
  return $response;
}

```

# Answer
> 3 votes
I recommend the Easy Email module. It combines with Swiftmailer and Mailsystem, allowing for creating and sending HTML emails, using templates you can build with a ckeditor right in the interface. Then you can send mails from your module using the standard Drupal mail service, and it will take care of turning it into an HTML email. The video on the top page of the module page is very informative and explains it all. It's by far the best HTML email solution I've found in Drupal over the years.

# Answer
> 1 votes
Swiftmailer in combination withmail system let you send html mail if correctly configured. It's decently documented, the very short guide is:

1. go to: `admin/config/system/mailsystem`, set as formatter and sender swift mailer, use the front\whatever theme as theme for mail
2. (optional) set the formatter\sender for the specific module
3. go to `admin/config/swiftmailer/messages` check the configuration, the default should already work for html mails.

You could then override the opportune template twig to style your email. You can also definy a css file that swiftmailer will convert in inline-css. Check the readme for more details but in short you have to define inside the your\_theme.libraries.yml file

```
swiftmailer:
  css:
    theme:
      css/my_theme.mail.css: {}

```

# Answer
> 0 votes
You can send emails using the MailManager class. If you are in the context of an injectable class I would strongly suggest to use dependency injection.

If now you can simply call the service like so:

```
\Drupal::service('plugin.manager.mail')->mail($module, $key, $to, $langcode, $params = array(), $reply = NULL, $send = TRUE);

```

In short just change `drupal_mail(...)` to `\Drupal::service('plugin.manager.mail')->mail(...)` and i believe that the above code will work as you intend it to.

**Edit:** Also make sure that in your .module file there is a hook like the one below.

**Edit 2:** Also remember to add subject and body in your params. And correct your function call, because as it is now you overwrite the $params to an empty array when you call the function.

```
/**
 * Implements hook_mail().
 */
function MYMODULE_mail($key, &$message, $params) {
  $site_name = \Drupal::config('system.site')->get('name');
  $site_mail = \Drupal::config('system.site')->get('mail');

  switch ($key) {
    case 'my_module_key':
      $message['headers']['Reply-To'] = $site_mail;
      $message['headers']['From'] = $site_name . '< ' . $site_mail . ' >';
      $message['subject'] = $params['subject'];
      $message['body'][] = $params['body'];
      break;
  }

```

This hook will manipulate the data to be used for the construction of the mail and is mandatory for the mail service to work.

**Caution:** the $key you use must be the same with the $key provided in the mail function call and the modulename.. well should be obvious :P

---
Tags: 8, ajax, emails
---


# Question
Title: How can I switch back and forth between globally installed Drush versions?
I installed Drush 8 using `cgr` (which is a safer replacement for `composer global require`):

```
cgr drush/drush:8.x-dev --prefer-source

```

But now I also want to install Drush 9 for certain sites. Is there a way to switch between Drush 8 and 9 easily?

# Answer
As you probably know newer Drush versions have to be installed locally. Go ahead with installing Drush 10 (Drush 9 is EOL) for certain sites. The globally installed Drush acts as Drush Launcher and will find local Drush installs.
> 3 votes

---
Tags: drush, composer
---


# Question
Title: Javascript file attached via Drupal behaviours does not work occasionally
I'm facing a weird issue where a JS file attached via the Javascript API does not work properly. I couldn't really pin down why it isn't working by the JS file consists of a few event listeners which get attached to DOM elements and it looks like this:

```
(function ($, Drupal) {
  Drupal.behaviors.basics = {
    attach: function (context, settings) {
      if (context !== document) {
        return;
      }

     initPublicationsAccordion($)
     initBackground($)
     initNavbarFix($)
     initMobileNav($)
     initAuthorsDropdown($)
     setTimeout(() => initCarousel($), 500) // this fixes it
    }
  };
})(jQuery, Drupal);

```

and the corresponding `*.libraries.yml` file:

```
global:
  css:
    theme:
      css/main.css: {}
  dependencies:
    - core/drupal
    - core/jquery
    - drulma/bulma
    - drulma/mainjs

```

...

```
mainjs:
  js:
    js/main.js: {}
  dependencies:
    - core/drupal

```

There are no errors in the console, but I noticed I can make it work by wrapping the functions in a setTimeout. I would appreciate if anyone has an idea?

# Answer
> 1 votes
You are firing your event on document context, which happens only once (basically same as old school `$(document).ready()`). But a major point Drupal behaviors is that they are fired every time when somehing is added to the DOM, even when added with Ajax. (core's `BigPipe` might add blocks with Ajax, this module is enabled by default)

So instead of the one-shot

```
  Drupal.behaviors.basics = {
    attach: function (context, settings) {
      if (context !== document) {
        return;
      }
      ...do stuff

```

target the specific DOM nodes, e.g. if your carousel has a container
`<div class="my_fancy_carousel">...</div>`
attach the behavior to its class:

```
  Drupal.behaviors.my_fancy_carousel  {
    attach: function (context, settings) {
      $('.my_fancy_carousel', context).once('init_my_fancy_carousel').each( function() {
        ...do stuff...

```

Also notice the `.once('my_unique_identifier')` part which makes sure your functions don't trigger repeatly on the same DOM node

---
Tags: 8, javascript
---


# Question
Title: Converting a Views SQL query with INNER JOIN to an EntityQuery
I'm trying to create a custom JSON:API resource that returns the entities that have been flagged by a user. (The Flag module does not offer a way to get this out of the box.)

I used Views to build a query to show all terms flagged by the user:

```
SELECT taxonomy_term_field_data.tid AS tid, flagging_taxonomy_term_field_data.id AS flagging_taxonomy_term_field_data_id
FROM
{taxonomy_term_field_data} taxonomy_term_field_data
INNER JOIN {flagging} flagging_taxonomy_term_field_data ON taxonomy_term_field_data.tid = flagging_taxonomy_term_field_data.entity_id AND (flagging_taxonomy_term_field_data.flag_id = 'MY_FLAG' AND flagging_taxonomy_term_field_data.uid = 'MY_UID')

```

Then, I installed the JSON:API Resources module and configured a custom resource.

However, JSON:API uses EntityQuery, not regular SQL queries.

So based on my very limited knowledge of SQL, I wrote a basic query to get all the terms:

```
    $query = $this->getEntityQuery('taxonomy_term')
      ->condition($entity_type->getKey('bundle'), 'MY_VOCABULARY');

```

Now I want to restrict this to the terms that have been flagged by the user. How do I implement the INNER JOIN in the Views query in EntityQuery?

# Answer
> 3 votes
You can try hook\_query\_TAG\_alter

Sample code

```
$query = $this->getEntityQuery('taxonomy_term')
  ->condition($entity_type->getKey('bundle'), 'MY_VOCABULARY')->addTag('join_flaging');

/**
 * Implements hook_query_TAG_alter().
 */
function MYMODULE_query_join_flagging_alter(Drupal\Core\Database\Query\AlterableInterface $query) {
  $query->addJoin("INNER","flagging","flg","taxonomy_term_field_data.tid = flg.entity_id AND (flg.flag_id='MY_FLAG' AND flg.uid='MY_UID')");
}

```

# Answer
> 2 votes
As the flagging\_taxonomy\_term is an entity, see https://git.drupalcode.org/project/flag/-/blob/8.x-4.x/src/Entity/Flagging.php, according to this change-record, JOINS are supported, for you like:

```
<?php
$query = Drupal::entityQuery('taxonomy_term')
  // $UPDATE: ->condition($entity_type->getKey('bundle'), 'MY_VOCABULARY') use vid as bundle:
  ->condition('vid', 'MY_VOCABULARY')
  ->condition('flagging.entity.flag_id', 'YOUR_FLAG')
  ->condition('flagging.entity.uid', 1);

```

---
Tags: entities, database
---


# Question
Title: Getting Miss always in varnish cache for the page using REST API
While hitting URL using REST API, it is always giving Miss for varnish cache for specific path and giving response from Memcahce. In header if we can check for cache-control we are getting "must-revalidate, no-cache, private". Can someone guide us what exactly the issue or help us with the solution.

# Answer
First of all, we need to disable "shield" module from our modules and then we need to check Cloudfare rules for caching and need to update accordingly.
> 0 votes

---
Tags: caching
---


title: how to migrate multiple taxonomy terms?

text:
# Question
Title: how to migrate multiple taxonomy terms?
I have a an array like this from json.

```
[terms] => Array
  (
    [0] => Array
      (
        [id] => 1
        [Name] => term 1
      )
    [1] => Array
      (
        [id] => 2
        [Name] => term 2
      )
    [2] => Array
      (
       [id] => 3
       [Name] => term 3
      )
    [3] => Array
      (
       [id] => 4
       [Name] => term 4
      )
  )

```

I want to migrate them as taxonomy terms.

```
name:
    - plugin: sub_process
      source: terms
      process:
        value: Name

```

but this only migrate the firs term. `term 1`.

how will I migrate all?

# Answer
> 0 votes
I have used the following code to fix my problem.

```
keywords:
    - plugin: sub_process
      source: keyword
      process:
        value: Name
    - plugin: entity_generate
      value_key: name
      bundle_key: vid
      bundle: keyword
      entity_type: taxonomy_term
      ignore_case: true

```

I put it in the nodes migration file.

---
Tags: 8, migrations
---


title: How to update changed date for a node

text:
# Question
Title: How to update changed date for a node
I am migrating content from Drupal 7 to Drupal 8. Migration works fine except the changed date for node get changed to the current time. I want to set the timestamp to the Drupal 7 timestamp. I have tried out the following but it is not working.

```
        $changed_date = $node->getChangedTime();
        $node->set($source['parent_field_name'], $paragraph_target);
        $node->changed->value = $changed_date;
        // print_r($changed_date);die;
        $node->save();

```

# Answer
Not personally tested, but according this issue is a problem for already existing entities, while it should be resolved for new ones. Also, there's a module that seems to address this issue. So, I'd say:

1. try to create the node only in one step, to see if that preserve the original timestamp
2. if that fails, try either the patch or the module
> 0 votes

---
Tags: 8, migrations
---


title: How do I apply path alias patch?

text:
# Question
Title: How do I apply path alias patch?
I am updating a site from Drupal 8.7 to Drupal 8.8, and after running a drush updb, I encountered this error:

```
[error]  TypeError: Argument 2 passed to Drupal\pathauto\AliasStorageHelper::__construct() must be an instance of Drupal\path_alias\AliasRepositoryInterface, instance of Drupal\Core\Path\AliasRepository given, called in drupal/core/lib/Drupal/Component/DependencyInjection/Container.php on line 289 in Drupal\pathauto\AliasStorageHelper->__construct() (line 79 of drupal/modules/contrib/pathauto/src/AliasStorageHelper.php) #0 drupal/core/lib/Drupal/Component/DependencyInjection/Container.php(289): Drupal\pathauto\AliasStorageHelper->__construct(Object(Drupal\Core\Config\ConfigFactory), Object(Drupal\Core\Path\AliasRepository), Object(Drupal\Core\Database\Driver\mysql\Connection), Object(Drupal\pathauto\VerboseMessenger), Object(Drupal\Core\StringTranslation\TranslationManager), Object(Drupal\Core\Entity\EntityTypeManager))

```

I found a similar issue in this link here and there seems to be a solution(patch) for it.

EDIT:

I ran a composer command attempting to fix the path alias error:

composer require 'drupal/pathauto:1.x-dev@dev'

Ran composer update, and drush updb. The following is the error displayed by the console:

```
>  [error]  Argument 2 passed to Drupal\pathauto\AliasStorageHelper::__construct() must be an instance of Drupal\path_alias\AliasRepositoryInterface, instance of Drupal\Core\Path\AliasRepository given
>  [error]  Update failed: block_field_update_8001
> PHP Fatal error:  Uncaught ReflectionException: Class Drupal\path_alias\AliasRepository does not exist in /var/www/html/docroot/vendor/symfony/dependency-injection/ContainerBuilder.php:1174
> Stack trace:
> #0 /var/www/html/docroot/vendor/symfony/dependency-injection/ContainerBuilder.php(1174): ReflectionClass->__construct('Drupal\\path_ali...')
> #1 /var/www/html/docroot/vendor/symfony/dependency-injection/ContainerBuilder.php(634): Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object(Symfony\Component\DependencyInjection\Definition), Array, true, 'path_alias.repo...')
> #2 /var/www/html/docroot/vendor/symfony/dependency-injection/ContainerBuilder.php(1281): Symfony\Component\DependencyInjection\ContainerBuilder->doGet('path_alias.repo...', 1, Array, true)
> #3 /var/www/html/docroot/vendor/symfony/dependency-injection/ContainerBuilder.php(1238): Symfony\Component\DependencyInjection\ContainerBuilder->doResolveServices(Object(Symfony\Component\DependencyInjection\Reference), Array, true)
> #4 /var/www/html/docroot/ in /var/www/html/docroot/vendor/symfony/dependency-injection/ContainerBuilder.php on line 1174
 [error]  Update aborted by: system_update_8803, block_field_update_8001
 [error]  Finished performing updates.

```

Is there anything else I can do with the pathauto module?

# Answer
> 0 votes
Do you mean of "apply a patch" on a drupal module? You should use composer-patches, the github page cleary explain of setup it and use for a patch modules\core.

In your case it should be somethings like:

```
{
  "require": {
    "cweagans/composer-patches": "~1.0",
    "drupal/core-recommended": "^8.8",
  },
  "config": {
    "preferred-install": "source"
  },
  "extra": {
    "patches": {
      "drupal/pathauto": {
        "issue name": "https://www.drupal.org/files/issues/2020-04-27/3131286-3.patch"
      }
    }
  }
}

```

However, this issue is already "fixed", so it is already in the dev version of the module. Applying on the stable one could fail, so you'd just have to switch to the dev version of the module, aka

```
composer require 'drupal/pathauto:1.x-dev@dev'

```

Please note that is best to avoid on production dev version unless strictly necessary. In other words, if you switch to dev, you should update to the next release of pathauto asap it's released

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


# Question
Title: Custom js added with drupal_add_js doesn't actually get added if I enable "Aggregate JavaScript files" or "Cache blocks"
The site is the most stock, only Drupal 7 core is installed.

included my theme, where the page.tpl and html.tpl theme files are copied from core

I created a Yandex.Maps module, this is a block where js is added.

```
<?php
  function yamap_block_info(): array {
    $blocks['yamap'] = [
      'info'  => 'Block Yandex.Map',
      'cache' => DRUPAL_CACHE_PER_ROLE,
    ];
    return $blocks;
  }

  function yamap_theme(): array {
    return [
      'main-yamap' => [
        'template' => 'yamap-block',
      ],
    ];
  }

  function yamap_block_view($delta = ''): array {
    if ($delta == 'yamap') {
      $module_path = drupal_get_path('module', 'yamap');
      drupal_add_js($module_path . '/src/js/yamap.js', ['scope' => 'footer', 'weight' => 40]);
      drupal_add_css($module_path . '/src/css/yamap.css');

      return [
        'content' => theme('main-yamap'),
      ];
    }
  }
?>

```

When I enable cache and aggregation, js falls off .. there are no errors on the page and in the console.

Drupal.settings.my\_data does not exist too. But, if I turn off the block cache or aggregation, then everything is ok

# Answer
> -1 votes
Is the site in D7 or D8/9?

Because in 8+ you should use #attached instead of drupal\_add\_js/css

---
Tags: 7, css-js-aggregation
---


# Question
Title: Move images from a image field to another field
Some months ago I developed a D8 based website for a customer with an image field with multiple values, displayed as a Bootstrap Basic Image Gallery.

Now, my customer has changed his mind so now he wants to set the possibility to insert either an image or a video, so I decided to use Paragraphs to let him choose if he wants an Image or an embed Video.

The problem is that the customer has over 1000 nodes with an average of 3-4 images per node, so if I change the field to a Paragraph one, the images previously saved in the Image field are not moving to the Paragraph field.

Is there a way to "migrate" the images from an Image field to a Paragraph referenced Image field?

P.S: As you may understand, re-uploading the images again might be, if I can say, a PITA

# Answer
Welcome to SO, MineDoodler!

A little bit ago I found the same problem, so I developed this piece of code. (Note that I started a little bit ago with developing, it is possible to achieve this easier).

Read the comments to understand the code.

```

use \Drupal\node\Entity\Node;
use \Drupal\paragraphs\Entity\Paragraph;
use \Drupal\file\Entity\File;

function migrateImages() {
  // Get all products
  $query = \Drupal::entityQuery('node');
  $query->condition('status', 1);
  $query->condition('type', 'productos');
  $nids = $query->execute();

  $allNids = [];

  // In my case, i had a keyed array (First element was [213] => "157") so I turned into ([0] => "157")
  foreach ($nids as $nid) {
    $allNids[] = $nid;
  }

  // Go through every node
  for ($i = 0; $i < count($nids); $i++) {
    $nodeID = $allNids[$i];

    // Load node.
    $node = Node::load($nodeID);

    // Get current paragraphs (if already has any).
    $current = $node->get('field_prod_media')->getValue();

    // Go through every image this node has.
    foreach ($node->field_prod_img as $item) {
      // Create new paragraph
      $paragraph = Paragraph::create(['type' => 'YOUR_PARAGRAPH_TYPE']);

      // Load image
      $file = File::load($item->target_id);

      // Save image
      $paragraph->set('IMAGE_FIELD_IN_PARAGRAPH', $file);

      // Force the new "alt". I've done this because it wasn't saving the alt.
      $paragraph->field_img->alt = $item->alt;

      // Check if it's new and save it.
      $paragraph->isNew();
      $paragraph->save();

      // Add to the current paragraphs the new one.
      $current[] = array(
        'target_id' => $paragraph->id(),
        'target_revision_id' => $paragraph->getRevisionId(),
      );
    }

    // Set again all paragraphs, with the new ones.
    $node->set('field_prod_media', $current);
    $node->save();
    dpm("node ".$node->label()." has been saved!");
  }
}

```

Took the idea from #7 in this post and developed by my knowledge.

I forgot to mention that this code was executed in the Devel PHP, in the Devel module.
> 0 votes

---
Tags: 8
---


# Question
Title: How do I render nodes, now that node_view() has been deprecated?
In Drupal 7 I frequently use `node_view()` for rendering nodes (using view modes) in blocks or pages as follows:

```
$nids = array(123,456,789);
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
  $node_view = node_view($node, 'teaser');
  $output .= drupal_render($node_view);
}
$build['nodes']['#markup'] = $output;
return $build;

```

`node_view()`/`entity_view()` has been deprecated and replaced by a view builder as explained in change record Entities are now rendered by a view builder. The information is not detailed enough for me to be able to figure out how to achieve the same result.

How can you render nodes in Drupal 8 so that the output can be used in the render array of a block or page?

# Answer
> 51 votes
The answer given by Berdir uses `entityManager`, which has been deprecated in favor of more specific services. This is the code I currently use.

```
$nid = 1;
$entity_type = 'node';
$view_mode = 'teaser';

$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$node = $storage->load($nid);
$build = $view_builder->view($node, $view_mode);
$output = render($build);

```

This code is a little more verbose than some might like; you could reduce it down to a couple lines if you really want more brevity by chaining together some methods.

```
$nid = 1;
$entity_type = 'node';
$view_mode = 'teaser';

$node = \Drupal::entityTypeManager()->getStorage($entity_type)->load($nid);
$output = render(\Drupal::entityTypeManager()->getViewBuilder($entity_type)->view($node, $view_mode));

```

# Answer
> 22 votes
The most important part is to stop rendering yourself. You can return render arrays almost everywhere and you should do it. Combining strings like that together doesn't work anymore.

All you need is this:

```
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
// Or a use the static loadMultiple method on the entity class:
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);

// And then you can view/build them all together:
$build = \Drupal::entityTypeManager()->getViewBuilder('node')->viewMultiple($nodes, 'teaser');

```

# Answer
> 5 votes
`entity_view()` will be removed from Drupal 9.0.0. The following code works also in Drupal 9.

```
$render_controller = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId());
$render_output = $render_controller->view($entity, $view_mode, $langcode);

```

Essentially, that is the code used from `entity_view()`, after I removed the part handling the entity render cache, and replaced a deprecated method that function uses.

# Answer
> 3 votes
This did work for me (perfect for PHPUnit tests with Drupal test traits - https://gitlab.com/weitzman/drupal-test-traits):

```
$nid = 3139;
$entity_type = 'node';
$view_mode = 'bs_full_guest';

$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$node = $storage->load($nid);
$build = $view_builder->view($node, $view_mode);
$output = \Drupal::service('renderer')->renderRoot($build);
$nodeHtml = $output->__toString();

```

---
Tags: entities
---


# Question
Title: Adding multiple taxonomy terms to a node via code
I've been editing nodes in code (Drupal 8) like so:

```
$node = \Drupal\node\Entity\Node::load($nid);
$node->body->value = $body;
$node->title->value = $title;
$node->taxonomy_field->target_id = $value;

```

If the 'taxonomy\_field' entity reference supports multiple terms, how do place them in the $node object? I have tried at least a dozen ways I found on other threads, but none worked. Either errors were thrown, of the code just silently failed.

# Answer
> 1 votes
The object orientated way would be to use `appendItem()` from `FieldItemList`:

```
$node->field_tags->appendItem([target_id => '1']);

```

But as the field object provides an array interface you can add items to the field the same way as in a php array:

```
$node->field_tags[] = '2';

```

# Answer
> 0 votes
$node-\>field\_tags-\>appendItem(\[target\_id =\> '1'\]); worked for me but $node-\>field\_tags\[\] = '2'; did not.

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


# Question
Title: Composer installing dev modules getting Authentication required (git.drupalcode.org)
When trying to composer install, and it reaches one of the modules using a Dev version, I get:

`- Installing drupal/paragraphs (dev-1.x 42842d5): Authentication required (git.drupalcode.org): Username:`

I tried removing the `vendor` folder, I tried removing my `composer.lock` file, I tried updating my git, and I tried `composer clearcache`. Nothing worked.

Also, I tried `composer install` and `composer install --no-dev`, and both didn't work.

Anyone ever experiences this before? I never had this issue until today...I'm also using WAMP if that helps too.

Here's my composer.json file:

```
{
"name": "drupal/recommended-project",
"description": "Project template for Drupal 8 projects with a relocated document root",
"type": "project",
"license": "GPL-2.0-or-later",
"homepage": "https://www.drupal.org/project/drupal",
"support": {
    "docs": "https://www.drupal.org/docs/user_guide/en/index.html",
    "chat": "https://www.drupal.org/node/314178"
},
"repositories": [
    {
        "type": "composer",
        "url": "https://packages.drupal.org/8"
    },
    { "type": "composer",
      "url": "https://asset-packagist.org"
    }
],
"require": {
    "composer/installers": "^1.2",
    "cweagans/composer-patches": "^1.6",
    "drupal/addtoany": "^1.14",
    "drupal/admin_toolbar": "^2.2",
    "drupal/adminimal_admin_toolbar": "^1.11",
    "drupal/adminimal_theme": "^1.5",
    "drupal/background_image": "^1.5",
    "drupal/bigmenu": "^2.0",
    "drupal/block_content_permissions": "^1.10",
    "drupal/calendar": "1.x-dev",
    "drupal/captcha": "^1.1",
    "drupal/conditional_styles": "^1.0",
    "drupal/context": "^4.0",
    "drupal/core-composer-scaffold": "^8.8",
    "drupal/core-recommended": "^8.8",
    "drupal/devel": "^4.0",
    "drupal/draggableviews": "^1.2",
    "drupal/easy_breadcrumb": "^1.12",
    "drupal/entity_block": "^1.0",
    "drupal/eva": "^2.0",
    "drupal/field_group": "^3.0",
    "drupal/filefield_sources": "^1.0",
    "drupal/flexslider": "^2.0",
    "drupal/google_analytics": "^2.5",
    "drupal/image_effects": "^3.0",
    "drupal/imce": "^2.2",
    "drupal/layout_builder_component_attributes": "^1.0",
    "drupal/libraries": "^3.0",
    "drupal/login_security": "^1.5",
    "drupal/mailsystem": "^4.3",
    "drupal/menu_block": "^1.6",
    "drupal/menus_attribute": "^1.1",
    "drupal/migrate_file": "^1.1",
    "drupal/migrate_plus": "^4.2",
    "drupal/migrate_tools": "^4.5",
    "drupal/migrate_upgrade": "^3.2",
    "drupal/mimemail": "^1.0",
    "drupal/module_filter": "^3.1",
    "drupal/override_node_options": "^2.5",
    "drupal/page_manager": "^4.0",
    "drupal/panelizer": "^4.4",
    "drupal/panels": "^4.6",
    "drupal/paragraphs": "1.x-dev",
    "drupal/password_policy": "^3.0",
    "drupal/pathauto": "1.x-dev",
    "drupal/protected_pages": "^1.2",
    "drupal/recaptcha": "^3.0",
    "drupal/redirect": "^1.6",
    "drupal/scheduler": "^1.3",
    "drupal/search_api": "^1.17",
    "drupal/search_api_page": "^1.0",
    "drupal/search_api_solr": "^4.0",
    "drupal/security_review": "^1.0",
    "drupal/sidr": "^3.1",
    "drupal/smart_trim": "^1.3",
    "drupal/text_resize": "^1.1",
    "drupal/twig_field_value": "^2.0",
    "drupal/twig_tweak": "^2.6",
    "drupal/views_data_export": "^1.0",
    "drupal/views_field_view": "^1.0",
    "drupal/views_slideshow": "^4.7",
    "drupal/webform": "^5.16",
    "drupal/xmlsitemap": "^1.0",
    "kint-php/kint": "^3.3",
    "oomphinc/composer-installers-extender": "^1.1"
},
"conflict": {
    "drupal/drupal": "*"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
    "sort-packages": true
},
"extra": {
    "installer-types": ["npm-asset"],
    "patches": {
        "drupal/core": {
            "Call to a member function getColumns() on boolean": "https://www.drupal.org/files/issues/2020-10-29/2893747-33.patch",
            "Call to a member function getTranslation() on null in ContentEntityBase": "https://www.drupal.org/files/issues/2020-01-24/core-ContentEntityBase_getTranslation_on_null-3108528-2.patch",
            "system_update_8804() fails if any path alias is created before it runs": "https://www.drupal.org/files/issues/2020-08-13/3098718-core.system_update_8804.truncate_path_alias_tables-69.patch"
        },
        "drupal/panels": {
            "Custom attributes in panels blocks and variants": "https://www.drupal.org/files/issues/2020-04-30/panels_custom_attributes_in_panels_blocks-2849867-78.patch"
        },
        "drupal/menu_block": {
            "Hide region when block menu is empty": "https://raw.githubusercontent.com/stef-van-looveren/drupal-8-patches/master/menu_block-8.x-1.5-empty-region.patch"
        },
        "drupal/pathauto": {
            "Custom aliases (which are not generated with the actual patterns) can be lost during the migration": "https://www.drupal.org/files/issues/2020-11-17/pathauto-prevent_losing_custom_aliases-3079275-17--combined-with-3179835-and-3179865.patch"
        },
        "drupal/calendar": {
            "Node with calendar block wont display": "https://www.drupal.org/files/issues/2019-12-11/fix_error_for_missing_url_from_view_display-2993422-2.patch"
        }
    },
    "drupal-scaffold": {
        "locations": {
            "web-root": "web/"
        },
        "file-mapping": {
            "[web-root]/robots.txt": false,
            "[web-root]/README.txt": false,
            "[web-root]/INSTALL.txt": false,
            "[web-root]/example.gitignore": false,
            "[web-root]/modules/README.txt": false,
            "[web-root]/profiles/README.txt": false,
            "[web-root]/themes/README.txt": false,
            "[web-root]/sites/README.txt": false,
            "[web-root]/sites/default/default.services.yml": false
        }
    },
    "installer-paths": {
        "web/core": [
            "type:drupal-core"
        ],
        "web/libraries/{$name}": [
            "type:drupal-library",
            "type:npm-asset"
        ],
        "web/modules/contrib/{$name}": [
            "type:drupal-module"
        ],
        "web/profiles/contrib/{$name}": [
            "type:drupal-profile"
        ],
        "web/themes/contrib/{$name}": [
            "type:drupal-theme"
        ],
        "drush/Commands/contrib/{$name}": [
            "type:drupal-drush"
        ],
        "web/modules/custom/{$name}": [
            "type:drupal-custom-module"
        ],
        "web/themes/custom/{$name}": [
            "type:drupal-custom-theme"
        ]
    },
    "drupal-core-project-message": {
        "include-keys": [
            "homepage",
            "support"
        ],
        "post-create-project-cmd-message": [
            "<bg=blue;fg=white>                                                         </>",
            "<bg=blue;fg=white>  Congratulations, you’ve installed the Drupal codebase  </>",
            "<bg=blue;fg=white>  from the drupal/recommended-project template!          </>",
            "<bg=blue;fg=white>                                                         </>",
            "",
            "<bg=yellow;fg=black>Next steps</>:",
            "  * Install the site: https://www.drupal.org/docs/8/install",
            "  * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html",
            "  * Get support: https://www.drupal.org/support",
            "  * Get involved with the Drupal community:",
            "      https://www.drupal.org/getting-involved",
            "  * Remove the plugin that prints this message:",
            "      composer remove drupal/core-project-message"
        ]
    }
 }
}

```

Thanks!

# Answer
This issue happens when you are requesting packages through composer from corporate network. Corporate firewall blocks the network request. The credentials it is asking is actually for corporate proxy.

Just connect to open internet and try again your issue will be probably resolved.
> 5 votes

# Answer
I figured it out! turns out my anti-virus is blocking `git.drupalcode.org/`. Had to add `git.drupalcode.org/*` to my whitelist.
> 2 votes

---
Tags: 8, composer
---


title: Help with URL argument token

text:
# Question
Title: Help with URL argument token
I'm trying to use tokens in the Linked Field module to link a field in one content type to another content type. I'm also using Pathauto.

So I want to link a field in URL `/type/subtype/pagetitle` to destination URL `/type/subtype`.

I've tried `[current-page:url:args:first]/[current-page:url:args:second]` but the second token doesn't work and the resulting URL is just `/type`.

I've tried using the `[node:field_nameofsubtype]` token but that results in `/type/Sub Type` instead of the `/type/subtype` generated by my Pathauto.

Surely it isn't that hard to use tokens to just move one step up the URL tree but I can't find it. What am I doing wrong?

# Answer
Done it!! This works anyway:

```
[current-page:url:args:first]/[current-page:url:args:value:1]

```
> 1 votes

---
Tags: tokens
---


# Question
Title: Why are the labels for two different form elements so different? Can I make them the same?
I created a webform that has one textfield and two radio button fields.

When displaying, the textfield label is themed correctly, but the radio button labels are not.

When I look at the tags and classes, the texfield label has a "label" tag with "control-label" class like this

```
<label for="textfield1" class="control-label">Textfield label</label>

```

but the radio labels have "span" tags with "fieldset-legend" class, inside "legend" tags, like this

```
<legend>
    <span class="fieldset-legend">Radio element question</span>
  </legend>

```

Why are they different? Can I ake them the same, or is add a CSS style to make the span.fieldset-legend match the label.control-label the only way to make them the same?

I am using the Bootstrap 3 theme and I enabled the webform-bootstrap module.

# Answer
> 2 votes
The differences here come down to the differences in the two types of form elements.

From the MDN docs for the label element:

> The HTML element represents a caption for **an item** in a user interface

From the MDN docs for the legend element:

> The HTML element represents a caption for the content of its parent .

Looking at the example from the legend documentation, we see how the two types of elements, labels and legends, are semantically different.

```
<fieldset>
    <legend>Choose your favorite monster</legend>

    <input type="radio" id="kraken" name="monster">
    <label for="kraken">Kraken</label><br/>

    <input type="radio" id="sasquatch" name="monster">
    <label for="sasquatch">Sasquatch</label><br/>

    <input type="radio" id="mothman" name="monster">
    <label for="mothman">Mothman</label>
</fieldset>

```

Each radio button has its own label element with text describing it. Meanwhile, the set of radio buttons is wrapped in a fieldset with a legend element to describe the group as a whole.

While you may be able to alter the markup for your radios, to replace the legend element with a label, you should not, especially if you're trying to build an accessible website (and you should be). This answer to Is it good practice to use for non-input/non-interactive elements? provides a more detailed explanation for why you shouldn't use a label in a context like this.

---
Tags: 8, theming, webforms
---


# Question
Title: How can I replace the hyphens in front of child terms with something else?
What code is responsible for adding `-` in front of taxonomy term sublevels on a taxonomy field in a node edit form?

Even though the most non-intrusive way to override it is preferred, I'm comfortable even with core patches.

# Answer
Looks like there is no easy way to override them, they are added by `TermSelection::getReferenceableEntities` in `core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php:73`:

```
$options[$vocabulary->id()][$term->id()] = str_repeat('-', $term->depth) . Html::escape($this->entityRepository->getTranslationFromContext($term)->label());

```

If you decide to edit it, I suggest using a Composer patch system afterwards if you are using Composer.
> 1 votes

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