# Question
Title: Why/How I could remove index.php in the URL
I have added a RewriteRule to force https on one domain at the end of my .htaccess file

```
RewriteCond %{HTTP_HOST} ^www.mydomain\.be [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}

```

It is working fine except that after that, I get a `/index.php/` inside all URL

If I add `RewriteEngine on` before like the following:

```
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.mysite\.be [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}

```

Then my `/index.php/` problem is solved...

I am happy with that, but I don't understand why

Note: Those lines are added at the end of a regular drupal .htaccess. I mean no change in it except that I have uncommented the all to "www" rule (before my https rule at the end)

```
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

```

There are no special apache2 conf as welll

# Answer
> 1 votes
I suggest you look at the .htaccess file supplied with Drupal, beside index.php. In the standard one, it has rules for both redirecting http: to https: (line ~104) and for rewriting URIs to index.php (line ~136)

Some servers are configured with these rules in the main config file because relying on .htaccess results in slower response from Apache (it reads the main files on startup but .htaccess per request).

So: \- Remove any additional rules you have added (i.e. revert to "out of the box") and check for expected behaviour; \- Uncomment the protossl conditions in .htaccess and check again; \- Optionally, move some of these into the .conf file for faster response.

---
Tags: .htaccess
---


# Question
Title: jsonapi Cross-Origin Read Blocking (CORB) blocked cross-origin response in vue
I got the data with postman in json:api at drupal.  But I has error of CORB in Vue-resource.get() with code blew：

```
 data(){
    return{
        cyclePic:[],
        rootUrl:this.$http.options.root,
        header:{headers:{Accept:'application/vnd.api+json',
            'Content-type':'application/vnd.api+json',
            Authorization:"Basic dG1wQWRtaW46VG1wQDEyMyM0NTY="}
            }
    }
},
created(){
    this.getCycleList()
},
methods:{
    getCycleList(){

        this.$http.get('jsonapi/node/banner?include=field_image',this.header).then(result=>{
            console.log(result)

            if(result.ok && result.status===200){
                this.cyclePic=result.body.included
                console.log(this.cyclePic)
            }else{
                Toast('Fail')
            }

        })
    }

```

what i miss some thing?

# Answer
You need to set up your Cors settings Look at your services.yml file then read ...

How do I set up CORS?
> 0 votes

---
Tags: 8
---


title: Views: URL Alias as a field

text:
# Question
Title: Views: URL Alias as a field
How do I get the URL alias of a node in views.

Here is a previous question, Get a url alias as a field value? However, the Content: Link field outputs something along the lines of

```
<a href="url">view</a>

```

I want to wrap the link around another field using rewrite results and tokens. Something like

```
<a href="/[url-alias]">[product:image]</a>

```

I was able to do this with

```
<a href="node/[nid]">[product:image]</a>

```

However, I would rather have it show the node alias than the node ID.

# Answer
> 8 votes
If you click on Content: Path it will give you the a field that repesents the path of the node.

# Answer
> 6 votes
Just an update for those than land here for Drupal 8.5+

The Path field no longer exists in views, you now need the "Link To Content" field instead. If you need to output the path only, then make sure you tick the "Out put URL as Text" option.

Reference: Issue raised on DO after Path field disappeared in Drupal 8.5.0

# Answer
> -1 votes
Firstly, it is not a good idea to write the url in a href manually, because it won't work if you move your site to a subdirectory.

You can rewrite a field in view and click make this field a link giving the URL to the provided text field. You can use tokens as you wrote and this is the best practice to do it, so that you can always change the aliases and the link won't break.

Then you can install the Global Redirect module and set it to always use URL aliases. This makes your site also more optimized for search engines, preventing duplicate content penalty.

# Answer
> -4 votes
Have you ever tried the Views PHP module? You could use it to do something like the following:

```
<a href="<?php print url('node/'.$data->nid)?>">Print Image Here</a>

```

Mind you, you will need to have the image field added before the PHP field. You will also need to exclude it so it doesn't show up twice.

---
Tags: views, path-aliases
---


# Question
Title: How can I render an HTML table in a block?
i have created a module for showing third party API data

here is some data returned from that API

```
{"ObjectId":43,"ObjectName":"MEGA MELA","ObjectTitle":"Event Created by API","ObjectDescription":"NEW EVENT BY API","ObjectLabel":"","ObjectTypeId":33,"MaxFieldsExpected":5,"ObjectValueType":null,"ObjectControlType":"","IsDeleted":true,"CreatedDate":"2019-05-22T07:56:03.767","CreatedBy":null,"EditedDate":null,"EditedBy":null,"DeletedDate":null},{"ObjectId":44,"ObjectName":"Event x11","ObjectTitle":"Event Created by API","ObjectDescription":"NEW EVENT BY API","ObjectLabel":"","ObjectTypeId":33,"MaxFieldsExpected":5,"ObjectValueType":null,"ObjectControlType":"","IsDeleted":true,"CreatedDate":"2019-05-23T00:33:50.7","CreatedBy":null,"EditedDate":null,"EditedBy":null,"DeletedDate":null}]}

```

i have created a custom module to show some of this data in a block

this is my module directory hierarchy , module directory name is `apihtml`

```
 -apihtml
    -src
      -Plugin
        -Block
          -rest.php

    -apihtml.info.yml

```

as you can see there are just two files `apihtml.info.yml` and `rest.php`

here is `apihtml.info.yml` content

```
 name: Third Party Api Data with html
    type: module
    description: 'This is for showing rest data in ui with html'
    package: Custom
    version: 8.x
    core: 8.x
    dependencies:
      - node
      - block

```

and here is `rest.php` content

```
   <?php

/**
 * @file
 */
namespace Drupal\apihtml\Plugin\Block;
use Drupal\Core\Access\AccessResult;

use Drupal\Core\Block\BlockBase;
use Drupal\Component\Serialization\Json;

/**
 * Creates a 'Foobar' Block
 * @Block(
 * id = "AntShow with html formatting",
 * admin_label = @Translation("Ant Show & HTML"),
 * )
 */
class rest extends BlockBase {
 public function build() {
    /** @var \GuzzleHttp\Client $client */
    $client = \Drupal::service('http_client_factory')->fromOptions([
      'base_uri' => 'http://myApiPath',
    ]);

       $response = $client->get('objects/events');

    $dec = Json::decode($response->getBody());

    $items = [];

foreach ($dec as $d) {
    foreach ($d as $ins) {
  $items[] = $ins['ObjectName'] ;

    }
}

         return [
      '#theme' => 'item_list',
      '#items' => $items,

    ];

  }
}

```

here by using `array` `Key` `ObjecName` i am able to show object name in block

here is the block OutPut

MEGA MELA
Event x11

but i want something more
i want to show this API returned data in the tabular form means the `array key` should be the `header` of the `data` value data will be in `rows`

like this

```
   ObjectId  | ObjectName | ObjectTitle           | ObjectDescription | ObjectLabel | ObjectTypeId | MaxFieldsExpected | ObjectValueType | ObjectControlType | IsDeleted | CreatedDate | CreatedBy | EditedDate |  EditedBy
    43        |  MEGA MELA |  Event Created by API | NEW EVENT BY API | ..............................................................................

```

in this Drupal block all the data displayed has to be returned in `build` function in `rest.php` file

this is the code which shows data returned by api in tabular format

```
     foreach ($dec as $d) {
  ?>
    <table>
<?php foreach ($d as $ins) { ?>
<tr>
<?php
 foreach ($ins as $key=>$value) {
   echo "<td><h3>".$key."</h3></td>";
 } ?>
</tr>
<tr>
<?php
 foreach ($ins as $key=>$value) {
   echo "<td><h3>".$value."</h3></td>";
 } ?>
</tr><?php
} ?>
</table> <?php
}

```

But i am not getting how can i put this code in `build` `function` of `rest.php` to show tabular data in the `block`

# Answer
> 1 votes
You can use the table theme type to do this. In your build section, return a render array that includes this:

```
return [
  '#type' => 'table',
  '#header' => $header,
  '#rows' => $rows,
];

```

Where header is an array of strings and rows is an array of row value arrays.

Some reference items I found:

New render element #type 'table'

Render arrays

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


title: How do I enable the ETag header?

text:
# Question
Title: How do I enable the ETag header?
I'd like my JSON:API responses to return the e-tag header so that consuming remote sites can determine (e.g. with a HEAD request) if they need to ditch their cached responses and re-fetch. There is no last-modified or e-tag headers being sent at all - for any Drupal page for that matter. How can I enable this? Thanks!

I do see `X-Drupal-Dynamic-Cache` and `X-Drupal-Cache` headers, but this isn't enough to go on.

Running Drupal 8.6.10 and JSON:API 8.x-2.4.

# Answer
I changed the "Browser and proxy cache maximum age" setting in Configuration \> Development \> Performance and it appeared to do the trick. It was previously set to "no caching".
> 1 votes

---
Tags: caching
---


# Question
Title: How to filter Views records by day-of-week, including multiples
I have a need to filter many records by the day of the week derived from a date-only field in those records (i.e. not today's dow).

I would like a solution that works with views filters, as the wider context is that the view itself is being manipulated in code to supply which days should be included -- note plural. Basically, a paragraph is configured with List(text) fields for the weekdays and during preprocess the view is loaded and the field values 'poked' into the view's value instead of the fixed original value. Several other fields are updated likewise.

If I was doing this in plain SQL I might use DATE\_FORMAT(fieldname, "%a") IN ("Wed", "Fri") or something similar. I have looked at various existing modules - views\_dates and views\_date\_format\_sql in depth - and have noted D7-only views\_dow. However I can't quite see a way forward using those (even as a base), partly because I'm not very familiar with views internals.

# Answer
I have managed to create a usable filter, though there is still a portability issue. This is the filter class I ended up with:

```
/**
 * Filter to handle dates stored as a timestamp.
 *
 * @ingroup views_filter_handlers
 *
 * @ViewsFilter("views_dates_day_of_week")
 */
class DayOfWeek extends InOperator {

  /**
   * {@inheritdoc}
   */
  protected function opSimple() {
    if (empty($this->value)) {
      return;
    }
    $this->ensureMyTable();

    /** @var \Drupal\views\Plugin\views\query\Sql $query */
    $query = $this->query;

    $placeholder = $this->placeholder().'[]';
    $fieldexpr = $this->getDateField();
    // For PostgreSQL use EXTRACT (DOW FROM field), result is numeric.
    // For SQLite use strftime("%w", field), result is numeric.
    // BUT : How to tell if these are needed!!
    $lhs = "DATE_FORMAT({$fieldexpr}, '%w')";
    $snippet = $lhs . ' IN (' . $placeholder . ')';
    // Keys are 0..6, to match %w format.
    $possibles = array_keys($this->value);

    $query->addWhereExpression(
      $this->options['group'],
      $snippet,
      [$placeholder => $possibles]
    );
  }

  /**
   * Return an array of day names, keyed by the value of the %w date format.
   *
   * If the 'options callback' is defined, use it to return values, otherwise
   * use the predefined (translatable) versions.
   *
   * Cache the return value in $this->valueOptions for speed.
   *
   * @return array|null
   *   The array of names, keyed by integer 0..6 representing Sunday - Saturday.
   */
  public function getValueOptions() {
    if (isset($this->valueOptions)) {
      return $this->valueOptions;
    }

    if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) {
      if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) {
        $this->valueOptions = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']);
      }
      else {
        $this->valueOptions = call_user_func($this->definition['options callback']);
      }
    }
    else {
      // Keys are 0..6 and starting Sunday, to match %w format.
      $this->valueOptions = [
        '0' => $this->t('Sunday'),
        '1' => $this->t('Monday'),
        '2' => $this->t('Tuesday'),
        '3' => $this->t('Wednesday'),
        '4' => $this->t('Thursday'),
        '5' => $this->t('Friday'),
        '6' => $this->t('Saturday'),
      ];
    }

    return $this->valueOptions;
  }
}

```

Note that the implementation of opSimple has hard-coded use of MySQL. I was unable to find out which DB type this operation is using and therefore adapt to the SQL used by that DB. The builtin 'dateSQL' member of $this is protected and marked views-internal, preventing it being used to identify the db type. I also used the array placeholder feature of Drupal (the ".'\[\]'" on the placeholder variable) to avoid having to separately quote all the IN values. I also cannot see a way to avoid this operation requiring a sequential search of the db table :(

I switched to using numbers (2) rather than abbrev-names (Tue) because that was more portable between db types and possibly faster. The rest of the code I have inherited/adapted from the drupal.org/project/views\_dates:

Add to views\_dates.filter.schema.yml:

```
views.filter.views_dates_day_of_week:
  type: views.filter.in_operator
  label: 'DoW'
  mapping:
    type:
      type: string
      label: 'Type'

```

Add an entry in views\_dates\_views\_data\_alter(), which is :

```
$data[$table_name][$base_field_id . '_dow'] = [
  'title' => t( '@label as day name', ['@label' => $base_field_label]),
  'help' => t( '@label as day name 0 - 6, representing Sunday (0) to Saturday (6).', ['@label' => $base_field_label]),
  'argument' => [
    'field' => $base_field_id,
    'id' => 'date_dow',
  ],
  'filter' => [
    'field' => $base_field_id,
    'id' => 'views_dates_day_of_week',
  ],
];

```

Note that, in views\_dates.module, entity type 'node' is skipped from adding these new filters - you may wish to change this!
> 0 votes

---
Tags: views, 8
---


title: How to import taxonomy with hierarchy?

text:
# Question
Title: How to import taxonomy with hierarchy?
We're upgrading our site from D7 to D8, which has vocabulary containing multi-level parent-child hierarchy. The list is too long (around 5K-10K terms) to import manually.

We've tried using migrate in D8 Core and extending it using migrate\_plus and migrate\_tools module. These works really well when there is no term hierarchy.

How can we get it working for importing term with hierarchy. The value it accepts for parent is term id. If we pass the parent name (as we're importing it for first-time), it creates the term at root level. Are we missing anything? If we can not do this only with these modules, how can we extend these modules. References would also greatly appreciated.

# Answer
If you want to import `Taxonomy with Hierarchy` along with the existing `tid` then follow the following. Configure your import configuration some thing like this

```
id: taxonomy_migration
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags:
 - CSV
migration_group: null
label: 'Taxonomy migration from CSV'
source:
  plugin: csv
  path: test.csv //path of file
  header_row_count: 1
  keys:
    - tid //unique key which is used for mapping while importing other content related with this taxonomy
process:
  parent: //this is for your parent term id
    plugin: migration_lookup
    migration: taxonomy_migration //this is the current migration id which will help you to make parent child on taxonomy
    source: pid //parent id source from your csv file
  name: term
  tid: tid
destination:
  plugin: 'entity:taxonomy_term'
  default_bundle: test_taxonomy //your vocabulary machine name where you want to import
migration_dependencies: null
migration_dependencies: null

```

now your `csv` file will be like this

now you can check your taxonomy, result will be like in the image below with existing `tid`.
> 9 votes

# Answer
It's a little late, but I think I just solved this...

In your migrate.whatever.yml file you have to add a process plugin in the parent source:

```
destination:
  plugin: entity:taxonomy_term

process:
  vid: vocab
  name: name
  weight: weight
  parent:
    -
      plugin: migration
      migration: whatever // This should be the name of your current migration
      source: parent // This is the name of the source field
      no_stub: true
    -
      plugin: default_value // Not required, but useful for large data sets
      default_value: 0

```
> 5 votes

# Answer
Alternative solution to Migrate module is to use Term CSV Export Import module which supports import a list of terms with parent structure.

Example format of CSV file:

```
name,description,format,weight,parent_name,[any_additional_fields]

```
> 0 votes

# Answer
There is a module that can import hierarchical taxonomy terms with ease. Have a look at Drupal 8 version of module and its name is **Hierarchical Taxonomy Importer**.

This can import terms on nested levels from a CSV file. Here is the link of module.

https://www.drupal.org/project/hti

There is no limitation for parent child relationship depth.
> 0 votes

# Answer
See this Patch: https://www.drupal.org/project/drupal/issues/2965938#comment-12587479

```
# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- a/core/modules/migrate/src/MigrateExecutable.php
+++ b/core/modules/migrate/src/MigrateExecutable.php
@@ -363,8 +363,18 @@
           $break = FALSE;
           foreach ($value as $scalar_value) {
             try {
-              $new_value[] = $plugin->transform($scalar_value, $this, $row, $destination);
+//              $new_value[] = $plugin->transform($scalar_value, $this, $row, $destination);
+                // reserve salar value
+                            $result = $plugin->transform($scalar_value, $this, $row, $destination);
+                            // fix parent_id always return null on MigrationLookup::transform
+                            if (is_null($result)) {
+                                if ($scalar_value) {
+                                    $new_value[] = $scalar_value;
             }
+                            } else {
+                                $new_value[] = $result;
+                            }
+            }
             catch (MigrateSkipProcessException $e) {
               $new_value[] = NULL;
               $break = TRUE;

```
> 0 votes

# Answer
I was a bit disappointed with using migration modules, and I quickly started using my own scripts. Below a script to import a taxonomy with hierarchy:

```
// You would first have to create an array $results from csv or other source
// Make sure you have tid, title and parent in your set
foreach($results as $result) {
  Term::create([
    'tid' => $result->tid,
    'name' => $result->name,
    'vid' => 'MY_NEW_VOCABULARY'
  ])->enforceIsNew()->save();
}
// Reload and resave to add hierarchy
foreach($results as $result) {
  $term = Term::load($result->tid);
  $term->parent = ['target_id' => $result->parent];
  $term->save();
}
// Smile! You imported your tags while keeping their tid and hierarchy

```
> 0 votes

# Answer
For me this solve the problem:

```
  # Only attempt to stub real (non-zero) parents.
  parent_id:
    -
      plugin: skip_on_empty
      method: process
      source: parent
    -
      plugin: migration_lookup
      migration: d7_taxonomy_term // this migration
  parent:
    plugin: default_value
    default_value: 0
    source: '@parent_id'

```

Source: https://api.drupal.org/api/drupal/core%21modules%21taxonomy%21migrations%21d7\_taxonomy\_term.yml/8.6.x
> 0 votes

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


# Question
Title: How to add unique class to each checkbox elements
I am displaying checkboxes using form API in Drupal 8. For functional and theming purpose I need to add unique custom class to each checkbox element. Is there any way to add classes to each checkbox elements on wrapper/label/input level?

Here is my form API for checkbox element.

```
  public function buildForm(array $form, FormStateInterface $form_state,
   $items = array()) {
    $tids = [5,8,7,9,3,1,45];
    $terms = Term::loadMultiple($tids);
    foreach($terms as $term) {
        $name = $term->getName();
        $options[$term->id()] = $term->getName();
    }
    $default= [5];

    $form['category_type'] = [
        '#type' => 'checkboxes',
        '#options' => $options,
        '#default_value' => $default,
        '#ajax' => [
            'callback' => '::searchCallback',
            'method' => 'replace',
            'effect' => 'fade',
        ],
    ];

    return $form;
 }

```

I have tried to theme through hook\_prepeocess\_HOOK() but its not rendering in final my custom class.

```
   function mytheme_preprocess_input(&$variables) {
      $element = $variables['element'];
      if (isset($element['#id']) && $element['#type'] == 'checkbox') {
        $variables['element']['#attributes']['class'][] = 'my-custom-class';
      }
    }

```

Any help on this will be highly appreciated. Thanks in advance

# Answer
> 4 votes
I think the Form Options Attribute module will solve this for you. It allows you to add option attributes in the form element render array. Below is the example from the module page. It also supports checkboxes as well.

```
$form['states'] = array(
  '#type' => 'select',
  '#title' => t('States'),
  '#options' => array(
    'AL' => t('Alabama'),
    'AK' => t('Alaska'),
    'AZ' => t('Arizona'),
    'AR' => t('Arkansas'),
    // ..
    'WI' => t('Wisconsin'),
    'WY' => t('Wyoming'),
  ),
  '#options_attributes' => array(
    'AL' => array('class' => array('southeast'), 'data-bbq-meat' => 'pork'),
    'AK' => array('class' => array('non-contiguous'), 'data-bbq-meat' => 'salmon'),
    'AZ' => array('class' => array('southwest'), 'data-bbq-meat' => 'rattlesnake'),
    'AR' => array('class' => array('south'), 'data-bbq-meat' => 'beef'),
    // ...
    'WI' => array('class' => array('midwest'), 'data-bbq-meat' => 'cheese'),
    'WY' => array('class' => array('flyover'), 'data-bbq-meat' => 'bison'),
    ),
  '#attributes' => array('class' => array('states-bbq-selector')),
);

```

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


# Question
Title: How can I purge a specific URL from varnish cache without making a curl request?
I'm programmatically updating images and keeping the same file name. I flush the image styles for the image when I do this, but I'm running into an issue where my image styles aren't being regenerated because the old image style is being loaded from varnish when the attempt to regenerate them is made. I've read (in a couple places, including this related Drupal answer How can I clear the Varnish cache?) that I can clear the cache with a curl request:

```
curl -X PURGE -H "Host: domain.com" http://127.0.0.1/test.html

```

How can I use an existing method in the Purge or Acquia Purge modules to clear the cache for a given url, specifically an image style url?

Note: I've seen the purge\_queuer\_url module, but that is not a viable solution for me.

**Update:** I don't even think this was happening. I can't reproduce the varnish cache hits at all so I must've been wrong about that. I found a bug elsewhere with the focal\_point module that was causing my image styles to not be recreated properly.

# Answer
> 6 votes
Here's some code that I use to clear Acquia varish via the Purge / Acquia purge modules when a pdf with the same name is uploaded. You could expand on this to clear the styles cache as well.

```
/**
 * Implements hook_entity_update().
 */
function my_module_entity_update(EntityInterface $entity) {
  $type = $entity->getEntityTypeId();
  if ($type != 'file') {
    return;
  }
  // \Drupal::logger('my_module')->debug("File entity found");
  $purgeInvalidationFactory = \Drupal::service('purge.invalidation.factory');
  $purgeQueuers = \Drupal::service('purge.queuers');
  $purgeQueue = \Drupal::service('purge.queue');

  $queuer = $purgeQueuers->get('coretags');
  // Invalidate cache tags so all pages that have the file get banned from varnish
  // Also invalidate the file's url.
  $invalidations = [
      $purgeInvalidationFactory->get('tag', 'file:' . $entity->id()),
      $purgeInvalidationFactory->get('url', file_create_url($entity->getFileUri())),
  ];

  $purgeQueue->add($queuer, $invalidations);
}

```

---
Tags: 8, caching
---


# Question
Title: How can I add an AJAX callback to a checkbox?
I am using taxonomy manager module I want to add ajax callback to checkbox tree view for checkbox is checked condition but it is not working can some one please suggest me. I have modified the code like this

```
$form[$term->tid]['checkbox'] = array(
      '#type' => ($multiple) ? 'checkbox' : 'radio',
      '#title' => $term->name, // Escaping is done in theme wrappers.
      '#value' => $value,
      '#return_value' => $term->tid,
      '#ajax' => array(
        'callback' => 'ajax_example_autocheckboxes_callback',
        'wrapper' => 'checkboxes-div',
        'method' => 'replace',
        'effect' => 'fade',
      ),
      '#required' => FALSE,
      '#theme_wrappers' => ($multiple) ? array('taxonomy_manager_tree_checkbox') : array('taxonomy_manager_tree_radio'),
      '#highlight' => in_array($term->tid, $terms_to_highlight) ? TRUE : FALSE,
    );

```

This is the taxonomy manager module theme function.

```
function theme_taxonomy_manager_tree_checkbox($variables) {
  global $user;
  $element = $variables['element'];
  $element['#attributes']['type'] = 'checkbox';
  $element['#attributes']['ajax']['event'] = 'change';
  element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));

  // Unchecked checkbox has #value of integer 0.
  if (!empty($element['#checked'])) {
    $element['#attributes']['checked'] = 'checked';
  }
  _form_set_class($element, array('form-checkbox'));
  $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
  /* custom alter function */
  if(user_is_logged_in()){
    if(!user_access('administer taxonomy')){
      $cdms_taxonomy_id = taxonomy_term_load($element['#return_value']);
      // echo "IF"; exit;
    }else{
      $cdms_taxonomy_id = taxonomy_term_load($element['#return_value']);
      // echo "Else"; exit;
    }
  }
  // echo '<pre>';print_r($variables);  echo"Term load"; print_r($cdms_taxonomy_id);  exit;
  $data = [
    'title' =>  $element['#title'],
    'tid' => @$cdms_taxonomy_id->field_cdms_txy_id[LANGUAGE_NONE][0][value],
    'count' => '',
  ];
  // Calling all modules implementing hook_my_data_alter():
  drupal_alter('my_data', $data);

  if (!in_array("Client User", array_values($user->roles))) {
  $title = $element['#title'] ."(".$data['count'].")";
}else{
   $title = $element['#title'];
}
  if (in_array("Client User", array_values($user->roles))) {
    $title = check_plain($title);
  }else{
    if (isset($element['#link'])) {
        $attr = array();
        $attr["class"][] = "term-data-link";
        $attr["class"][] = "term-data-link-id-" . $element['#return_value'];
        if (isset($element['#extra_info'])) {
          $attr["title"] = $element['#extra_info'];
        }
        $title = l($title, $element['#link'], array('attributes' => $attr));
      }
      else {
        $title = check_plain($title);
      }
  }

  $element['#children'] = '<label class="option">' . $output . ' ' . $title . '</label>';
  $element['#title_display'] = 'none';
  return theme('form_element', array('element' => $element));
}

```

# Answer
`ajax_example_autocheckboxes_callback` function is not defined in the above code.

Also please update more info about what you are trying to do.

```
$form[$term->tid] = array(... 'ajax_example_autocheckboxes_callback' ...); //ajax callback
$form['tree']; //new field.

```

after the above function call you can get new `built_info` of `$form_state` as its rebuilt. So you can alter output of the field.

```
function ajax_example_autocheckboxes_callback($form, $form_state) {
  dsm($form_state);
  return $form['tree']; // this is a new field.
}

```

I will update my answer if more information is provided.
> 0 votes

---
Tags: 7, forms, ajax
---


title: Field collection item code not working

text:
# Question
Title: Field collection item code not working
Hi Every one I am trying to create new field collection item programmatically but code is not working. I want to create a number of field collection items but no Luck. My code is following.

```
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\field_collection\Entity\FieldCollectionItem;

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if($form_id == 'my_form'){

for($i = 0; $i < 2; $i++) {

$new_experience_item = FieldCollectionItem::create(['field_name' => 'field_collection_name']);

      }

    }

}

```

My first Question-\> Can we run this code in the hook\_form\_alter? If yes, Then why my code is not working perfectly?

# Answer
> 0 votes
Paragraphs or Field Collection doesn't matter for your code. You need to add the newly created items to a field.

For example if the field collection field is in a node:

`$node->field_collection_name[] = $new_item;`

Not in a form alter hook, but in an entity create hook. See the linked question.

---
Tags: 8, hooks
---


# Question
Title: How do I get a plaintext list of tags from a multi value entity reference field?
I have a module that's making custom RSS feeds for me.

In a content type, I have my tags stored in "field\_tags" entity reference field.

My goal is to get the names of all the tags, and ultimately put them into an array, so they can go into a markupless RSS field.

When I'm pulling the data, I get it with this:

```
foreach ($this->dbh->selectVideos(self::RPP) as $nid) {
  $node = $this->entityMgr->getStorage('node')->load($nid);

  if (!empty($node)) {
    $data->nodes[] = [
      'title'    => $this->filterTxt($node->title->value),
      'body'     => $this->filterTxt($node->get('field_paragraph')->value),
      'body2'     => $this->filterTxt($node->get('field_paragraph')->value),
      'created'  => date('D, d M Y H:i:s', $node->created->value) . ' GMT',
      'guid'     => $node->id(),
      'img'      => $this->getImgUrl($node, self::IMG_FIELD),
      'keywords' => $this->filterTxt($node->get('field_tags')->value),
      'video'    => $node->get('field_vid_url')->getString(),
    ];
  }
}
return $this->render($data, 'nameoffeed');

```

}

The problem is that 'field\_tags' is an entity reference field, so it's turning up blank.

I had partial success with this:

```
    if ($node->hasField('field_tags')){
      $entity_ref = $node->get('field_tags');
      if ($entity_ref->count() > 0){
        $tagoutput = entity_view($entity_ref->entity, 'default');
      }

```

Then setting 'keywords' to equal $tagoutput. This grabs the first tag, which isn't great as I need them all, and then along with it comes a whole html layout enclosure that won't work for an RSS feed.

I'm confused what the correct way is to get a proper list of tag names. In D6 I had this list as plain text, which wasn't great because you wouldn't be able to click on one in the page view and be taken to a list of all pages with that tag, but at least the tags worked on the feeds easily.

Any thoughts?

# Answer
> 1 votes
How do I get a plaintext list of tags from a multi value entity reference field?

```
$tag_names = [];
foreach ($node->field_tags->referencedEntities() as $term) {
  $tag_names[] = $term->getName();
}

```

# Answer
> 0 votes
You can get the array of reference entities from node using

> $node-\>get('field\_tags')-\>referencedEntities();

So the code will look something like below:

```
// Get the referenced entities
$tags = $node->get('field_tags')->referencedEntities();
// Check if we have output. (Assuming we get an array, You will have to check what your output it.)
if (!empty($tags)) {
  // Go through each entity.
  foreach ($tags as $tag) {
    // Write your Business Logic here to create your Keywords Array.
  }
}
// Use the Keywords Array for further use.

```

I Hope this helps you.

---
Tags: entities
---


# Question
Title: Why is data-quickedit-entity being printed in plain text when I'm signed in?
I have a template for theming paragraph sections that, for some reason, prints out data-quickedit-entity-id="paragraph/2" in plaintext above any of my paragraphs that contain images.

```
{% set bgcolor = content.field_background_colour[0]["#markup"] ?: color_class %}
{% set bundle = paragraph.bundle ?: base_class %}
{% set image = content.field_section_image|without("label") %}
{%
  set classes = [
    "paragraph"|clean_class,
    "paragraph--" ~ bundle|clean_class,
    "paragraph--" ~ bundle|clean_class ~ "--" ~ bgcolor|clean_class,
  ]
%}
{{kint(attributes)}}
{% if attributes %}
  <div{{ attributes.addClass(classes) }}>
{% else %}
  <div class="{% for class in classes %}{{ class ~ " " }}{% endfor %}">
{% endif %}

<div class="paragraph--{{ bundle }}__inner">
{% if content %}
  {{ content.field_main_heading }}
    {% if content.field_sub_heading %}
      {{ content.field_sub_heading }}
    {% endif %}
    {% if content.field_section_image["#title"] %}
    {{ attributes.removeClass(classes) }}
      {% include "@base/layouts/grid/00-grid.twig" with {
        items: [image, content.field_body_text],
        grid_base_class: "grid",
        grid_modifiers: ["columns-2"]
        } %}
    {% else %}
      {{ content.field_body_text }}
    {% endif %}
{% else %}
  {{ dummy_content|raw }}
{% endif %}
</div>
</div>

```

This happens right above the image, inside the on line 18. Screenshot below:

It only gets output when logged in as it's obviously something to do with the quickedit system.

Has anyone seen this or can advise on how to prevent it?

# Answer
This line prints the attributes in plain text:

```
{{ attributes.removeClass(classes) }}

```

If you want to remove classes without printing then use `set`:

```
{% set attributes = attributes.removeClass(classes) %}

```
> 0 votes

---
Tags: entities
---


# Question
Title: How do I skip importing a duplicate item?
I use unique field mapping, but instead of blocking the import on duplicates from CSV, it overwrites the data in Drupal and inserts the new value from the CSV file.

This is the default behavior with unique title field mapping:

"IF the title is duplicate THEN overwrite old item in Drupal with new item from spreadsheet"

But I'm looking for this behaviour:

"IF the title is duplicate THEN skip new item from spreadsheet, and keep old original item in Drupal intact"

I have field tamper, the item field AND the importer field all set to unique. It all works fine, but on duplicate feed imports, instead of preventing import of duplicate items, it overwrites the old field, and inserts the new duplicate...

My goal is for Drupal to PREVENT the duplicate field to be populated at all...the same way if you manually try to input a duplicate entry in manually imputing content, it shows an error and prevents you from submitting the form.

Is this even possible without custom code? Maybe with rules?

# Answer
> 1 votes
I have a hard time parsing your question. This is what I think you want:

* If the source item has a title that already exists on the website, don't import this item.
* If the source item has a title that does *not* exist on the website, import as a new item.

So if above are your only requirements, it would imply that you don't need to update existing content. In this case, the solution is:

1. On the processor settings, set "Update existing" to "Do not update existing".
2. On the mapping page, only set "Title" as unique.

From your story though, I sense that there might be more going on than just the above scenario, but I'm not exactly sure what it is.

---
Tags: 7, feeds
---


# Question
Title: How to inject a new variable into a menu template
I have a menu with a machine name of `menu-principal`, which in turn has a theme hook of `menu__menu_principal` and a template of `menu--menu-principal.html.twig`. I'm trying to inject another menu into the template in a variable so that I can render it in this menu template but so far have been unsuccessful.

I tried to add a preprocess function to my `MY_THEME.theme` but this doesn't seem to work. My code is as follows:

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYTHEME_preprocess_menu__menu_principal(&$variables) {
  $menu_tree_service = \Drupal::service('menu.link_tree');
  $menu_name = 'menu-quicklinks';
  $menu_parameters = new \Drupal\Core\Menu\MenuTreeParameters();
  $tree = $menu_tree_service->load($menu_name, $menu_parameters);
  $variables['quicklinks'] = $tree;
}

```

When I go to to the template and use `{{ kint() }}` to dump out the defined variables, I don't see the variable. I only see the following:

I then found this answer and tried the following, using the example from the answer there:

```
/**
 * Implements hook_theme_registry_alter().
 */
function MY_THEME_theme_registry_alter(&$theme_registry) {
  $theme_registry['menu__menu_principal']['variables']['quicklinks'] = [];
}

```

I used `dd()` to verify that `$theme_registry['menu__menu_principal']['variables']` existed and that the variables were definitely being set in the theme registry, but it still didn't work.

# Answer
I had the same issue, but i was using `{{ dump() }}` to debug the template

## The problem

I have the same arguments when i am using `{{ dump() }}` inside macro tags. For example:

```
   {% macro menu_links(items, attributes, menu_level ) %}
       {{ dump() }}
       ... code ...
   {% endmacro %}

```

If you focus on function `menu_links()`, you realize that variables are available in your degug trace. So, the macro tags have isolated the bunch of code and variables can't be accessed.

## The solution

If you place the debug code outside of macro tags, you can see the variables that has been passed throught a preproccess function. For example:

```
   # You can see here your variables
   {{ dump() }}

   {% macro menu_links(items, attributes, menu_level ) %}
       ... code ...
   {% endmacro %}

```

**How can you pass variables to macro ?**

There are an invocation of `menu_links()` in template, so you only need to add all the arguments you want to pass them to the macro.

```
   {{ menus.menu_links(items, attributes, 0, my_custom_argument ) }}

   {% macro menu_links(items, attributes, menu_level, my_custom_argument ) %}
       ... code ...
   {% endmacro %}

```
> 4 votes

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


title: Content entity doesn't load on edit

text:
# Question
Title: Content entity doesn't load on edit
I have a custom entity, `BaseEstablishment` which is an abstract base class, implemented by `Practice`.

```
abstract class BaseEstablishment extends ContentEntityBase implements EntityOwnerInterface {
    // The necessary functions required for get/set methods
    // The baseFieldDefinitions method
    public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
        $fields = parent::baseFieldDefinitions($entity_type);
        // Standard field, used as unique if primary index.
        $fields['id'] = BaseFieldDefinition::create('integer')
              ->setLabel(t('ID'))
              ->setDescription(t('The ID of the entity.'))
              ->setReadOnly(TRUE);
        // Standard field, unique outside of the scope of the current project.
        $fields['uuid'] = BaseFieldDefinition::create('uuid')
              ->setLabel(t('UUID'))
              ->setDescription(t('The UUID of the entity.'))
              ->setReadOnly(TRUE);
       /*=====================================================*/
       // Name field for the establishment (vc 256)
       $fields['name'] = BaseFieldDefinition::create('string')
          ->setLabel(t('Name'))
          ->setDescription(t('Name of the establishment.'))
          ->setRequired(TRUE)
          ->setSettings([
                  'default_value' => '',
                  'max_length' => 256,
                  'text_processing' => 0,
          ])
          ->setDisplayOptions('view', [
                'label' => 'above',
                'type' => 'string',
                'weight' => -5,
          ])
          ->setDisplayOptions('form', [
                'type' => 'string_textfield',
                'weight' => -5,
          ])
          ->setDisplayConfigurable('form', TRUE)
          ->setDisplayConfigurable('view', TRUE);
        $fields['affiliated_users'] =

        BaseFieldDefinition::create('entity_reference')
          ->setLabel(t('Affiliated Users'))
          ->setDescription(t('The users allowed to manage this     establishment.'))
          ->setRevisionable(FALSE)
          ->setRequired(FALSE)
          ->setSettings([
                  'target_type' => 'user',
                  'default_value' => 0,
                ]
              )
          ->setCardinality(-1)
          ->setDisplayOptions('view', [
                'label' => 'hidden',
                'type' => 'author',
                'weight' => 0,
          ]);
    // Rest of fields that I need
    return $fields;
    }
}

/**
* Defines the practice entity class.
*
* There are many more properties to be used in an entity type definition. For
* a complete overview, please refer to the '\Drupal\Core\Entity\EntityType'
* class definition.
*
* @ingroup practice
*
* @ContentEntityType(
*   id = "myentity_practice",
*   label = @Translation("Practice"),
*   label_collection = @Translation("Practice"),
*   label_singular = @Translation("Practice"),
*   label_plural = @Translation("Practices"),
*   label_count = @PluralTranslation(
*     singular = "@count practice",
*     plural = "@count practices"
*   ),
*   handlers = {
*     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
*     "list_builder" = "Drupal\myentity\Entity\Controller\PracticeListBuilder",
*     "form" = {
*       "add" = "Drupal\myentity\Entity\Form\PracticeForm",
*       "edit" = "Drupal\myentity\Entity\Form\PracticeForm",
*       "delete" = "Drupal\myentity\Entity\Form\PracticeDeleteForm",
*     },
*   },
*   base_table = "_practice",
*   data_table = "myentity_practice_data",
*   fieldable = FALSE,
*   translatable = FALSE,
*   entity_keys = {
*     "id" = "id",
*     "uuid" = "uuid",
*     "owner" = "uid",
*   },
*   links = {
*     "canonical" = "/practice/{id}",
*     "delete-form" = "/practice/{id}/delete",
*     "edit-form" = "/practice/{id}/edit",
*     "collection" = "/practice/list"
*   },
*   field_ui_base_route = "myentity.admin.entity.practice.main",
* )
*/
class Practice extends BaseEstablishment implements PracticeInterface {
    // Any changes that are required for the practice entity.
    // The PracticeInterface extends the EstablishmentInterface,
    // which exposes all the required get/set methods.
    // There aren't many changes that happen here;
    // I've commented out everything in this file
    // and the issue still persists.
}

class PracticeForm extends ContentEntityForm {
    public function buildForm(array $form, FormStateInterface $form_state) {
        $form = parent::buildForm($form, $form_state);
        /**
         * This is always null,
         * regardless of whether it is accessed via:
         * /practice/add or /practice/{id}/edit
         */
        $entity = $this->entity;

        if (is_null($entity->id()) {
            $form['#title'] = $this->t("Add Practice");
        } else {
            // $entity->getName() is a getter method defined by the practice interface.
            $form['#title'] = $this->t("Edit " . $entity->getName());
        }

        // rest of customization to the form that are dependent upon the conditional above.

        return $form;
    }
}

```

The above is the PHP code that drives the entity. I'm not sure if it's necessary, but the routing file is below:

```
#########################################################
# Practice Admin/User paths
#########################################################
myentity.admin.entity.practice.main:
  path: '/admin/content/practice'
  defaults:
    _entity_list: 'myentity_practice'
    _title: 'Practice List'
  requirements:
    # Checks for permission directly.
    _permission: 'administer site'

myentity.user.entity.practice.form.add:
  path: '/practice/add'
  defaults:
    # Calls the form.add controller, defined in the practice entity.
    _entity_form: 'myentity_practice.add'
    _title: 'Add Practice'
  requirements:
    _permission: 'administer site'

myentity.user.entity.practice.form.edit:
  path: '/practice/{id}/edit'
  defaults:
    # Calls the form.edit controller, defined in the practice entity.
    _entity_form: 'myentity_practice.edit'
    _title: 'Edit Practice'
  requirements:
    _permission: 'administer site'
#    _permission: 'authenticated user'

myentity.user.entity.practice.form.delete:
  path: '/practice/{id}/delete'
  defaults:
    # Calls the form.delete controller, defined in the practice entity.
    _entity_form: 'myentity_practice.delete'
    _title: 'Delete Practice'
  requirements:
    _permission: 'administer site'

```

The problem is that when I add a practice through the form: `/practice/add`, it correctly stores it in the database. However, when I go to: `practice/1/edit`, the entity is *always* null, I can see it in the database and it is listed on `PracticeListBuilder` page.

As for trying to figure out what the issue is: I've tried minimizing the total fields added -- removing the `EntityOwner` and my custom affiliated users field. I don't understand why the entity is always null when trying to edit the entity.

# Answer
> 1 votes
The parameter should be the machine name of the entity, then it will be upcast to an entity object.

---
Tags: 8, entities
---


# Question
Title: Get data from remote REST API (read only)
We use a remote service (not Drupal) to publish press releases and to show those releases in a remote newsroom.

This remote service offers an API so we should be able to fetch and show the newsroom on our Drupal site. To use the API a custom token must be present in the request header and the method used must be GET:

```
Notified-Custom-Token: [TOKEN]

```

This is what I have done so far in a custom module named notified\_api. \[custom token\] is replaced by a unique token genererated for our newsroom and \[id\] is replaced by our newsroom ID:

```
function notified_api_preprocess_page(&$variables) {
  // Fetch newsroom from Notified API with custom token
  $headers =  array('Authorization'=>'Notified-Custom-Token [token]', 'Content-Type'=>'application/json' );
  $url = "https://api.newsroom.notified.com/api/newsrooms/[id]";

  $options=array('headers'=>$headers, 'method'=>'GET');

  $result=drupal_http_request($url, $options);

  dpm($result);
}

```

Partial result from the dpm:

```
... (Object) stdClass
url (String, 53 characters ) https://api.newsroom.notified.com/api/newsrooms...
status (String, 5 characters ) Done.
code (Integer) 401
chunk_size (Integer) 32768
data (String, 0 characters )
request (String, 438 characters ) GET /api/newsrooms/345345 HTTP/1.0 Authorizatio...
GET /api/newsrooms/345345 HTTP/1.0
Authorization: Notified-Custom-Token 9832502938403876504329820348ewieitrje...
Content-Type: application/json
User-Agent: Drupal (+http://drupal.org/)
Connection: close
Host: api.newsroom.notified.com

options (Array, 20 elements)
headers (Array, 5 elements)
Authorization (String, 258 characters ) Notified-Custom-Token 9832502938403876504329820348ewieitrje...
Content-Type (String, 16 characters ) application/json
User-Agent (String, 28 characters ) Drupal (+http://drupal.org/)
Connection (String, 5 characters ) close
Host (String, 25 characters ) api.newsroom.notified.com
method (String, 3 characters ) GET

```

What I get is a 401 message: **unauthorized**. Can anyone see what I am doing wrong?

# Answer
> 0 votes
In case anyone else have the same problem. By replacing the name "Authorization" like this:

```
  $headers =  array('Notified-Custom-Token'=>'my-unique-token', 'Content-Type'=>'text/json' );

```

... it worked and I got a success response with code 200. My mistake was to believe that Authorization was a mandatory name in the name/value pair.

---
Tags: 7, http-request
---


# Question
Title: Is it possible to create/manage Roles using a .yaml file?
I'm trying to secure some REST URLs that are present in my **ApiController.php** so that users with certain privileges can access these REST APIs. I created some users and assigned them with some Roles using the below link:

https://www.drupal.org/docs/user\_guide/en/user-concept.html

As you can see, I'm creating roles in Drupal Admin following below steps:

***Drupal UI → People → Role → Add New Role // line 4***

After that, I added a few permissions in permission.yml:

**xyz.permissions.yml**

```
edit permission:
  title: 'edit permission'

```

And updated routing file to secure APIs:

**xyz.routing.yml**

```
xyz.update:
  path: '/update'
    _controller: 'ApiController::update'
    _permission: 'edit permission'

```

This is working fine. i.e. users that have "edit permission" can access URL "/update". But, I don't want to do step on line 4 rather I would like to use some .yaml file to create Roles.

# Answer
User roles are defined in YML files called `user.role.ROLENAME.yml`.

Do a config export (`drush cex`) to get an idea how these files should look like (they will be written to your `config/sync` directory).

Then create your custom role YML files in `my_module/config/install` and they will be created when you enable your module (if you took a YML file from `config/sync` as blueprint, remove the `uuid` and `default_config_hash` keys)

The file should look something like this:

```
langcode: en
status: true
dependencies: {  }
id: my_custom_role
label: My custom role
weight: 1234
is_admin: null
permissions:
  - 'do fancy stuff'

```
> 3 votes

---
Tags: theming
---


# Question
Title: Problem installing Knowledge base module
I installed Drupal using the Bitnami stack. I'm trying to install the knowledge base module from https://www.drupal.org/project/kb . I have installed and enabled the modules upon which it is dependent but when I try to enable the knowledge base module itself I get the error

Unable to install KnowledgeBase due to unmet dependencies: core.entity\_form\_display.node.kb\_content.default (field.field.node.kb\_content.body)

Obviously I am still missing a dependency and it's telling me what it is but what is but how do I fulfill the requirement?

Further, I can see the core.entity\_form\_display.node.kb\_content.default yml file in C:\Bitnami\drupal-8.7.2-1\apps\drupal\htdocs\modules\kb\config\install when I use file explorer.

Is the yml file in the wrong place? Or do I need to do something with it so the knowledgebase install knows about it?

Can someone tell me what I need to do? Please excuse if it's obvious I am a newbie to Drupal.

Thanks for any help, Roscoe

# Answer
> 0 votes
The install yml is not in the wrong place. This is a new module with 1 install currently in beta state so you might face a few problems with it if not all bugs are not ironed out but perhaps this is not the case.

The error message is not that helpful I must admit. If you want to see what dependencies you are missing you go into the .info.yml file and can also be seen online here and here is the relevant section

```
...
dependencies:
  - drupal:field
  - drupal:file
  - drupal:text
  - drupal:node
  - drupal:group
  - drupal:gnode
  - drupal:views
  - drupal:views_jump_menu
  - drupal:eva

```

for field, file, text, node, views are part of core (nothing to do)

but you have to download https://www.drupal.org/project/group (for group and gnode) https://www.drupal.org/project/views\_jump\_menu https://www.drupal.org/project/eva

before you are able to install this module

I suggest that you start looking into installing things using composer that takes care of the dependencies for you so if you did

```
composer require drupal/kb

```

all the dependencies would also be installed for you

More info about composer based drupal installations can be found here and here and perhaps other places but those are good starting points

---
Tags: installation
---


# Question
Title: Get author id in field template - or make an edit button on a node's teaser
* I am using Display Suite to display Teasers of a custom content type Project in a View.
* I want to show link on each Teaser to edit that node *if the logged in user is the author of the node*.
* Our requirements *do not allow us* to use Contextual Links with the little hover gear.

**Things I have tried:**

* I was also able to make a Display Suite field for `[node:author:uid]` and display that field in the Teaser.
* I was able to create a Display Suite field to hold the link and display it in the Teaser.
* I was able to create a custom field template for that Project Edit Button field I just made and display it in the Teaser. `field--field-project-edit-button.html.twig`.
* This is where I hoped to wrap the content of that field (the link) in a conditional statement.

**However**

* In the past I have been able to access fields in a different field's template using this technique. `{{ element['#object'].field_name.value }}`
* I was able to do this with a Display Suite field for `[node:nid]` and then do `{{ element['#object'].nid.value }}` (where `nid` is the machine name of my `[node:nid]` Display Suite field) in the Project Button field template above.
* It also works to use it in a conditional statement like `{% if element['#object'].nid.value == 6 %}`.
* But this same technique is *not* working with `{{ element['#object'].aid.value }}` (where `aid` is the machine name of my Display Suite 'Author ID' field). It just comes back empty.

**So**

What is different about my `[node:author:uid]` and `[node:nid]` fields?

Why am I seeing the actual Author ID field properly but not `{{ element['#object'].aid.value }}` in the edit link's field template?

How do I make this silly button? I am completely open to other ways of doing this as long as it meets my requirements at the top of this post.

**FULL SOLUTION, thanks to No Sssweat below**

Display Suite token field:

```
<a href="[node:edit-url]" class="btn btn-sm btn-outline-info"><span class="fa fa-pencil"></span> Edit <span class="sr-only">[node:title]</span></a>

```

In the .theme file under mytheme\_preprocess\_field

```
/* Make the current user id available in field templates */
$vars['uid'] = \Drupal::currentUser()->id();

```

In that custom field template:

```
{% if element['#object'].getOwner.uid.value == uid %}
  {% for item in items %}
    {{ item.content }}
  {% endfor %}
{% endif %}

```

# Answer
> 0 votes
Assuming in your use case an Author is a user on your site, I believe you will be able to access to Author's ID using

`{{ element['#object'].getOwner.uid.value }}`

No need to create a custom field to hold the author's value.

# Answer
> 0 votes
First, this should be the simplest way for getting the the author's id in a twig template.

```
{{ node.getOwnerId }}

```

Second, I would use the path() function and the entity.user.canonical route with the user id to create the link to the user's page. This won't break if you choose to alias the user pages.

```
<a href="{{ path('entity.user.canonical', {user: node.getOwnerId}) }}">
   {{ author_pic }}
</a>

```

---
Tags: 8
---


# Question
Title: "Uncaught ReflectionException: Class DOMDocument does not exist" error
On Ubuntu 16.04, I installed Drush using Composer: `composer global require drush/drush:~8`. Installation succeeded, but running `drush --version`, I got this error:

> PHP Fatal error: Uncaught ReflectionException: Class DOMDocument does not exist in /.../composer/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php:24

What do I do now?

# Answer
> 26 votes
DOMDocument is included in the extension php-xml. To install it on ubuntu, run:

```
sudo apt-get install php-xml

```

# Answer
> 3 votes
Same problem on my machine, where I have php-5.6 and php-7.0 installed.

To fix this issue I have installed `php5.6-xml` and `php7.0-xml` too.

# Answer
> 1 votes
Checking your php version first by command line:

```
php -v

```

and install the corresponding php-xml extension (eg: php5.6-xml; php7.0-xml; php7.1-xml; php7.2-xml).

---
Tags: drush, composer
---


# Question
Title: How to get a backtrace in Drupal, without problems like out-of-memory when huge objects are in the trace?
I often have problems with the standard backtracing functions when working with Drupal:

* `debug_print_backtrace();` often seems to get lost between pages and never prints,
* Drupal's objects and classes are often so big that `debug( debug_backtrace(), "Backtrace", true );` can kill my server with out of memory errors, and `debug( debug_backtrace() );` almost always fails with a "Nested dependency" recursion error.

Is there any alternative to the above approaches that can be used reliably, ideally as a drop-in function without needing to set up any framework?

# Answer
I find this useful as a less memory intensive Drupal-friendly way to backtrace PHP as a one-off code snippet to temporarily drop into a troublesome location without installing modules or server-side tools:

```
  $trace = debug_backtrace();
  $backtrace_lite = array();
  foreach( $trace as $call ) {
    $backtrace_lite[] = $call['function']."    ".$call['file']."    line ".$call['line'];
  }
  debug( $backtrace_lite, "TRACE", true );

```

It gets the backtrace into Drupal's debugging system, but strips it down to the essentials to avoid failures when massive objects are involved.

For handy reference, the other keys within each row of the debug\_backtrace() object are:

* class
* object
* type
* args

---

Note - this answer was first posted in the now-deleted too-broad question How do I debug Drupal?
> 5 votes

# Answer
More compact variant:

```
  $backtrace_lite = array_map(function($call_item) {
    return "{$call_item['function']} -> {$call_item['file']} -> line {$call_item['line']}";
  }, debug_backtrace());

```
> 2 votes

---
Tags: 7, debugging
---


title: Add Open Graph Metatag in backend

text:
# Question
Title: Add Open Graph Metatag in backend
I need to set the og:iamge metatag using the Metatag Module. Since there is no option for editing the names of the metatags or adding custom ones, I'm unsure if this is possible.

Is it possible to do this not programatically/from the backend?

# Answer
Provided you installed the Metatag and Metatag Open Graph extensions, you need to:

* Go to the metatag configuration page (/admin/config/search/metatag).
* Edit the desired config
* Under the `Open Graph` tab, fill the Image field with the relative path to your image
* Save your config.
* When expanding the config you modified, you can see the list of metatags you set (on my example I edited the `Global` configuration). You can see that og\_image is in it.
> 1 votes

---
Tags: meta-tags
---


# Question
Title: Drupal 8's last minor release = Drupal 9?
I have read about the planned release date of Drupal 9 is scheduled to be on June 3rd, 2020. I read this documentation about how to prepare a Drupal 8 site for Drupal 9:

Prepare a Drupal 8 site for Drupal 9

In the document it says:

"1. Keep Drupal core up to date. Drupal 8's last minor release will become Drupal 9."

Does it mean that when we update the Drupal 8 core to the last minor release of Drupal 8, it will automatically convert our site to use Drupal 9 and we don't have to radically change, migrate or redevelop our sites again in Drupal 9?

In summary, is Drupal 8 core's last minor release = Drupal 9?

# Answer
Yes, upgrading from Drupal 8 to 9 is scheduled to be an incremental update from the last minor version of Drupal 8.

It seems the main thing to consider is to remove any usage of deprecated functions to ensure a smooth upgrade.

> Contributed project developers, as well as those maintaining custom integrations, should follow the deprecations when possible and use the latest APIs available. This means that when Drupal 9 is released they will have to make fewer changes to be compatible

https://www.drupal.org/core/deprecation
> 6 votes

---
Tags: upgrading, 9
---


# Question
Title: Variable default_bundle in migration? Field collection to varying paragraph types
I'm trying to migrate a D7 field collection to D8 paragraphs, but to a different paragraph bundle type depending on the value in one of the field collection's fields.

The logic is as follows: If the field collection's field\_type value is "header", the migration should create a header paragraph type. If the field collection's field\_type value is "card" it should migrate to a card paragraph type.

I'm trying to set a variable in process, and assign the value of that variable to default\_bundle in the destination, but it's not working, the paragraph type is empty for the entities created by this migration:

```
langcode: en
status: true
dependencies: { }
id: d7_field_collection_list_items
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags:
 - 'Drupal 7'
migration_group: migrate_drupal_7
label: FC
source:
  plugin: d7_field_collection_item
  key: migrate
  field_name: field_list_item
process:
  temp_bundle_type:
    plugin: static_map
    source: field_list_item_type
    map:
      card: card
      header: header
    default_value: card
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: '@temp_bundle_type'
migration_dependencies:
  required: { }
  optional: { }

```

What is the correct way to achieve what I am trying to do? I have tried several other methods without success.

# Answer
> 1 votes
Don't use the `default_bundle` at all, instead set the bundle type like other field values in the process section:

```
process:
  temp_bundle_type:
    plugin: static_map
    source: field_list_item_type
    map:
      card: card
      header: header
    default_value: card
  type: '@temp_bundle_type'

```

# Answer
> 0 votes
If we want to migrate field collection to paragraphs first you should create paragraph types and it's fields manually. There is no automation available yet to create paragraph types.

After that you can write migration script in .yml format to migrate content.

Reference(Migrating data from a SQL source): https://www.mtech-llc.com/blog/ada-hernandez/migration-field-collection-d7-paragraphs-node-d8

Example of Migrating data from a CSV source:

```
id: d7_field_collection_list_items
migration_group: migrate_drupal_7
label: 'Import field collection to paragraph'
source:
  plugin: csv
  path: 'csv file path'
process:
  type:
    plugin: default_value
    default_value: 'paragraph type name'
  // Do field mapping here.
destination:
  plugin: 'entity_reference_revisions:paragraph'
  default_bundle: 'paragraph type name'
migration_dependencies: {  }

```

---
Tags: 8, migrations
---


# Question
Title: Drupal theme error. functions from add on libraries are not included when running my custom script
I'm trying to load a javascript function in my custom script with jquery and materialize. When the script load it says

```
 Uncaught TypeError: $ is not a function and sidenav() is not defined.

```

My theme library is as follows

```
    global-styling:
  version: VERSION
  css:
    base:
      materialize/css/materialize.min.css: {}
      css/style.css: {}
  js:
    materialize/js/materialize.min.js: { minified:true}
    js/layout.js: {}
  dependencies:
    - core/jquery

```

My layout.js is simple

```
  $('.sidenav').sidenav();

```

If I look at dev tools it shows materialize and jquery loading before my script. I followed the answer to get jquery working but sidenav() comes back undefined. sidenav() is a materialize function and material.js is loading before this script.

How do I properly attach a 3rd party js framework and call a function from it?

# Answer
$ is a shortcode for jQuery, does your layout.js contain just

```
 $('.sidenav').sidenav();

```

Maybe try

```
(function ($, Drupal) {
    $('.sidenav').sidenav();
 })(jQuery, Drupal);

```

You can read more here: https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview
> 1 votes

---
Tags: theming, javascript
---


# Question
Title: WSOD "The provided host name is not valid for this server"
My Drupal 8 site only works with www. but without it I'm getting a WSOD with the "The provided host name is not valid for this server" error.

I've tried to implement the suggestions from this thread: What does "The provided host name is not valid for this server" mean?

Specifically I tried:

```
$settings['trusted_host_patterns'] = array(
  '^www\.example\.com$',
  '^example\.com$'
);

$settings['trusted_host_patterns'] = [];

$settings['trusted_host_patterns'] = [ '.*' ];

```

Still, site will only work with www

# Answer
You need to add your domains into the array as per your first example. I.e.

```
    $settings['trusted_host_patterns'] = array(
  '^www\.yourdomain\.co\.uk$',
  '^yourdomain\.co\.uk$',
);

```

Then clear the caches and the message should go away. It may be that you're missing the comma after your second entry.
> 2 votes

---
Tags: 8, wsod
---


title: Changing a node's content type

text:
# Question
Title: Changing a node's content type
In Drupal 7, I can easily switch a node's content type by using Node convert. Node Convert, however, has not been ported to Drupal 8, nor does there appear to be much enthusiasm for the port.

If I have two content types with identical fields, how can I convert a node from a content type to another one, in Drupal 8? What is the code I should use for Drupal 8, which is equivalent to the following Drupal 7 code used by the *Node convert* module? (See `node_convert_node_convert()` in node\_convert.util.inc.)

```
  // $nid, $destination_node_type, $source_fields, $destination_fields,
  // $no_fields_flag, and $hook_options are the parameters passed to the function.

  $node = node_load($nid);
  if ($node == FALSE) {
    return FALSE;
  }

  // Change the node type in the DB
  db_update('node')->fields(array('type' => $destination_node_type))->condition('nid', $nid)->execute();

  // If there are fields that can be converted
  if ($no_fields_flag == FALSE) {

    // Conversion process for each field
    $re_save_body_field = FALSE;

    // Use node revisions to extract all field revision in node_convert_field_convert
    $node_revisions = node_revision_list($node);

    foreach ($source_fields as $key => $field) {
      $replaced_body = node_convert_field_convert($node, $field, $destination_fields[$key], $destination_node_type, $node_revisions);
      if ($replaced_body == REPLACE_BODY) {
        $re_save_body_field = TRUE;
      }
    }
    // If something was appended to the body, or replaced the body, we update body field.
    if ($re_save_body_field == TRUE) {
      $field_body = field_info_fields();
      $field_body = $field_body['body'];
      $field_ids = array($field_body['id'] => $field_body['id']);
      module_invoke($field_body['storage']['module'], 'field_storage_write', 'node', $node, FIELD_STORAGE_UPDATE, $field_ids);
    }
  }

  // Omissis.

  // Clear the node cache, so we have the latest information when saving the
  // node.
  $controller = entity_get_controller('node');
  /* @var $controller DrupalEntityControllerInterface */
  $controller->resetCache(array($node->nid));
  cache_clear_all('field:node:' . $node->nid, 'cache_field');

```

`node_convert_field_convert()` contains the following code.

```
  // &$node, $source_field, $destination_field, $destination_node_type,
  // and $node_revisions are the parameters passed to node_convert_field_convert().

  $field_info_source = field_info_fields(); // Get source field information
  $field_info_source = $field_info_source[$source_field];
  $db_info_source = $field_info_source['storage']; // Get DB specific source field information

  if ($destination_field == 'discard') {
    // Delete node info in the separate field table
    node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
    return NULL;
  }

  $field_info_destination = array();
  $db_info_destination = array();
  if (!in_array($destination_field, array('discard', APPEND_TO_BODY, REPLACE_BODY))) {
    $field_info_destination = field_info_fields($destination_field); // Get destination field information
    $field_info_destination = $field_info_destination[$destination_field]; // Get destination field information
    $db_info_destination = $field_info_destination['storage']; // Get DB specific destination field information
  }

  // We save each field value from the DB for transfer. (this only applies to the current revision of the field)
  $source_values = field_get_items('node', $node, $source_field);

  if (count($node_revisions) > 1 && !in_array($destination_field, array(APPEND_TO_BODY, REPLACE_BODY))) {
    // Get all field revisions for current node
    $field_revision_values = array();
    $field_revision_source_table = current(array_keys($db_info_source['details']['sql']['FIELD_LOAD_REVISION']));
    $field_revision_destination_table = current(array_keys($db_info_destination['details']['sql']['FIELD_LOAD_REVISION']));

    $source_columns = array('entity_type', 'entity_id', 'revision_id', 'bundle', 'delta', 'language');
    foreach ($field_info_source['columns'] as $column => $attributes) {
      $source_columns[] = _field_sql_storage_columnname($source_field, $column);
    }

    $revision_query = db_select($field_revision_source_table, 'r', array('fetch' => PDO::FETCH_ASSOC))
      ->condition('entity_type', 'node')
      ->condition('bundle', $node->type)
      ->condition('entity_id', $node->nid)
      ->condition('revision_id', $node->vid, '<>')
      ->fields('r', $source_columns)->execute();

    // Change the bundle to the destination type of the node
    foreach ($revision_query as $row) {
      $row['bundle'] = $destination_node_type;
      $field_revision_values[] = $row;
    }

    // Remove all field revisions for current field in DB
    node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);

    // Reinsert the field revisions in the destination field revision table
    $query = db_insert($field_revision_destination_table);
    $columns = array('entity_type', 'entity_id', 'revision_id', 'bundle', 'delta', 'language');
    foreach ($field_info_destination['columns'] as $column => $attributes) {
      $columns[] = _field_sql_storage_columnname($destination_field, $column);
    }
    $query->fields($columns);
    foreach ($field_revision_values as $row) {
      $query->values(array_values($row));
    }
    $query->execute();

  }
  else {
    // After getting the source field values, we delete the values stored in the DB (this deletes values for all field revisions)
    node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
  }

  // The source field value should be appended to the body or replaced.
  if ($destination_field == APPEND_TO_BODY || $destination_field == REPLACE_BODY) {
    static $node_body = '';
    //static $node_teaser = '';

    // We try to get the node body from a static variable, which means we did some body manipulations, otherwise load it.
    if (empty($node_body)) {
      $node_body_field = field_get_items('node', $node, 'body');
      $node_body = $node_body_field[0]['value'];
      //$node_teaser = $node_body_field[0]['summary'];
    }

    // Double check we have values in the field.
    if (is_array($source_values)) {
      // Get the field value.
      $field_value = node_convert_format_field_value($node, $field_info_source, TRUE);

      if ($destination_field == APPEND_TO_BODY) {
        $node_body = $node_body . "\n" . $field_value;
        //$node_teaser = $node_teaser . "\n" . $field_value['value'];
      }
      elseif ($destination_field == REPLACE_BODY) {
        $node_body = $field_value;
        //$node_teaser = $field_value['value'];
      }
      $lang_code = field_language('node', $node, $source_field);
      $node->body[$lang_code][0]['value'] = $node_body;
      //$node->body[$lang_code][0]['summary'] = $node_teaser;
    }

    return REPLACE_BODY;
  }

  // We put each field value back into the DB
  // To do it we first get the id of the field, then we find its language code from the source value
  // We add $source_values into the node object, and invoke field_storage write
  $field_ids = array($field_info_destination['id'] => $field_info_destination['id']);
  $lang_code = field_language('node', $node, $source_field);

  // Make sure that we actually have values in the source field
  if ($source_values !== FALSE) {
    $node->{$destination_field}[$lang_code] = $source_values;
  }
  else {
    $node->{$destination_field} = array();
  }

  // Give possibility to fields to pre-process their data
  // (e.g., Link module transforms attribute array into a serialized array before insertion)
  field_attach_presave('node', $node);
  // For some reason link_field_presave doesn't exist anymore, so we have to call it the processing function used inside manually.
  if ($field_info_destination['type'] == 'link_field') {
    $instances = field_info_instances('node', $destination_node_type);
    link_field_update('node', $node, $field_info_destination, $instances[$destination_field], $lang_code, $node->{$destination_field}[$lang_code]);
  }

```

# Answer
> 2 votes
Some time has passed, and the good news is there is now the convert\_bundles module for d8.

It's alpha, but I was able to use it to convert entities on a dev site.

# Answer
> 1 votes
Joachim Noreiko just posted a blog post about changing the type of a node. You will need to update the following tables:

* the entity base table
* the entity data table
* the entity revision data table
* each field data table
* each field data revision table

The post comes with complete instructions and code snippets, just follow them step by step.

# Answer
> 1 votes
Here is a solution for converting article nodes into a blog type. I tried Convert Bundles suggested in another answer, but wasn't able to filter which nodes to convert. With this, you can add additional conditions to the query, such like a taxonomy term value.

```
$query = \Drupal::entityQuery('node')
  ->condition('type', 'article')
$results = $query->execute();

foreach ($results as $nid) {
  $node = \Drupal\node\Entity\Node::load($nid);
  $node->set('type', 'blog');
  $node->save();
}

```

---
Tags: nodes, 8, entities
---


# Question
Title: Why is the jquery_update module not supporting the latest jQuery version?
The recommended jquery\_update module only supports 1.10. Why recent jQuery security version 3.4.1 not updated? https://jquery.com/download/

So is it recommended to make my Drupal site to update with latest jQuery version for security reasons?

When I try to make the module to support latest jquery version, I am facing issues with other jQuery UI files. What are the additional UI files need to be addressed to work with latest jQuery version?

Thanks,

# Answer
You'll want to use the latest dev version of jQuery update, `7.x-3.x-dev` to get the latest version of jQuery, or at least jQuery 3.1. See this drupal issue for more insight.

You can see in the `7.x-3.x` dev branch, it has jQuery 3.1.

Note, there is also a patch for jQuery 3.2, 3.3, and 3.4 against the `7.x-2.7` branch.
> 2 votes

---
Tags: 7, javascript
---


title: Drush terminated abnormally

text:
# Question
Title: Drush terminated abnormally
Drush version 9.7.0 Drush Launch version 0.6.0 Drupal ver 8.7.3 Open social dist 5.5.

The error I get at the command line when running `drush topic` or `drush cr` or any Drush command:

> \[warning\] Drush command terminated abnormally. Check for an exit() in your Drupal site.

I have tried reinstalling Drush, removing and reinstalling, clearing cache via the GUI, but nothing seems to help.

I don't know where to check for an "exit() in your Drupal site".

# Answer
> 0 votes
Use an IDE to open your site and search into all your files.

When you find one **exit()**, comment it and try to use Drush again. Do it until you find the exit() that block Drush.

---
Tags: drush
---


# Question
Title: Passing an array stdClass Object from custom module to template
I’ve created some D8 custom modules which call rest API and and it’s working fine when I get simple array in my `$response`.

In my controller, this is working :

```
return [
            '#theme' => 'webservices_client',
            '#id' => $infos_clients->body->id,
            '#nom' => $infos_clients->body->nom,
 ];

```

But when I receive that kind of array `$response->body` :

```
Array
(
    [0] => stdClass Object
        (
            [numero] => 625
            [dateDebut] => 2018-09-27T09:21:54.5746973
        )

    [1] => stdClass Object
        (
            [numero] => 468
            [dateDebut] => 2018-05-17T16:50:33.6357383
        )

)

```

I don’t how to send my array from the controller to the twig template and assign variable in `my-module.module`

Could you explain how to this ?

I've tried this kind of thing :

in controller :

```
return [
            '#theme' => 'webservices_informations',
            '#myvariable' => $response,
       ];

```

in my-module.module :

```
function webservices_informations_theme(array $existing, $type, $theme, $path) {
    return array(
        'webservices_informations' => array(
            'variables' => array(
                'myvariable' => NULL,
            ),
        ),
    );
}

```

In twig template :

```
{% for key, value in myvariable %}
            Key : {{ key }}<br>
            Name : {{ value.id }}<br>
{% endfor %

```

# Answer
I don't know why it was not working because after I've done a simple

```
<pre>
    {{ dump(myvariable) }}
</pre>

```

In order to check if the array was passed to the twig template, everything is working.

So the solution is in `my-template.html.twig`

```
{% for key, value in myvariable %}
    Key : {{ key }}<br>
    Date: {{ value.dateDebut }}<br>
    Societe : {{ value.societe }}<br>
{% endfor %}

```
> 1 votes

---
Tags: 8, theming
---


# Question
Title: JS function undefined although JS framework attached
I attached materialize to my library theme.

```
global-styling:
  version: VERSION
  css:
    base:
      materialize/css/materialize.min.css: {}
      css/style.css: {}
  js:
    materialize/js/materialize.min.js: { minified:true}
    js/layout.js: {}
  dependencies:
    - core/drupal
    - core/jquery

```

But in layout.js I run .sidenav() and it says it's undefined.

```
  (function ($, Drupal) {
  Drupal.behaviors.myModuleBehavior = {
    attach: function (context, settings) {
      $('.sidenav', context).once('.sidenav').each(function () {
        M.AutoInit();
        $('.sidenav').sidenav();
      });
    }
  };
})(jQuery, Drupal);

```

I can't find how to properly call 3rd party js functions in my custom scripts. I'm not sure why if

```
 $('.sidenav', context).once('.sidenav').each...

```

is correct because I don't need to call a function for each. The example Drupal gives is confusing.

# Answer
> 0 votes
So Leymannx was right about the dist folder version of Google Materialize. I had downloaded the framework directly from their get started page. I thought it was the same files, everything else worked, even when I just created a simple index.html on my local server, the simple sidenav() worked. For the heck of it and being completely out of ideas, I did a node install of Google's materialize framework and saw the dist folders. So I switched to loading those dist files and it worked this time in Drupal. ¯\_(ツ)\_/¯

Thanks for everybody's help.

---
Tags: 8, javascript
---


title: Capture amount on order state change

text:
# Question
Title: Capture amount on order state change
I would like to know if it is possible to capture payments by subscribing to order transition events.

Example:

1. Transaction mode: Authorize only
2. On order placed - Capture some amount (application fee)
3. On order validated - Capture outstanding amount

Thank you!

# Answer
> 0 votes
I've managed to create new payment and modify authorisation amount. Here is what I have so far:

```
public static function getSubscribedEvents() {
  $events = ['commerce_order.place.post_transition' => ['captureFee', -50]];
  return $events;
}

public function captureFee(WorkflowTransitionEvent $event) {
  /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
  $order = $event->getEntity();

  if ($order->bundle() != 'training') {
    return;
  }

  /** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
  $payment_gateway = $order->payment_gateway->entity;
  $payment_gateway_plugin = $payment_gateway->getPlugin();

  $payment_storage = $this->entityTypeManager->getStorage('commerce_payment');

  // Load first order payment
  $payments = $payment_storage->loadMultipleByOrder($order);
  $first_payment = current($payments);

  // Only proceed if payment is not captured
  if ($first_payment->isCompleted()) {
    return;
  }

  // Default fee amount
  $fee_amount = new \Drupal\commerce_price\Price('50.00', 'USD');

  // Get fee amount from product variation
  if (isset($order->getItems()[0]->getPurchasedEntity()->field_app_fee) && !$order->getItems()[0]->getPurchasedEntity()->field_app_fee->isEmpty()) {
    $fee_amount = $order->getItems()[0]->getPurchasedEntity()->field_app_fee->first()->toPrice();
  }

  // Create fee payment
  /** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
  $payment = $payment_storage->create([
    'state' => 'new',
    'amount' => $fee_amount,
    'payment_gateway' => $payment_gateway->id(),
    'order_id' => $order->id(),
  ]);

  // Capture fee payment
  if ($payment_gateway_plugin instanceof OnsitePaymentGatewayInterface) {
    $payment->payment_method = $order->payment_method->entity;
    $payment_gateway_plugin->createPayment($payment, 'capture');
  }
  elseif ($payment_gateway_plugin instanceof ManualPaymentGatewayInterface) {
    $payment_gateway_plugin->createPayment($payment, TRUE);
  }
  else {
    return;
  }

  // Subtract captured amount from authorized amount and save first payment
  $first_payment_amount = $first_payment->getAmount();
  $first_payment->setAmount($first_payment_amount->subtract($fee_amount));
  $first_payment->save();

}

```

I have "training" bundle that is limited to 1 item per cart. This is the result with variation price set to $2,100.00 and $45.00 fee.

---
Tags: 8, commerce
---


title: Sortable table: secondary sort

text:
# Question
Title: Sortable table: secondary sort
I have a view (Drupal 6 / Views 2, but I think this may apply to other versions as well) displayed as a sortable table. I can add fixed sort criteria as you can with all views, but once the table is sorted by the visitor on a certain table, those sort criteria are ignored.

In the style options there is a box called "Override normal sorting if click sorting is used", which doesn't make sense to me. It seems to effectively disable click sorting, leaving the end user with a clickable but not working table headers.

Is there a way to keep the fixed sort criteria and use them as secondary criteria?

# Answer
The initial sorting that you have specified in views is only used on the first page view. When you click on the header to change the sort the query is altered to use the drupal table sort routines instead. Unfortunately there is no support in the built in table sort code to allow multiple column sort, nor the ability to define a default of descending instead of ascending column. An alternative if your table is displaying all results is to add some Javascript that performs table sorts on the HTML and not provide sorting on the columns in Views. A google.com search for "javascript table sort" will give many results, this one looks to be quite robust: http://tablesorter.com/docs/
> 3 votes

# Answer
As others said before

> there is no support in the built in table sort code to allow multiple column sort, nor the ability to define a default of descending instead of ascending column

But you should have a look at the following approach with Tablesorter.

For D7:

1.Download and enable Tablesorter Module

2.Download and extract Tablesorter jQuery Plugin into `sites/all/libraries/tablesorter`

3.Add a CSS class `tablesorter` and an unique id to your Views tables in template.php

```
/**
 * Preprocess variables for Views tables.
 */
function YOUR_THEME_preprocess_views_view_table(&$vars) {
  $view = $vars['view'];
  $vars['classes_array'][] = 'tablesorter';
  $vars['attributes_array']['id'] = $view->name . '-' . $view->current_display;
}

```

4.Clear cache a few times. Now Tablesorter should already start to work. You'll see it when the styling changed.

5.For secondary sort you need to add a small custom JavaScript. In template.php:

```
/**
 * Override or insert variables for the page templates.
 */
function YOUR_THEME_preprocess_page(&$vars) {
    // you might define some conditions around here
    drupal_add_js(drupal_get_path('theme', 'YOUR_THEME') . '/scripts/custom_tablesort.js');
}

```

6.In that script write the following to tell Tablesorter to sort the first six collumns of certain tables in ascending alphabetical order. To tell Tablesorter to sort only the second and third column in ascending order write `sortList: [[1,0], [2,0]]` instead.

```
(function ($) {
  Drupal.behaviors.tableSorting = {
    attach: function (context, settings) {

      $("#your_view_name-display_name").tablesorter({
        sortList: [[0,0],[1,0],[2,0],[3,0],[4,0],[5,0]]
      });

    }
  }
}) (jQuery);

```

If you want to let Tablesorter secondary sort all your tables you don't need to define a CSS id when preprocessing and simply tell Tablesorter: `$("table").tablesorter({ sortList: [[0,0],[1,0],[2,0],[3,0],[4,0],[5,0]] });`

After a little testing I'ld say you leave any custom Tablesorter option out (finish with step 4) and simply explain your users that while holding down `shift` when clicking multiple headers, secondary sorting works on every desired column they want.
> 3 votes

# Answer
Remove the "Default Sort" from the Table settings and use the "Sort Criteria" for the first and second order
> 2 votes

# Answer
From the question what I get is that you want a table sorter function in Views; if it is so, you can follow the following steps:

1. Edit the view you want to add the column sorting to.
2. Under "Basic Settings", look for "Style: Table" and click on the picture of a cog next to it.
3. Scroll down to see the table settings.
4. There is a list of the fields, and a tickbox for each labelled "sortable"; tick the boxes for any columns you want users to be able to change the sort order on.
> 1 votes

# Answer
(D8)

After lots of debugging I ended up with similar D7 approach D7 hook\_views\_query\_alter

It boils down to using triggering the table style plugins **clickSort** method.

* Create a sub folder named **multisort** in modules.
* Safe the code below as **multisort.module** into folder created above.

```

<?php

use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_query_alter().
 */
function multisort_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {

  $views_to_alter = [
    // view name
    'sort_test' => [
      [
        'table' => 'node__field_col_a',
        'field' => 'field_col_a',
        'column' => 'field_col_a_value',
        'order' => 'desc',
      ],
    ]
  ];

  if (isset($views_to_alter[$view->id()])) {
    //dpm($query->orderby, 'by config or url');

    $fields_used = [];
    foreach($query->orderby as $field) {
      $fields_used[$field['field']] = 1;
    }

    $fields = $views_to_alter[$view->id()];

    foreach($fields as $field) {
      // Skip fields already clicked
      if (isset($fields_used[$field])) {
        continue;
      }

      $alias = $field['table'] . '.' . $field['column'];
      if (isset($fields_used[$alias])) {
        continue;
      }

      // @see \Drupal\views\Plugin\views\style\Table::buildSortPost
      $view->field[$field['field']]->clickSort($field['order']);
    }

    //dpm($query->orderby, 'altered');

  }
}

```
* Save text below into **multisort.info.yml**

```

name: Multisort
type: module
description: Sort on more then one field
core: 8.x
package: Views

```
> 1 votes

# Answer
This is my solution in D7/Views 3. It adds a last order\_by clause to the query if its not already present. I believe you could look at the $view parameter and add the order by columns from there if you dont want to do it statically like I did.

```
function MODULENAME_views_query_alter(&$view, &$query) {
  if ($view->name == 'the_name_of_the_view_to_alter') {
    //First check that we don't already sort by the "the_field_alias" column
    if(array_search('the_field_alias', array_column($query->orderby, 'field')) === FALSE) {
      //Add the "the_field_alias" column last in the orderby array
      $query->orderby[] = [
        'field' => 'the_field_alias',
        'direction' => 'ASC',
      ];
    }
  }
}

```
> 1 votes

# Answer
Edit the views and go to Table settings there you can see sorting checkbox... you can checked and apply..
> 0 votes

---
Tags: views
---


# Question
Title: Webform dynamic select options based upon another element's state
Say there are two select elements with dynamic options (via an options alter hook, sourced from an external resource): A and B. There is also a datasource that provides a relationship that determines the options in B that should shown when a particular selection in A is chosen.

The source data for each element in addition to the relationship data source is not able to be predicted or controlled by Drupal.

For example:

A Options at a particular instant

```
| name | code |
| Group 1 | 1 |
| Group 2 | 2 |
| Group 3 | 3 |

```

B options at a particular instant

```
| name | code |
| Thing 1 |  1 |
| Thing 2 | 2 |
| Thing 3 | 3 |

```

The relationships at any given time.

```
| group | thing |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 3 |

```

So if group 1 is selected for A, then things 1, 2, and 3 should be options for B

If group 2 is selected for A, then things 1 and 2 should be options for B

If group 3 is selected, then only thing 3 should be an option for 3.

We are currently implementing this requirement through the core FAPI and ajax callbacks, but would like to covert it to use Webforms.

What would be the recommended approach to take in order to solve this with Webforms? Please bear in mind that modifying the source data is not an option, as it is not able to be predicted nor controlled by our unit and adjustments must be reflected in realtime.

# Answer
No one has contributed back a solution for Drupal 8. I think the best approach is going to be to organize cascading select menus using a CSV and implementing something like Cognito form's cascading dropdowns menus.

Another supported approach is the Webform Simple Hierarchical Select module but it requires a taxonomy.
> 2 votes

---
Tags: 8, webforms
---


title: Programmatically create a term?

text:
# Question
Title: Programmatically create a term?
I'm attempting to add a lot of terms (~200) to a vocabulary, but I can't find any import modules that are updated for Drupal 8, and it seems the functions for doing this in Drupal 7 don't exist in Drupal 8. So, can anyone point me in the right direction for doing this?

I attempted to do it with `entity_create`, as suggested in the comments, with this code:

```
$term_create = entity_create('taxonomy_term', array('name' => 'test', 'vocabulary_name' => 'client'));

```

but I got this error:

```
Drupal\Core\Entity\EntityStorageException: Missing bundle for entity type taxonomy_term in Drupal\Core\Entity\FieldableEntityStorageControllerBase->create() (line 65 of core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php).

```

Any ideas?

# Answer
You know that you want something from taxonomy module so first you need to look in `Drupal\taxonomy\Entity` -- or the corresponding directory -- you will find the `Term` class there. Now look at the annotation, it says `@ContentEntityType` and in there:

```
*   entity_keys = {
*     "id" = "tid",
*     "bundle" = "vid",
*     "label" = "name",
*     "uuid" = "uuid"
*   },

```

So, what you want is

```
$term = Term::create([
  'name' => 'test',
  'vid' => 'client',
])->save();

```

because the `label` entity key is `name` and the `bundle` entity key is `vid`. I added a `->save()` call as well as I presume you wanted to save it too.
> 55 votes

# Answer
At this time you should add term in little bit another way (in compare with this answer) First of all in your file begin you should write

> use Drupal\taxonomy\Entity\Term;

Because Term class listed in Drupal\taxonomy\Entity. And you don't need to pass taxonomy\_term parametr to

> Term::create

because only one parametr is needed (array with values) (below listed code for this method in taxonomy module)

```
public function create(array $values = array()) {
  // Save new terms with no parents by default.
  if (empty($values['parent'])) {
    $values['parent'] = array(0);
  }
  $entity = parent::create($values);
  return $entity;
}

```

So the final example is

```
use Drupal\taxonomy\Entity\Term;
$categories_vocabulary = 'blog_categories'; // Vocabulary machine name
$categories = ['test 1', 'test 2', 'test 3', 'test 4']; // List of test terms
foreach ($categories as $category) {
  $term = Term::create(array(
    'parent' => array(),
    'name' => $category,
    'vid' => $categories_vocabulary,
  ))->save();
}

```
> 15 votes

# Answer
With `entityTypeManager()`:

```
$term = [
  'name'     => $name,
  'vid'      => $vocabulary,
  'langcode' => $language,
];

$term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->create($term);

```
> 9 votes

# Answer
```
Term::create([
 'name' => 'Lama',
 'vid' => $vocabulary_id,
]);

```

The other answers use `entity_create()`, which works, but is not quite as nice as the OOP approach.
> 8 votes

# Answer
Before creating a term, it's better to check if it's exist, here is the code:

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

if ($terms = taxonomy_term_load_multiple_by_name($term_value, 'vocabulary')) {
  // Only use the first term returned; there should only be one anyways if we do this right.
  $term = reset($terms);
} else {
  $term = Term::create([
    'name' => $term_value,
    'vid' => 'vocabulary',
  ]);
  $term->save();
}
$tid = $term->id();

```

Source: https://www.btmash.com/article/2016-04-26/saving-and-retrieving-taxonomy-terms-programmatically-drupal-8
> 7 votes

# Answer
You may want to look at how devel/devel\_generate does this.

From devel\_generate :

```
$values['name'] = devel_generate_word(mt_rand(2, $maxlength));
$values['description'] = "description of " . $values['name'];
$values['format'] = filter_fallback_format();
$values['weight'] = mt_rand(0, 10);
$values['langcode'] = LANGUAGE_NOT_SPECIFIED;
$term = entity_create('taxonomy_term', $values);

```
> 2 votes

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


# Question
Title: Skip words/vary word order in search for autocomplete suggestions
I'm using an Entity Reference field which searches taxonomy terms of type Person to suggest options for autocompletion.

Let's say, i have the following terms (Persons): \- Jason Jay Smith \- John Jacob Andrews... etc.

When I input "Jason Ja..." in the field, the autocompletion works fine and suggests me the Smith guy. But if i input "Jason Smi...", the term won't be found because the word Jay is skipped. How can i fix this?

Or generally, how can i implement a better autocomplete search? My terms are composed of a number of words and searching by just one word or a fixed word order is definitely not enough

# Answer
> 0 votes
Doing this would require a different selection handler. Look at class Drupal\Core\Entity\Plugin\EntityReferenceSelection to see how the default selection handler works. In particular you need to create a different buildEntityQuery method. I don't know of any module that provides a handler to do this, and I'm not sure how I would go about accomplishing it myself. Sorry I can't give a more satisfactory answer.

---
Tags: search
---


# Question
Title: How to change order currency in cart/checkout page?
I want to change the price of the order in the cart/checkout page. Let's say I have a product ABC with **$100(USD)** and I added that in cart. But after adding I want to change the currency to **EUR** and proceed with the checkout process. I tried to change the currency and amount in order like below:

```
$order = commerce_order_load(1234);
$amount = 100;
$order->commerce_order_total['und'][0]['amount'] = round($amount,2);
$order->commerce_order_total['und'][0]['currency_code'] = 'EUR';
$order->commerce_order_total['und'][0]['data']['components'][0]['price']['amount'] = round($amount,2);
$order->commerce_order_total['und'][0]['data']['components'][0]['price']['currency_code'] = 'EUR';
commerce_order_save($order);

```

But when I refresh the checkout or visit cart page, it's still in USD. So I need help in changing the currency of order based on user input in cart/checkout page or based on the field (currency) which admin has created for every product.

# Answer
You cannot directly manipulate the order total like this, as it gets recalculated based on its line items' prices each cart refresh. (That happens on every pageload in checkout and however you've configured it for other routes.)

You should look into the Commerce Multicurrency module instead or else configure your pricing rules / otherwise hook into product sell price calculation to change the currency on the order items (and shipping if present). If those are all the same target currency, the order total will use it, too.
> 1 votes

---
Tags: 7, commerce
---