# Question
Title: Remove dots ( ... ) from default search results descriptions ( snippet )
I want to remove dots from search results items descriptions to search result page ( Default Search ), i have used Drupal default search for the search result page so how to remove the dots from the search descriptions.

I tried with search and replace function using theme preprocess search result function but no luck.

> theme\_preprocess\_search\_result()

```
function theme_preprocess_search_result(&$variables) {

  $variables['search_excerpt'] = str_replace("...", "", $variables['snippet']['#markup']);

}

```

But it's not work as expected,if have any solution please put into comment.

Thanks in advance.

# Answer
> 1 votes
You use incorrect variable name.

Take a look for the search-result.html.twig template. We have a snippet template variable.

Your code should looks like:

```
function theme_preprocess_search_result(&$variables) {
  $variables['snippet']['#markup'] = str_replace('…', '', $variables['snippet']['#markup']);
}

```

Pay attention to …, this is a special symbol, not ... (three dots).

---
Tags: theming, search
---


# Question
Title: How do I hide the download button on the audio player?
I want to hide the "download" button on the audio player provided by the Media module in Drupal 8. How can I do that?

# Answer
1. Create a subtheme if you haven't already.
2. Find the file `core/modules/file/templates/file-audio.html.twig` and copy it to your subtheme's `templates` directory.
3. Edit the following line in the file.

Original line:

`<audio {{ attributes }}>`

Change it to this:

`<audio {{ attributes }} controlsList="nodownload">`
> 5 votes

# Answer
For files uploaded into the private:// directory, you can restrict access via permissions. Also, take a look for the Protected File (from download) module.
> 0 votes

---
Tags: media
---


# Question
Title: How to get different image styles in the same view?
I'am a newbie, and I want to make a simple view with an image field (in article nodes), that looks like this layout :

And for this, I don't want to use CSS rules to resize the view rows images, for two reasons :

1. I am using bootstrap grid, and I don't want to deal with relative heights, since images in articles have various sizes, so I prefer that this view do the image resizing for me.
2. I want to learn this view trick without relaying on CSS tricks.

I tried different tricks, like:

1. importing the image filed twice, making each one in different image style, rewriting them (displaying them conditionaly) based on "view result counter", but putting a condion like {% if counter == 1 %} or like {% if counter == '1' %} don't work (i think it still an open issue).
2. I tried also making some theme preprocess or theme hook altering to force a different image style for the first iteration.

I'm so frustrated because of such an easy task that looks so hard to me.

Any help?

# Answer
> 0 votes
The Twig Tweak can help you.

Firstly, you should write a specific condition for check if the image is first.

```
{% if loop.index == 1 %}

```

Inside condition you need to fetch an uri to the image and apply the Image Style Filter.

---
Tags: views, theming
---


# Question
Title: Separate exposed sort form from exposed filter block
Is is possible in Drupal 8 Splitting exposed filters and exposed sort & pagination i.e. placing sort & pagination inside a separate block and filters in another block?

Right now there is no out of the box solution to this. In my opinion this would greatly improve user experience.

# Answer
> 0 votes
I didn't see solution for such issues. But I solved these issue with custom form elements and using the hook\_views\_query\_alter. In the hook\_views\_query\_alter you can alter orderBy property.

---
Tags: views
---


# Question
Title: Custom home page not recognized by system
I have set up a Drupal 8 site with a custom home page using page--front.html.twig. The content displays at domain.com/front. When I go into Administration to change to the new home page, it says that the path is invalid. I've also tried leaving the field blank.

I also noticed that when I'm on /front, the browser tab displays "Page not found".

I've cleared the cache repeatedly (and every time it sends me to /user/1).

What am I missing here?

# Answer
> 2 votes
There are two separate issues at play here, which is where you are getting confused.

1) `page--front.html.twig` \- this is a template suggestion for the `page` theme hook. This can be seen by the double-hyphens that follow `page`. The `page` theme hook is used to wrap the content of every page on the site, using the `page.html.twig` template. Drupal's theme layer allows for creating suggestions for templates that take precedence over the base template. In this case, when on the front page, the site looks for `page--front.html.twig`, and if it finds this file, it uses it. You have created this file. However, you'll notice I said this template wraps the current page content. That leads to:

2) Page content. 'Pages' on Drupal show content if a page has been assigned to the given path. However, if a user goes to a path that doesn't exist, they get the 'page not found' page. This page is wrapped by `page.html.twig`, just like any content page.

When you go to /front, you see page not found, because you have not created a page at that path yet. You've only created a template for the front page, whatever that may be (even if that ends up being page not found).

You can test this by creating a new node, and setting the path to be `/front` (note - you'll need appropriate permissions for this). Then set the site front page to `/front`, and your template will be picked up.

# Answer
> 1 votes
If you need a clear homepage, then you can use the Empty Page module. Just create a page with the module, add the URL to page in the Site Information settings and define a template in the theme.

---
Tags: theming
---


# Question
Title: How do I define the default cache and cache settings programmically in a Kernel test?
A user provided a set of site caching configuration settings that cause some errors. For example:

```
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.memcache';
$settings['cache']['bins']['discovery'] = 'cache.backend.memcache';

```

On top of that, the memcache module states that users must include the following in their site configuration:

```
$settings['cache']['default'] = 'cache.backend.memcache';

```

I would like to extend some core Kernel tests to run with the memcache module configured the way the user described. I can easily enable the module by adding it to the $modules array in the MyTest class. What else do I need to add to ensure the “site configuration settings” are the way the user recommends. I was hoping I could add something to the MyTest::setUp() function to change the settings, or better yet, have a dataProvider to supply a variety of settings to the test function to test against. I thought there would be something obvious in the system.performance configuration item, but it looks like cache.default is a service. Do I need to redefine this service programmically? How do I do that? The memcache module does not automatically override the cache.default service in its services.yml file.

# Answer
Take a look the Memcache module. The module has tests, and seems you need write

```
  protected function setUp() {
    $this->config = [
      'memcache' => [
        'servers' => ['127.0.0.2:12345' => 'default'],
        'bin' => ['default' => 'default'],
      ],
      'hash_salt' => $this->randomMachineName(),
    ];
    $settings = new Settings($this->config);
    $this->settings = new MemcacheSettings($settings);
  }

```
> 0 votes

---
Tags: 8, caching, testing
---


# Question
Title: How can I manually change image orientation?
I manage a website with Drupal 7 where users can upload pictures from their mobile or from their desktop. I have configured Image Style with "autorotate" effect and most of the pictures are well displayed after styling.

But some are misoriented and I'd like to be able to manually change the picture orientation (or let the user do it).

Do you know a solution for this ?

# Answer
> 0 votes
1 Read an image in JS from attached file https://developer.mozilla.org/ru/docs/Web/API/URL/createObjectURL

2 Use Lib for reading Exif data from jpg for autorotation as default option https://github.com/exif-js/exif-js

3 Create controls for manual rotate image on canvas as manual tool https://stackoverflow.com/questions/17411991/html5-canvas-rotate-image

4 Send on server additional param with rotation value (for apply rotation to orig image on server side) OR Apply rotation on original size image on JS and send result on server as base64 code. Decode to binary data in server side and put it on disk.

sorry for my english

# Answer
> 0 votes
Try to use the Simple Image Rotate module.

---
Tags: 7, media
---


# Question
Title: Commerce Fee not being added to order total sent to payment processor
I have followed the Commerce Fees module's instructions found at https://www.drupal.org/project/commerce\_fees:

```
DOCUMENTATION

    Go to admin/commerce/config/fees and add a new fee type
    Add a rule at admin/config/workflow/rules
        Event: "Apply a fee to a given order".
        Set the conditions.
        Action: "Apply a fee to an order".
            Entity data selector: "commerce-order".
            Fee: Your fee type.
            Set amounts, currency and taxes as necessary.

Notice: if using fees based on payment type, be sure to move the payment type pane to a screen before the review pane on admin/commerce/config/checkout so that customers can see the fee before accepting.

```

The Fee shows up in the cart contents on checkout but that fee is not added to the order total that is sent to the payment processor not show in the orders view. It's like the fee is not actually added to the total, except for in the cart content view on the checkout page.

Any idea of what I am missing?

# Answer
> 0 votes
Take a look for the issue https://www.drupal.org/project/commerce\_fees/issues/2191191, maybe a patch can help you.

---
Tags: 7, commerce
---


title: Feeds Importer and cron not running

text:
# Question
Title: Feeds Importer and cron not running
I have a Drupal 7 setup with a number of different content types, each with a common set of fields.

Each content type has its own feed, which calls a .csv that's produced from a Google Spreadsheet in tab-delimited format. Cron is set to run feeds importers daily, so when we make updates to the Google Sheet they are automatically reflected in the website

This has been working fine until recently, when we noticed the website was not updating. I checked the feeds log and see this:

I checked and the URL to the .csvs are working-- if I past them into the search bar I can download the file.

When I try to run the feeds manually from the "import" page, the screen just goes blank and nothing happens--no error or message. The same thing happens when I try to run cron.

# Answer
**Where is the site running?** You mention you can download the file in your browser, but I wonder if the network from the site to google is different than the network from your computer to google.

**What's in the error log in general?** When the page goes blank like that it usually means some kind of severe error happened and that should show up in the `Administer -> Reports -> Recent log entries` page for the database log. Or it might show in the php or apache error logs. The location of those logs depends on your system.

**How are you running cron?** Depending on how you run it you might see different errors. If you have drush maybe try running cron via `drush cron`.
> 0 votes

---
Tags: feeds, cron
---


# Question
Title: How to change date format of a custom entity in an update hook?
In would like to display the created date of a custom entity in the "short" format, whereas currently it displays in some default format. This is in a module that is already in, production so I need to do it as an update. I've changed the custom entity code so that it looks like this:

```
    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created on'))
      ->setDescription(t('When the case was created.'))
      ->setDisplayOptions('view', [
        'type' => "datetime_default",
        'label' => 'above',
        'settings' => [
          'date_format' => 'short'
        ]
      ]);

```

Then I ran `drupal update:entities` but it did not change. I was not surprised, because I had read somewhere recently (I can't find it now, sorry) that it had become obsolete & custom entity updates now have to be done in update hooks.

But I am stumped as to how to update it in the update hook. I've tried this

```
function opencase_entities_update_8016() {
  $update_manager = \Drupal::entityDefinitionUpdateManager();
  $definition = $update_manager->getFieldStorageDefinition('created', 'oc_case');
  $update_manager->updateFieldStorageDefinition($definition);
}

```

... which did nothing, and then I looked at this documentation which helped me understand it's not the field storage definition that needs updating but the view config. So I made another update hook following the suggestion there, but simplifying it for my own case. I must have got it wrong because the date is still stubbornly showing in the default format. Can you help?

```
function opencase_entities_update_8017() {
  $update_manager = \Drupal::entityDefinitionUpdateManager();
  $field = $update_manager->getFieldStorageDefinition('created', 'oc_case');
  $properties = array(
    'targetEntityType' => $field->getTargetEntityTypeId(),
    'bundle' => $field->getTargetBundle()
  );
  if ($view_displays = \Drupal::entityTypeManager()->getStorage('entity_view_display')->loadByProperties($properties)) {
    foreach ($view_displays as $view_display) {
      $view_display->setComponent('created', array(
        'type' => 'datetime_default',
        'settings' => ['format_type' => 'short'],
      ) + $component)->save();
    }
  }
}

```

I ran`drush updb` each time and it appeared to complete successfully. No errors in log.

# Answer
When I changed base fields in the past they always updated in the plugin definitions on a cache clear. Also if this involved a schema update, by the way, which then produced a warning on the status page that there is a mismatch with the database, for which you then would need what you've described in the question.

In your case, though, my guess would be that the new settings are not valid for a timestamp field. The field formatter `datetime_default` is probably only working for a `datetime` field.

So try to change the field formatter in the base field definition to:

```
    'type' => 'timestamp',

```
> 1 votes

---
Tags: 8, entities, hooks
---


title: Why isn't the module shown as updated?

text:
# Question
Title: Why isn't the module shown as updated?
I updated a module with Composer and it shows updated in the composer.json file.
However, on *Available updates*, it still shows the old version is installed. I ran update.php and nothing changed.

Drupal core is updated and the module needs to be updated to work with the core version.

Why isn't the module shown as updated? How can I fix this issue?

# Answer
> 1 votes
It's possible that you have multiple instances of the module in different places in your codebase. You may want to try a `find . -type d -name MODULE_NAME` from your project root and see what turns up.

---
Tags: 8, composer
---


title: Get parameter from current url

text:
# Question
Title: Get parameter from current url
How can I get parameter i.e node id from URL in views link path . Eg. - suppose in taxonomy term's view I am giving field name's custom link path is "document/**getParameterFromCurrentURL**/{{tid}}". where suppose getParameterFromCurrentURL is variable or etc so how can i get id from current url in **getParameterFromCurrentURL**.

# Answer
You could try adding a "Global: Null" contextual filter to your Views display, configured to "Provide default value" with type "Content ID from URL".

The Null filter type doesn't change the output of your view. But it would make the Node ID available as a replacement pattern.
> 1 votes

---
Tags: views
---


title: Custom views filter to select roles

text:
# Question
Title: Custom views filter to select roles
I have scoured the internet trying to find information on how to achieve this functionality to no avail. I am hoping I can get an answer here.

I have a content type called 'Server' on my website. One of the fields on 'Server' is an 'Access Role' field, which is an entity reference of user roles.

When a new piece of content is made, the author selects one (or multiple roles) that have access to this piece of content (The author can't be granted the 'manage roles' permission, so they can't use the standard 'permissions' options available when creating content).

I have a view setup (that is a REST EXPORT of type key\_auth. When a user accesses the endpoint using their auth key, the view should return a list of server content that matches ONLY if one of the users roles is in the access roles field for the piece of content. I can't seem to find out how to achieve this using views and filters.

As an example;

Server 1 Access Roles: Developer, Testing

Server 2 Access Roles: Administrator

The user accessing the endpoint does not have the administrator role, but does have the Testing role. When the user accesses the endpoint, only 'Server 1' should return for them, since that's the only server that matches one of their roles. If more servers matched, those servers would be displayed, too.

I have the access roles setup, and the view setup to connect the api key to the correct user, but can't figure out how to set the filter up to match user roles to one of the possible access roles on the server content.

Is there somebody that could offer me some assistance?

# Answer
**EDIT: I think this is actually wrong: Views doesn't evaluate hook\_node\_access() for performance reasons. How to filter a view according to nodes permissions**

It's going to be difficult for Views to model the relationships needed for this correctly, because Roles are configuration entities in Drupal 8 (as opposed to content entities).

You may be going about this the wrong way, though. Views already respects entity access control, preventing entities from showing in results if the current user doesn't have permission to access those entities. You haven't made those access control rules explicit to Drupal yet, which is why they don't get automatically filtered out in Views. But you could implement `hook_node_access()` to formally describe those access permission rules to Drupal.

Here's the API documentation example: https://api.drupal.org/api/drupal/core!modules!node!node.api.php/function/hook\_node\_access/8.8.x

Your implementation would look something like this:

```
<?php

function MYMODULE_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
  if ($op == 'view' && $node->hasField('field_roles')) {
    $node_roles = array_column($node->field_roles->getValue(), 'target_id');
    $user_roles = $account->getRoles();
    if (array_intersect($node_roles, $user_roles)) {
      return \Drupal\Core\Access\AccessResult::allowed();
    }
    else {
      return \Drupal\Core\Access\AccessResult::forbidden();
    }
  }
  return \Drupal\Core\Access\AccessResult::neutral();
}

```
> 0 votes

---
Tags: views, 8
---


# Question
Title: How to load a menu item and its children menu items?
I have the menu item id. I want to display that menu item with its children.

Suppose for example I have menu item `test` and it has two children menu items. So I want to load them and display it as

```
test
  test1
  test2

```

I tried to load the menu item with the following code.

```
$menu_content = current(\Drupal::entityManager()->getStorage('menu_link_content')->loadByProperties(array('id' => 1)));

```

But I am unable to get the children from the variable. Can someone help me here?

# Answer
Try these:

```
// Select the parent menu link with 49 id.
$menu_link_content_id = 49;
// Use the 'menu_link_content' entity storage.
$menu_content_storage = \Drupal::entityTypeManager()->getStorage('menu_link_content');
/** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link_content */
// Fetch an entity with parent menu link.
$menu_link_content = current($menu_content_storage->loadByProperties(['id' => $menu_link_content_id]));
// Build a specific value for a parent property.
$parent_prop = "menu_link_content:{$menu_link_content->uuid()}";
// Load child menu items by 'parent' property.
$menu_link_content_childs = $menu_content_storage->loadByProperties(['parent' => $parent_prop]);

```
> 3 votes

# Answer
Try this:

```
 $menu_tree = \Drupal::menuTree();
            $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name);
            $tree = $menu_tree->load($menu_name, $parameters);
            $manipulators = array(
            array('callable' => 'menu.default_tree_manipulators:checkAccess'),
            array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
            );
            $tree = $menu_tree->transform($tree, $manipulators);
            $list = [];
            $i =0;
         foreach ($tree as $item) {
             $title = $item->link->getTitle();
             $url = $item->link->getUrlObject();
             $menu_url = $url->toString();
             $list[] = array('id'=> $i, 'value'=>$title ,'img_url' =>'' ,'menu_link_url' => $menu_url);
             $i++;
           }

```
> -3 votes

---
Tags: 8, navigation
---


title: "Parse error: unexpected '['"

text:
# Question
Title: "Parse error: unexpected '['"
I have this error when I connect to my site from the Internet. (I don't have it if connected locally via 192.168.0.xx/drupal8.)

> Parse error: syntax error, unexpected '\[' in /volume1/web/drupal8/core/lib/Drupal/Core/Security/RequestSanitizer.php on line 156

The line causing the error is the following one.

```
    if ($key !== '' && ((string) $key)[0] === '#' && !in_array($key, $whitelist, TRUE)) {

```

I have PHP 5.6 and Drupal 8 installed on a Synology server.

What should I do?

# Answer
That is an error that happens on PHP 5.6 and earlier versions. Since Drupal 8.7.x requires PHP 7, you need to change the PHP version the server is using.

You could not see the error locally either because the PHP version is different or because locally you are using a different Drupal 8.x version (for example, Drupal 8.6.0).
> 1 votes

---
Tags: 8
---


title: How can I remove all contextual links?

text:
# Question
Title: How can I remove all contextual links?
When using the layout builder module, the contextual links module is a hard dependency. This works quite well in the context of the layout builder. But I don't want those links anywhere else, because elsewhere they are not helpful at best, and completly mess up my frontend theme at worst.

I've already written a custom theme negotiator to force my admin theme in layout building mode.

But I don't know how to remove all contextual links when I'm in frontend. My current ugly hack is

```
function wt_cms_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
  /**
   * Suppress the contextual edit pen on frontend themes, we only want it
   * for layout builder in admin theme
   */
  if (isset($build['#contextual_links'])) {
    $routeName = \Drupal::routeMatch()->getRouteName();
    if (!in_array($routeName, ['layout_builder.overrides.node.view', 'layout_builder.defaults.node.view'])) {
      unset($build['#contextual_links']);
    }
  }
}

```

and an additional rule in my frontend CSS

```
.contextual-toolbar-tab, [data-contextual-id] {
  display: none !important;
}

```

This does at least hide the contextual edit pen in frontend, but it does not really remove the contextual link menu. (There still is an empty placeholder div).

I've also tried @Shreya Shetty's suggestion

```
function mymodule_contextual_links_alter(array &$links, $group, array $route_parameters) {
  $routeName = \Drupal::routeMatch()->getRouteName();  //incorrect, this always returns "contextual.render"
  if (!in_array($routeName, ['layout_builder.overrides.node.view', 'layout_builder.defaults.node.view'])) {
    $links = [];
  }
}

```

In contextual alter I've got other problems: The current `$routeName` is always `contextual.render` and not the route of the host page, so I've no "entry point" to specifically alter non-layout bulder-pages. It also has the same problem as the hook\_entity\_view\_alter workaround: The menu items are suppressed, but the empty contextual placeholder divs are still rendered.

Can anyone tell me how to reliably and cleanly remove the contextual links? I don't want them anywhere, except in layout building mode.

# Answer
It was a caching issue. This is my final code to cleanly hide all contextual links except in layout building mode:

```
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;

function mymodule_page_attachments(array &$page) {
  $routeName = \Drupal::routeMatch()->getRouteName();
  if (!in_array($routeName, ['layout_builder.overrides.node.view', 'layout_builder.defaults.node.view'])) {
    $page['#attached']['library'] = array_diff($page['#attached']['library'], ['contextual/drupal.contextual-links', 'contextual/drupal.contextual-toolbar']);
  }
}

function mymodule_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
  $routeName = \Drupal::routeMatch()->getRouteName();
  if (!in_array($routeName, ['layout_builder.overrides.node.view', 'layout_builder.defaults.node.view'])) {
    unset($build['#contextual_links']);
  }
}

```

For the caching issue:
The changes above most likely will (after cache clearing) remove all contextual link entries, but leave an empty placeholder like `<div data-contextual-id="..." data-contextual-token="..."></div>` in your rendered HTML. To get rid off those empty divs, go to your browsers `Developer console > Application > Session storage` and clear all keys starting with `Drupal.contextual.` After clearing them, the empty placeholder divs are gone too, no more CSS hacking needed.
> 1 votes

---
Tags: 8, navigation
---


# Question
Title: PHPUnit errors occur when running drupal-check
I am trying to run `drupal-check` on the social\_auth\_dropbox module (`vendor/bin/drupal-check -ad web/modules/contrib/social_auth_dropbox`) and I'm facing this error:

```
Warning: Class 'PHPUnit\Framework\MockObject\Matcher\InvokedRecorder' not found in /Users/Documents/sample/my_site_name_dir/web/core/tests/bootstrap.php on line 197
0/11 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
Fatal error: Declaration of Drupal\Tests\BrowserTestBase::setUp() must be compatible with PHPUnit\Framework\TestCase::setUp(): void in /Users/Documents/sample/my_site_name_dir/web/core/tests/Drupal/Tests/BrowserTestBase.php on line 39

```

# Answer
The first warning could make you think PHPUnit isn't installed, but since `drupal-check` is able to tell you that the declaration of `Drupal\Tests\BrowserTestBase::setUp()` is not compatible with the declaration of `PHPUnit\Framework\TestCase::setUp()`, that is not the case. If PHPUnit weren't installed, `drupal-check` would report more missing classes.

PHPUnit is installed, but it's version 9.0.0 or higher version, where:

So, in short:

* The installed version of PHPUnit is at least 9
* The Drupal version you installed still requires PHPUnit 7

Notice that, so far, only Drupal 9.x has been updated to PHPUnit 8, and in future it will support PHPUnit 9. Previous Drupal versions still need PHPUnit 7, and eventually they will be updated to support PHPUnit 8.
> 3 votes

# Answer
I see similar behavior when I haven't installed PHPUnit and use `drupal-check` to perform the static code analysis on a module. The tests provided by Drupal modules/core require PHPUnit to be run, so when it's missing it seems logical `drupal-check` reports warnings/errors.

According to the documentation of mglaman/drupal-check you should be able to exclude directories (e.g., \*/tests/\*). However, when you are running this tool you might want to add PHPUnit to your development stack. One way to do this is to add drupal/core-dev by running `composer require --dev drupal/core-dev`.

Another option is to use the contributed Upgrade Status module, which provides extra functionality on top of drupal-check.
> 2 votes

---
Tags: 8
---


# Question
Title: Allow comments only for author of the node and certain role
I'm using Drupal 7. It is possible to disable the comment form for a specific node type for authenticated users? What hooks should I use if I want to allow only the author of the node and the administrator to post comments. The normal users (authenticated role) should only read them.

Thank you

# Answer
You can probably unset the comment form using `hook_form_alter` on the basis on certain condition:

```
function MODULENAME_form_alter(&$form, &$form_state) {
  if ( $form_id == 'comment_form') {
    global $user;
    if (!user_access('administer nodes') {
      // Form alter here to unset comment form
      unset($form);
    }
  }
}

```
> 2 votes

# Answer
You could try the Comment Access module.

> Comment Access allows your users to control the comments on their posts. It adds permissions to administer, approve, and delete comments on nodes they create without granting full comment administration access. Permissions are granted by node type, so it's a great way to allow your users to manage comments on their own blogs.
>
> ### Features
>
> * Adds permissions to:
>     + Administer comments on own content (for each content type)
>     + Delete comments on own content (for each content type)
>     + Approve comments on own content (for each content type) User
> * Option for e-mail notifications on comments needing approval site
> * Administrators can set a custom comment approval message and e-mail
> * Unapproved comments are left unpublished, so site administrators can still work with them as normal
> 0 votes

# Answer
If by *administrator* you mean the user whose ID is 1, I would use the following code.

```
/*
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_comment_form_alter(&$form, &$form_state) {
  global $user;
  $uid = $user->uid;
  if (($uid !== 1 && !isset($form['#node']) || ($uid !== 1 && $form['#node']->uid == $uid)) {
    $form['access'] = FALSE;
  }
}

```

If by *administrator* you mean the users who have the permission to administer comments, I would use use the following code.

```
/*
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_comment_form_alter(&$form, &$form_state) {
  global $user;
  $permission = user_access('administer permissions');
  if ((!$permission && !isset($form['#node']) || (!$permission && $form['#node']->uid == $user->uid)) {
    $form['access'] = FALSE;
  }
}

```

If by *administrator* you mean a user with a different permission, replace `'administer permissions'` with the permission you want to check.

In any case:

* Setting `$form['access']` to `FALSE` is better to unset `$form`, which would throw many warnings because of module accessing a `NULL` value as it would be an array
* Implementing `hook_form_FORM_ID_alter()` is better than implementing `hook_form_alter()` as the latter is invoked for every form, while the first is invoked only of a form type
> 0 votes

---
Tags: comments, users
---


# Question
Title: Allow comments only for the author of the node
I'm using Drupal 8 for a personal project and I'd like to allow only the node author to post comments.

Can you please help? I'm stuck.

# Answer
> 1 votes
although the Drupal 8 version still is on dev but you can try comment\_perm module.

> The Comment Permissions module enables control of commenting by user role and by node type. Additional user permissions for selected node types are added to the user access system so you can configure commenting with more control than Drupal core provides.

**Update**

another solution that I could suggest is using hook\_form\_alter.

in your custom module

```
function YOURMODULENAME_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if($form_id == "YOUR_COMMENT_TYPE_ID"){
    $node = \Drupal::request()->attributes->get('node');
    if(!is_null($node) && $node->getOwnerId() != \Drupal::currentUser()->id()) {
      $form['#access'] = false;
    }
  }

```

}

---
Tags: 8, nodes, comments
---


# Question
Title: Delete node references for some content types only
Unless there's a method I'm unaware of, node references are not related to their node's content type. I need to delete referenced nodes when the target ids are **not** of a certain content type. Here's my code so far.

```
// Get My content type nodes.
$nids = \Drupal::entityQuery('node')
  ->condition('type', 'my_content_type')
  ->execute();
/** @var \Drupal\node\NodeInterface[] $nodes */
$nodes = Node::loadMultiple($nids);
foreach ($nodes as $node) {
  // Select the related nodes from each node.
  $result = \Drupal::database()->select('node__my_reference_field', 'n')
    ->fields('n')
    ->condition('entity_id', $node->id())
    ->execute();

  // Determine what content type the related node is.
  while ($record = $result->fetchAssoc()) {
    $query = \Drupal::database()->select('node_field_data', 'nfd');
    $query->fields('nfd', ['type']);
    $query->condition('nid', $record['my_reference_field_target_id']);
    $type = $query->execute()->fetchField();

    if ($type != 'content_type_one' || $type != 'content_type_two') {
      \Drupal::database()->delete('node__my_reference_field')
        ->condition('entity_id', $node->id())
        ->condition('my_reference_field_target_id', $record['my_reference_field_target_id'])
        ->execute();
    }
  }
}

```

If this line

```
if ($type != 'content_type_one' || $type != 'content_type_two') {

```

were

```
if ($type == 'content_type_one' || $type == 'content_type_two') {

```

the related nodes of `content_type_one` and `content_type_two` are deleted. Using `!=` removes all the related nodes on the node. I only want to remove the related nodes that are **not** of `content_type_one` and `content_type_two`.

What am I missing?

---

@Jaypan here's the exact code that takes nine minutes to run.

```
function my_module_update_8008() {
  // Get the nodes.
  $nids = \Drupal::entityQuery('node')
    ->condition('type', 'my_type')
    ->execute();

  /** @var \Drupal\node\NodeInterface[] $nodes */
  $nodes = Node::loadMultiple($nids);

  foreach ($nodes as $node) {
    // Delete references on the nodes that are not news or story.
    foreach ($node->get('field_entity_reference')->referencedEntities() as $entity) {
      drush_print($node->id());
      if (!in_array($entity->bundle(), ['news', 'story'])) {
        $entity->delete();
      }
    }
  }
}

```

`drush_print()` is for debugging purposes. During the run of this code, a $node-\>id() prints every 1 or 2 seconds. As you well know, to run an update\_N hook from the command line, use

```
drush php-eval 'module_load_include('install', 'my_module'); my_module_update_8008();';

```

Anyway, it's 160 nodes x ~20 node references for each node. So the `drush_print()` helps me understand where the time is going.

Thanks for your help. I didn't mean to sound ungrateful. I think `referencedEntities()` and `$entity->bundle()` and the like are great, but I find them too slow. Once I have the field table populated with only the records I need, `drush cr` gets the referenced nodes to print in the text fields on the admin. I'll post my query code when I get it working again.

Btw, it's `getStorage()` not `loadStorage()` with entityTypeManager(). Thanks again.

# Answer
> 2 votes
Your code can be made more concise using Drupal APIs. It's rare that DB queries are required in Drupal 8, as the system generally has APIs that handle it for you. Here's how I'd do what you're trying to do. I think the key you were looking for is the line with `in_array()`.

```
// Load all 'some_content_type' nodes.
$properties = [
  'type' => 'some_content_type',
];
$nodes = \Drupal::entityTypeManager()->loadStorage('node')->loadByProperties($properties);

foreach ($nodes as $node) {
  // Loop through the entities referenced by the field.
  foreach ($node->get('my_reference_field')->referencedEntities() as $entity) {
    // Only act if the entity is not one of the given types.
    if (!in_array($entity->bundle(), ['type_1', 'type_2'])) {
      // Delete the entity.
      $entity->delete();
    }
  }
}

```

# Answer
> 0 votes
I think the `$entity->bundle()->delete()` code deletes the entire node entity. I want to delete the reference on the node, not the referenced node entity.

For example, say the entity reference id is 4070 and the node referencing it is node id 196541. `$entity->bundle()->delete()` deletes node 4070 when I just want to delete the reference to node 4070 from the field on node 196541. That's where the ~9 minutes to run happened.

I don't want to delete the referenced nodes (yikes), I only want to delete the references to the node.

Using database queries:

```
/**
 * Delete nodes references that are not news or story.
 */
function my_module_update_8008() {
  // Get the nodes.
  $nids = \Drupal::entityQuery('node')
    ->condition('type', 'my_type')
    ->execute();
  /** @var \Drupal\node\NodeInterface[] $nodes */
  $nodes = Node::loadMultiple($nids);

  // Delete references on overview node that are not news or story.
  foreach ($nodes as $node) {
    $result = \Drupal::database()
      ->query("SELECT * FROM {node__field_entity_reference} WHERE entity_id=:entity_id ORDER BY field_entity_reference_target_id", [':entity_id' => $node->id()]);
    while ($record = $result->fetchAssoc()) {
      $type = \Drupal::database()
        ->query("SELECT type FROM node_field_data WHERE nid =:target_id", [':target_id' => $record['field_entity_reference_target_id']])
        ->fetchField();
      if ($type == 'news' || $type == 'story') {
        continue;
      }

      $params = [
        ':entity_id' => $node->id(),
        ':target_id' => $record['field_entity_reference_target_id'],
      ];
      \Drupal::database()
        ->query("DELETE FROM {node__field_entity_reference} WHERE entity_id=:entity_id AND field_entity_reference_target_id=:target_id", $params);
      \Drupal::database()
        ->query("DELETE FROM {node_revision__field_entity_reference} WHERE entity_id=:entity_id AND field_entity_reference_target_id=:target_id", $params);
    }
  }
}

```

This code:

```
  if ($type == 'news' || $type == 'story') {
    continue;
  }

```

skips the news and story types.

If I want to keep news and story node references and delete the other types, I can take out the `continue;`.

And then `drush cr` does its magic and the references are updated in the referenced field. Takes seconds and solves the problem.

---
Tags: 8
---


# Question
Title: How do I get the referring entity of a referenced node in a template file?
I am struggling since a couple of days with my problem now and I have no idea what else I can do to come to a stage of enlightenment.

In Drupal 8 I have a content type called "Release" and a content type "Article" which, among others, contains Reviews of Releases. So in Releases I created an entity reference field called "Review" which references Article content type.

For index pages I could create views of Articles and there I pretty easy could integrate the fields of the referencing release entity via the Relations section in views administration. There the reverse direction of a relationship is not a problem.

How do I access the fields of the release in a node--article.html.twig template?

Edited due to character limitation in the comments section (I hope this is allowed): Thank you so much, @JeremyM4an, but there was a little misunderstanding due to my bad explanation of the problem. I should have mentioned that article has a reference to a taxonomy term, called field\_post\_category.

So a review is an article with field\_post\_category == 'Review' and finally a release has an entity reference field, called field\_review, referring to article. After reading your answer I tried this:

```
$category_field = $node->get('field_post_category');
$category_field = $category_field->getValue();
if( isset($category_field[0]['target_id']) && $category_field[0]['target_id'] ){
  $term = taxonomy_term_load($category_field[0]['target_id']);
  if($term && $term->get('name')->value == 'Reviews'){
    $release = \Drupal::entityQuery('node')
    ->condition('type', 'release')
    ->condition('field_review.entity:node.nid', $node->id())
    ->execute();
    // Load release node and store in variables.
    $variables['release'] = Node::load(array_values($release)[0]);
  }
}

```

But this does not work.

# Answer
> 2 votes
You can get the "relationships" to your referencing node in a preprocess function, in your theme's mytheme.theme file:

```
function mytheme_preprocess_node(&$variables) {
  if (!empty($variables['node'])) {
    $node = $variables['node'];
    if ($node->getType() === 'article') {

      // Get the review by article node id.
      $review = \Drupal::entityQuery('node')
        ->condition('type', 'review')
        ->condition('field_article', $node->id())
        ->execute();

      // Get release by review node id.
      $release = \Drupal::entityQuery('node')
        ->condition('type', 'release')
        ->condition('field_review', array_pop($review))
        ->execute();

      // Load release node and store in variables.
      $variables['release'] = Node::load(array_values($release)[0]);
    }
  }
}

```

Then you can access the fields in your template:

```
{{ release.field_name.value }}

```

---
Tags: 8
---


# Question
Title: Why does #triggering_element pick the wrong element?
I'm triggering an ajax-enabled button on a form but Drupal's setting `$form_state['#triggering_element']` to the wrong element.

The button is a child of a `#tree` and is identical to other buttons in other tree-ed structures, except for its parents. But I thought this was the point of `#tree`.

Looking at the drupal code in `form.inc` it's clear that Drupal only goes on the `#name` property to identify the triggering element, which is automatically set to `'op'` for buttons. This seems to have no idea about trees or the element's parents.

The rather scant and very old docs for tree state:

> `#parents` is used to create the name/ID of the form element itself.

But my button element's names are not being set to anything other than 'op'. I'm creating the buttons in a `#process` function for the parent element.

Example code

```
$form['group1'] = [
  '#prefix' => '<div>group1',
  '#suffix' => '</div>',
  '#tree' => TRUE,
  'trig' => [
    '#type' => 'submit',
    '#value' => 'ajax go',
    '#ajax' => [
      'callback' => 'mymod_ajax_callback',
      'wrapper' => 'foo',
      ],
  // Other elements part of group 1...
  ],
$form['group2'] = // The same.

```

A work-around is to code creating unique names for every one of these elements, but I feel I might be missing a trick/nuance?

# Answer
> 6 votes
The problem is in form\_builder() where it fallbacks to the first button if no button can be found.

A comment from form\_builder():

```
// Therefore, to be as consistent as we
// can be across browsers, if no 'triggering_element' has been identified
// yet, default it to the first button.
if (!$form_state['programmed'] && !isset($form_state['triggering_element']) && !empty($form_state['buttons'])) {
  $form_state['triggering_element'] = $form_state['buttons'][0];
}

```

More info can be found here: https://www.drupal.org/node/2546700#comment-11164091

There is also a patch for this problem that can be found in the link above.

# Answer
> 3 votes
First of all: you should implement all your $form modifications inside the form builder (hook\_form or hook\_form\_alter), not inside ajax callbacks. And my mistake in one form was that when I have added few buttons with one ajax callback but set **name** html attribute using #attributes\['name'\]. Drupal way in this case is to use '#name' parameter. Only when you set name attribute this way, $form\_state\['triggering\_element'\] and $form\_state\['clicked\_button'\] will be set to the correct element

# Answer
> 3 votes
To get a triggering element you must provide a unique '#name' for each button. Additionally, you can specify parameters to identify the action and record

```
function example_form($form, &$form_state){
    $form['groups'] = array(
        '#tree' => TRUE,
    );

    foreach(array(5,4,8,10) AS $id){

        $form['groups'][$id] = array(
            'id' => array(
                '#markup' => 'Group '. $id,
            ),
            // Some buttons with different actions for every group
            'btn_clone' => array(
                '#type' => 'submit',
                '#value' => 'Clone',
                // Any unique name for each button
                '#name' => 'clone-'. $id,
                // Your additional data to identify the action
                '#my_op' => 'clone',
                '#my_key' => $id,
            ),
            'btn_delene' => array(
                '#type' => 'submit',
                '#value' => 'Delete',
                //
                '#name' => 'del-'. $id,
                '#my_op' => 'delete',
                '#my_key' => $id,
            ),
        );

    }
    return $form;
}

function example_form_submit($form, &$form_state){
    $clicked_element = drupal_array_get_nested_value($form, $form_state['triggering_element']['#parents']);
    drupal_set_message($clicked_element['#my_op'] .' '. $clicked_element['#my_key']);
}

```

# Answer
> 2 votes
Your example code isn't right, it should be:

```
$form['group1'] = array(
  '#prefix' => '<div>group1',
  '#suffix' => '</div>',
  '#tree' => TRUE,
);

$form['group1']['trig'] = array(
  '#type' => 'submit',
  '#value' => 'ajax go',
  '#ajax' => array(
    'callback' => 'mymod_ajax_callback',
    'wrapper' => 'foo',
  ),
);

```

You shouldn't need to use $form\_state\['#triggering\_element'\] as you should be able to do everything you need in the mymod\_ajax\_callback function

# Answer
> 2 votes
When you click on a submit input field, the browser sends the value of the submit button along with the fields. So giving you have a input like this in the HTML:

```
<input type="submit" value="foo" />

```

Foo will be posted along with which ever input/select/textarea elements are located in the form.

Drupal uses this to figure out which form element was pushed. The limitation of this is that if you have multiple inputs that have the same value, Drupal can't discern which of them was actually pushed (since it only can look at the data posted) so it will take the same one.

The only way to make Drupal able to figure out which input was clicked is to

* Give them different names
* Use ajax with different callback functions.
* Use some JS + hidden field to post the info and handle this yourself.

As you can see, if you want a solution that doesn't rely in JS, you need to have different values on the submit buttons.

---
Tags: forms, ajax
---


# Question
Title: How to render HTML output in hook_ENTITY_TYPE_presave()
Upon node save, I want to take the value of a text field that uses a custom input filter and save the HTML-ified final version (what the input filter renders) in a second field.

I have two text fields:

* Field **text\_main** (which is never actually displayed, avoiding the performance penalty of rendering the field)
* Field **text\_main\_display** (which is displayed publicly)

The field **text\_main** uses a custom input filter that is very slow to run. So, I want to get the rendered output of the field after running the input filter and save it to the field **text\_main\_display**.

```
/**
 * Implements hook_ENTITY_TYPE_presave()
 */
function MYMODULE_node_presave(NodeInterface $entity) {
  switch ($entity->getType()) {
    case 'custom_page':
      $processedResult = $entity->get('field_text_main')->view('custom_display');
      // $processedResult is now a render array. How do I render this to HTML?
      $entity->set('field_text_main_display', $processedResult);
      break;
  }
}

```

Reference: This post on how to render Drupal 8 fields

# Answer
In hooks which are not executed in a render context use renderPlain(), see Cron error: LogicException : Render context is empty

```
$html = \Drupal::service('renderer')->renderPlain($processedResult);

```

Caveat: Text filters can bubble up metadata which you ignore by storing only the HTML. For a custom text filter this might be OK when you know it doesn't depend on cache metadata and attachments, but don't use this as a general approach. This can have security implications, like revealing data to non-authorized users.
> 2 votes

---
Tags: 8, entities, hooks
---


title: Contextual filter by node reference ID

text:
# Question
Title: Contextual filter by node reference ID
Since good 10 years I work with Views in Drupal. Seems I am just to stupid to get it :) I tried really every combination but I am not able to put out a working block view with articles, which are referenced to the current node.

We have two node types:

```
- Articles
  -  field (relationship to product node)
- Products

```

Some articles have a relationship (node reference field) to products. When on the node page the view blog should output every 'article', that has a relationship to the current node (product).

I tried to add a contextual filter (node id from url) and a relationship (field\_node\_reference). The contextual filter uses then this relationship. However, I know this is not enough.

Results are 0 Which steps are involved? What have I forgotten?

Thanks

# Answer
Try first with a hardcoded node id. Once that is working, check if the node id in URL is working.
> 0 votes

---
Tags: views, 8
---


# Question
Title: Add an item to a checkbox in a content type
I started working with drupal recently and I have been assigned many small tasks. I would like to know how I can add an item to the following checkbox, I can't understand how:
Thanks in advance!

# Answer
> 1 votes
Click on "field settings" in the top right hand corner of that screen. That's where storage specific options are held.

If you can edit the options there then it's a simple text list. But it may be that field is referencing a taxonomy term or content/entity but that tab will lead you in the right direction to add an item

# Answer
> 1 votes
Once a field is created, you can still change its settings clicking on the *Field settings* tab you see in the screenshot you took.

>

As you notice, the warning tell you the settings cannot be longer changed, as there is already a node containing data for that field. That doesn't mean you cannot change anything for that field. For example, I was able to add a new value to the list, which is what you want to do.

>

What you cannot do is removing values that are used. In that case, you get an error message, similarly to what happened to me when I tried to remove the default value (*frontpage|Front page*), which was used from the test node I created.
The message is clear: *Allowed values list: some values are being removed while currently in use.*

>

---
Tags: 7
---


# Question
Title: How to check if a Vocabulary is translatable?
In Drupal Core, I found the following code:

```
$entity instanceof TranslatableDataInterface && $entity->isTranslatable()

```

But it looks like it is not working for the Taxonomy vocabularies

# Answer
> 1 votes
This information is stored in configuration and you can retrieve it by using this service:

```
\Drupal::service('content_translation.manager')->isEnabled('taxonomy_term', 'my_vocab')

```

More info Where do I fetch myself complete definition for a bundle?

# Answer
> 0 votes
`$entity instanceof TranslatableDataInterface && $entity->isTranslatable()` doesn't work because the first part is checking for the wrong interface. The correct code is the following one.

```
$entity instanceof TranslatableInterface && $entity->isTranslatable()

```

It's `TranslatableInterface` that defines `isTranslatable()`. `TranslatableDataInterface` is not an interface defined from Drupal core.

The documentation page for the `Term` class has a list of its methods. You can also see which class implements them, and which method they override. In the case of `isTranslatable()` the page reports the following data.

```
ContentEntityBase::isTranslatable    public    function    Returns the translation support status.
                                                           Overrides TranslatableInterface::isTranslatable

```

The `Vocabulary` class, which is the class for the configuration entity used to define the bundles of the *Taxonomy term* entity (a content entity), doesn't have any `isTranslatable()` method.

---
Tags: taxonomy-terms, i18n-l10n
---


# Question
Title: How to add image field in a custom module form?
In our custom module, `mymodule` we have a form `MyModuleForm` where we want to allow for an image to be uploaded or chosen from already uploaded images. Below is the `MyModuleForm.php` file, but cannot figure out why we are not able to upload the Image and save it. There is a menu link where the module's form is and when we navigate to the page we see a blank page with no field or widget to set the image.

**Goal**

1. To be able to make the `Image Browser` widget display so that we can use an existing image or upload one.
2. Store the image using `MyModuleForm` from the custom module.
3. We should be able to change the image as needed and save the configuration.
4. Set file status to permanent.
5. Add to file usage calculation.

How do we add an `Image` field on our `MyModuleForm` so that we can either use an existing image or upload a new one?

**Here is what we tried but didn't work**

**MyModuleForm.php**

```
class MyModuleForm extends ConfigFormBase {
  protected function getEditableConfigNames() {
    return [
      'mymodule.settings'
    ];
  }

  public function getFormId() {
    return 'mymodule_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('mymodule.settings');
    $form['my_file'] = [
      '#type' => 'managed_file',
      '#title' => 'my file',
      '#name' => 'my_custom_file',
      '#description' => $this->t('my file description'),
      '#default_value' => $config->get('my_file'),
      '#upload_location' => 'public://'
    ];

    return parent::buildForm($form, $form_state);
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Check if image is uploaded.
    if(isset($form_state['default_press_release_image'])) {
      // Set file status to permanent.
      $image = $form_state->getValue('my_file');
      $file = File::load($image[0]);
      $file->setPermanent();
      $file->save();
      // Add to file usage calculation.
      \Drupal::service('file.usage')->add;
    }

    $this->config('ns_default_images.settings')
      ->set('default_press_release_image', $form_state->getValue('default_press_release_image'))
      ->save();

    parent::submitForm($form, $form_state);
  }
}

```

# Answer
The default\_value attribute accept an array in case of managed\_file:

```
  $form['my_file'] = [
      '#type' => 'managed_file',
      '#title' => 'my file',
      '#name' => 'my_custom_file',
      '#description' => $this->t('my file description'),
      '#default_value' => [$config->get('my_file')],
      '#upload_location' => 'public://'
    ];

```

In The submit function you are using a field name different from the declared one in the buildForm().

The value of a managed\_file should be an array even when the field is not multiple:

```
$form_state->getValue('default_press_release_image')[0];

```
> 2 votes

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


# Question
Title: hook_menu_links_discovered_alter() not being called
I'm working on a theme for a Drupal 8.8 project. I've implemented hook\_menu\_links\_discovered\_alter() in my `.theme` file – but Drupal doesn't seem to be invoking it, and I don't understand why.

(For context: my goal is to make some modifications to the "Log in" and "Log out" links on the user account menu. I've found numerous examples online which say that this is the right hook to use for this purpose.)

Here's what I've tried:

* I've checked (a dozen times) that I'm using the correct function name, with the correct signature: `mythemename_menu_links_discovered_alter(&$links)`
* I've added `die('in hook')` in my hook function to determine whether it's even being called. (It's not.)
* I've cleared cache many times, from both the Drupal web dashboard and via `drush cr`. No luck.
* I've noticed that Drupal sometimes takes a while to notice changes to `.theme` files, even after you've cleared cache. So, to be absolutely sure that Drupal is using the latest version of the file, I've added `echo` statements to other (already-working) hooks. This has confirmed that Drupal is using the latest version of the file – but `mythemename_menu_links_discovered_alter()` still isn't being called.

Any ideas?

# Answer
> 1 votes
You can only implement `hook_menu_links_discovered_alter()` in a module.

Generally, alter hooks are invoked even if they are implemented in themes, but to be sure you always need to check the code invoking the specific alter hook.
In this case, `hook_menu_links_discovered_alter()` is invoked from `MenuLinkManager::getDefinitions`. You can see this by clicking on *1 invocation of hook\_menu\_links\_discovered\_alter()*.

>

That method only invokes hooks implemented by modules, as it uses the following code.

```
$this->moduleHandler->alter('menu_links_discovered', $definitions);

```

To allow themes to alter those links, the code should contain a line similar to the following one, where `$this->themeManager` is an object implementing the `ThemeManagerInterface` interface.

```
$this->themeManager->alter('menu_links_discovered', $definitions);

```

---
Tags: 8
---


# Question
Title: How can I add arbitrary placeholder text to form fields?
I'm converting an existing site (built by someone else) from Drupal 7 to Drupal 8.

The old site uses the Field Placeholder module to add placeholders to form fields. However, there isn't yet a Drupal 8 version of this module.

I came across the Form Placeholder module, which does have a Drupal 8 version – but it won't work for my case. (Most significantly, it only allows you to use the field label as the placeholder – you can't enter an arbitrary placeholder that's different from the label.)

Is there another option I can consider?

(I'm aware that I could hack something together with jQuery. For various reasons, I'd prefer not to do that.)

# Answer
> 0 votes
It seems that this functionality is now in the Drupal core – placeholders can be added from the widget settings on the content type's form display page.

---
Tags: 8
---


# Question
Title: Composerise Drupal command syntax and starting location
I have 2 sites a dev site and the production site. Need to convert them from drupal/drupal composer sites to the newer format allowing continued support for composer. The syntax is unclear to me as detailed below. From https://github.com/grasmash/composerize-drupal

The '**composer-root**' is supposed to be where .git is. Composer is at /home dir, their is a Git directory a .composer (dir) .gitconfig (file) (**I have always ran composer from terminal /opt/lampp/htdocs/d8/web directory**)

So is composer-root=./home ??

The Drupal dev site is located in /opt/lampp/htdocs/d8/web where in the web dir the index.php, composer.json, composer.lock, update.php files are. This is where I ran composer from previously.

So is --drupal-root=./opt/lampp/htdocs/d8/web ??

**And I run the command from /opt/lampp/htdocs/d8/web as I have done previously?**

If correct: composer composerize-drupal --composer-root=./home --drupal-root=./opt/lampp/htdocs/d8/web --no-update

Many thanks for any suggestions!

# Answer
`composer-root` should not be your Home directory. It looks like you might have assumed that because there is a directory named `git` there, but that's not what the installation instructions at https://github.com/grasmash/composerize-drupal are referring to. Those instructions assume that your project files are being tracked as part of a Git repository. You can tell where the root of a Git repository is because it contains a directory called `.git` (note the dot in front, which the `git` directory in Home doesn't have).

If your project files are indeed part of a Git repository, the root would be in one of the upward directories from `/opt/lampp/htdocs/d8/web`.

> So is --drupal-root=./opt/lampp/htdocs/d8/web ??

Almost. The drupal root is where the `core` directory and `index.php` can be found. But that `.` in there makes this a relative directory path. You almost certainly mean to use an absolute path there, which would be `--drupal-root=/opt/lampp/htdocs/d8/web`.

> So is composer-root=./home ??

No. Most likely, you will want your `composer-root` to be one directory up from your project root (where index.php is). So I'd try `--composer-root=/opt/lampp/htdocs/d8`.
> 1 votes

---
Tags: composer
---


# Question
Title: How to use the managed_file field in a custom form plugin
I'm attempting to create a module with a custom form that allows users to upload a file using a managed\_file field. The name of my module is foundation\_settings and the file structure is:

```
foundation_settings
  -foundation_settings.info.yml
  -foundation_settings.module
  -src
    -Form
      -FoundationForm.php

```

Inside FoundationForm.php I'm building the form with the following code:

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $config = $this->config('foundation.settings');
  $form['icons'] = [
    '#type' => 'details',
    '#title' => t('Front Page Icons'),
    '#open' => FALSE,
    'icon1' => [
      '#type' => 'fieldset',
      '#title' => t('First Icon'),
      'icon1_file' => [
        '#type' => 'managed_file',
        '#name' => 'icon1',
        '#title' => t('First Icon Image'),
        '#default_value' => $config->get('icon1_file'),
        '#upload_location' => 'public://',
      ],
    ],
  ];
}

```

However I'm not sure how to handle the managed\_file when the form is being submitted. In my submitForm function I have

```
public function submitForm(array &$form, FormStateInterface $form_state) {
  $imageid = $form_state->getValue('icon1_file');
  $file = file_load($imageid[0]);
  if (gettype($file) == 'object') {
    $file->status = FILE_STATUS_PERMANENT;
  }
  $this->config('foundation.settings')
    ->set('icon1_file', $form_state->getValue('icon1_file'))
    ->save();
  $file->save();
}

```

The upload and saving works okay but I keep receiving this error after submitting

> The file used in the First Icon Image field may not be referenced.

How are you supposed to use managed\_file field in custom form plugins?

# Answer
I think the issue we had was understanding the data that the form was sending back to us when using the 'managed\_file' type. This creates an entity of File and stores the image information directly into the table called 'file\_managed' in your database, but also saves the file to your directories based upon where you send it. So take this code for example:

```
$form['mainslider_slide_one']['image_dir'] = [
  '#type' => 'managed_file',
  '#upload_location' => 'public://module-images/home-slider-images/',
  '#multiple' => FALSE,
  '#description' => t('Allowed extensions: gif png jpg jpeg'),
  '#upload_validators' => [
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('gif png jpg jpeg'),
    'file_validate_size' => array(25600000)
  ],
  '#title' => t('Upload an image file for this slide')
];

```

For the `#upload_location` we are telling the file to be stored in our public folder under the specified directory (`sites/sitename/files/`). So now we have the actual file stored where we want, as well as data stored in the database.

When we receive the information back (during validation for instance) we have the following code:

```
public function validateForm(array &$form, FormStateInterface $form_state) {
  $managedFileId_imageOne = $form_state->getValue(['mainslider_slide_one' => 'image_dir']);
  if (empty($managedFileId_imageOne)) {
    $form_state->setErrorByName('test', 'No image found for image one');
  }
}

```

The result of `$managedFileId_imageOne` will either be an empty array (whereas I am sending an error message back) or an array of fid's. The fid is the location in the database. This is the information that we ended up saving into our settings file data. So when we pull the information into our program we are querying for the 'fid' located in the 'file\_managed' table using the Entity::load method.

**NOTE/UPDATE:**

Don't forget that files uploaded in this manner are currently, by default, set to be temporary (status column in the "file\_managed" table). You need to set the file to permanent to manually set status to 1 so they are not temporary. I believe this is functionality that is currently a bug and they are looking into possibly updating this in future releases.

Sample from Jasodeep

```
$image = $form_state->getValue('image');
$file = File::load( $image[0] );
$file->setPermanent();
$file->save();

```

Hope this helps at least get you on your way!
> 15 votes

# Answer
You may have troubles with file storage. It can mark your file as temporary file. And it will disappear after file cron. So it's better to consider this topic to prevent Drupal doing it.

```
$file->setPermanent();
$file->save();
// Add to file usage calculation.
\Drupal::service('file.usage')->add($file, 'my_module_name', 'file', $file->id());

```
> 1 votes

---
Tags: forms, 8, blocks
---


# Question
Title: Safe and elegant way to access nested entities via fields
I've seen a variety of approaches to access entity values in the theming layer. The code below is just a simple example using magic methods. It assumes all values are set - if any part of that returns a NULL, then in my experience errors ensue.

```
$value = $node->field_paragraph
    ->entity->field_media
    ->entity->field_file
    ->entity->field_text->value;

```

There are methods like `->hasField` and `->count()` to check things, and i have a variety in my themes. I can get the job done but sometimes it feels ugly. I'm interested the coding patterns that devs use to safely and elegantly drill through entity references.

# Answer
Suggestion, create a domain object that has the logic.

Normally these entities represent something that fits your business-domain.

E.g in your instance, the node might be an event.

So you might model a domain object called `EventWrapper`.

```
<?php

namespace Drupal\my_domain;
use Drupal\node\NodeInterface;
use Drupal\media\MediaInterface;
use Drupal\file\FileInterface;

class EventWrapper {
  protected $node;
  public static function fromNode(NodeInterface $node): EventWrapper {
    $instance = new static();
    $instance->node = $node;
    return $instance;
  }
  public function getMedia() : ?MediaInterface {
    if ($this->node->hasField('field_media') && !$this->node->get('field_media')->isEmpty()) {
      return $this->node->field_media->entity;
    }
    return NULL;
  }
  public function getMediaImage() : ?FileInterface {
    if (($media = this->getMedia()) && $media->hasField('field_file') && !$media->get('field_file')->isEmpty()) {
      return $media->field_file->entity;
    }
    return NULL;
  }
  public function getImageCaption(): ?string {
    if (($file = this->getMediaImage()) && $file->hasField('field_text') && !$file->get('field_text')->isEmpty()) {
      return $file->field_text->value;
    }
    return NULL;
  }
}

```

Then in your code:

```
<?php

$image_caption = EventWrapper::fromNode($node)->getImageCaption();

```
> 7 votes

# Answer
Although normally you render paragraphs recursively, you can retrieve a fixed structure non-recursively by recreating it with foreach loops:

```
foreach ($node->field_paragraph->referencedEntities() as $paragraph) {
  foreach ($paragraph->field_media->referencedEntities() as $media) {
    ...
  }
}

```

This avoids accessing empty fields and is able to process multi-value fields.
> 6 votes

# Answer
To expand on the great answer by 4k4 which shows a pattern we use widely but doesn't cover the existence of the field, you could create a simple class patterned after larowlan's great answer:

```
class EntityReferenceItemListHelper {
   protected $fieldItemList;
   static function create(?EntityReferenceFieldItemListInterface $fieldItemList) {
     $instance = new static;
     $instance->fieldItemList = $fieldItemList;
   }
   public function referencedEntities(): array {
     return $this->fieldItemList ? $this->fieldItemList->referencedEntities() : [];
   }
}

```

and then `foreach (EntityReferenceItemListHelper::create($paragraph->field_media)->referencedEntities() as $media) {`
> 1 votes

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


# Question
Title: Search Results page. Move the search form after the results?
Apparently the only template file to edit is for an individual search result, located at `core/modules/search/templates/search-result.html.twig`. So you can't move the search form after the results and style accordingly?

Just want to double check this.

# Answer
Short answer. If you're looking for a twig template to move around the search form, no you can't.

Long answer. Drupal core search dynamically builds its search routes for all searchable entities then handles the page render via `SearchController::view()`. The controller view method only defines the theme functions/templates for the search results, not the search page as a whole.

If you wanted to move these around the render form & results elements, It's possible to override the search routes via a custom module so the `_controller` property points to a custom controller that extends `SearchController` and defines a `view()` method that does something like:

```
// in my custom search controller:
public function view(Request $request, SearchPageInterface $entity) {
  $build = parent::view($request, $entity);
  // @TODO: alter $build render array so form / results are re-ordered
  return $build;
}

```
> 1 votes

---
Tags: 8, search
---


# Question
Title: How can I create an entity reference field to list a subset of roles?
I want to provide a field in a node to lists a subset of available roles. These roles could be used to decide how the node would be displayed to users with the roles selected here.

Is there a way to create an entity reference field of entity type user role? If yes, how can I restrict the field to display only certain roles? The usual way is to create a view with entity reference display and add conditions in the view to restrict the options. Is it possible to create a view of type user role?

# Answer
Two parts to check here.

1. Is it possible to reference user role (a config entity)
2. Is there a way to restrict the available roles in the field level.

reg #1, yes! the out-of-box Drupal core allows creating an entity reference field with the target entity as a user role.

For #2, there is no easy way as the only way to restrict the available option(in core) is via views, but unfortunately, we can create views of the content entities. However, we can add a reference handler with config (as below) to restrict the available roles.

```
<?php

namespace Drupal\mymodule\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provide configuration to select specific roles to reference.
 *
 * @EntityReferenceSelection(
 *   id = "default:user_role",
 *   label = @Translation("Role selection"),
 *   entity_types = {"user_role"},
 *   group = "default",
 *   weight = 1
 * )
 */
class RoleSelection extends DefaultSelection {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $configuration = $this->getConfiguration();
    $entity_type_id = $configuration['target_type'];
    $storage = $this->entityTypeManager->getStorage($entity_type_id);

    $options = array_map(function ($entity) {
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      return $entity->label();
    }, $storage->loadMultiple());

    $form['target_roles'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Allowed roles'),
      '#options' => $options,
      '#default_value' => isset($configuration['target_roles']) ? (array) $configuration['target_roles'] : [],
      '#multiple' => TRUE,
    ];
    return $form;
  }
    /**
   * {@inheritDoc}
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    $configuration = $this->getConfiguration();
    $target_type = $configuration['target_type'] ?: [];
    $entity_type = $this->entityTypeManager->getDefinition($target_type);
    $query = parent::buildEntityQuery($match, $match_operator);

    // Add condition, if set of roles selected.
    if (isset( $configuration['target_roles'])) {
      $query->condition($entity_type->getKey('id'), $configuration['target_roles'], 'IN');
    }
    return $query;
  }

}

```

Here is the field settings page:

and here is the final output:
> 3 votes

---
Tags: 8, users
---


# Question
Title: How can we show the difference between values in consecutive rows in views
I am building a site where users will fill webforms (these are quality of life questionnaires). Users will fill the same form several times. I want to show the change in the value of fields in the webform. For example, if there is a field, say score 1 which has a value of 10 on 13 May 2020, and 15 on 14 May 2020, I want to show that the value has changed by 5 points.

I want to show this using Views as it will allow us to filter by dates on which the form was filled as well as the users (and use contextual / exposed filters).

The Views Aggregator field allows us to calculate the range for a column and using the a modified range formula (which the maintainer kindly developed very quickly) we can show the difference between two values. However, this is constrained to be displayed as a table row and not a field.It also has the disadvantage that the value is always maximum - minimum of the two values.

Is it possible that we can get this as a field in Views (so that I can apply custom css code). The motivation for doing this is to show the value in different colors depending on the value (e.g. red color if the value is more than 10 and green if it is less than 5).

It is noteworthy that each questionnaire can have many different scores computed and I would like to make a display for each. Note that for the display of the change we are looking for change of the recent value as compared to last filled.

Any pointers will be appreciated.

# Answer
Daniel Cothran, the developer of the Views Cumulative field prepared a field (in no time at all) that serves the purpose. The link to the file is available here Measure of Change Field in Views Cumulative Field Module
> 0 votes

---
Tags: views, webforms
---


title: How to get fetchField using db_query?

text:
# Question
Title: How to get fetchField using db_query?
I wrote db\_query in two ways, I followed the drupal documentation to write safe db\_query, one of them doesn't work, I want to know what I'm doing wrong in the code below.

```
// Worked perfectly
function custom_get_user_account_id() {
  global $user;
  return db_query("SELECT `field_account_target_id` FROM {field_data_field_account} where `entity_id`=:user_id and `bundle` = 'user'", array('user_id' => $user->uid))->fetchField();
}

// doesn't work
function custom_get_user_account_id() {
  global $user;
  return db_query("SELECT field_account_target_id FROM {field_data_field_account} fa where 'fa.entity_id = :user_id and fa.bundle = :user' ", array(':user_id' => $user->uid, ':user' => 'user'))->fetchField();
}

```

# Answer
> 0 votes
Supposing that the first version of the function is working, it doesn't restrict the values by the entity ID, since you aren't providing any value for the *:user\_id* placeholder.

The second version of the function doesn't work because, instead of passing the `'user'` string as value for the *:user\_id* placeholder, it's passing an object which, if casted to a string, it's not surely equal to `'user'`. Plus enclosing the `fa.entity_id = :user_id and fa.bundle = :user` in string delimiters is wrong, as it's making that part a literal string, which is not what you want.

The correct version of the function is the following one.

```
function custom_get_user_account_id() {
  global $user;
  return db_query("SELECT fa.field_account_target_id FROM {field_data_field_account} fa WHERE fa.entity_id = :uid AND fa.bundle = :bundle", array(':uid' => $user->uid, ':bundle' => 'user'))->fetchField();
}

```

# Answer
> 0 votes
You could achieve this by either one of the following:

By using `db_query()`:

```
function custom_get_user_account_id() {
    global $user;
    return db_query('SELECT field_account_target_id FROM {field_data_field_account} WHERE entity_id = :user_id AND bundle = :bundle', [
        ':user_id' => $user->uid,
        ':bundle' => 'user',
    ])->fetchField();
}

```

Or by using `db_select()`:

```
function custom_get_user_account_id() {
    global $user;
    return db_select('field_data_field_account', 'fa')
        ->fields('fa', ['field_account_target_id'])
        ->condition('entity_id', $user->uid)
        ->condition('bundle', 'user')
        ->execute()->fetchField();
}

```

---
Tags: 7, database
---


# Question
Title: Add new items to a multivalue field instead of override existing values
I have an *Article* content type with a multi-values taxonomy reference field (field\_article\_countries) for the *Countries* vocabulary. I also have a *Book* content type with a multi-values taxonomy reference field (*field\_book\_countries*) for the same vocabulary.

I am trying to:

* Loop through all the loaded articles one by one
* Get all the *field\_article\_countries* values
* Set those values to *field\_book\_countries*
* Save the loaded *Book* node

For example, a *Book* node (ID 12) has *field\_book\_countries* set to *none*. An *Article* node (ID 3) has *field\_article\_countries* set to *Italy*; another *Article* node (ID 40) has *field\_article\_countries* set to *Greece, Turkey, Egypt, Brazil, Spain*.

I want to:

* Load the first *Article* node
* Get the value of its *field\_article\_countries* (*Italy*)
* Load the *Book* node and set its value of *field\_book\_countries* to *Italy*
* Load the other *Article* node
* Get the values of its *field\_article\_countries* (*Greece, Turkey, Egypt, Brazil, Spain*)
* Set the *field\_book\_countries* values for the *Book* node to *Greece, Turkey, Egypt, Brazil, Spain, Italy*
* Save the Book node

The code I am using to achieve this is the following.

```
$articleIDs = [
  '3',
  '40'
];

// Load all the articles.
$articles = \Drupal\node\Entity\Node::loadMultiple($articleIDs);

// Loop through the loaded articles.
foreach ($articles as $article) {
  // Get the "Countries" Values.
  $countries = $article->get('field_article_countries')->getValue();

  // Set the 'countries' values to the node "book".
  $book->set('field_book_countries', $countries);
  // $book->field_book_countries[] = ['target_id' => $countries];
}

// Save the Book node.
$book-->save();

```

However, for some reason and during the loop, the new values of *field\_book\_countries* are overriding the existing one.

What am I doing wrong?

# Answer
You need to loop through all articles, saving all countries in an temp array. When the loop finished save the countries in the book node.

For example:

```
$countries = [];
// Loop through loaded articles.
foreach ($articles as $article) {

    // Get the "Countries" Values.
    $countries = array_merge($countries, $article->get('field_article_countries')->getValue());
}
// Set the 'countries' values to the node "book".
$book->set('field_book_countries', $countries);
// Save Book node.
$book-->save();

```
> 3 votes

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


title: How do I remove an unused patch?

text:
# Question
Title: How do I remove an unused patch?
I'm trying, for the first time, to add a patch in composer.json, for a layout builder issue (https://www.drupal.org/project/drupal/issues/3045171#comment-13450756).

It's the first time I do it, I see that after using the patch composer creates a "b" directory in inside the "core" directory.

The question is: when I'll upgrade the core version what should I do, if the patch will be include in the next release? Remove patch from composer.json? And what about that "b" directory?

I've added this code in the "extra" section of my composer.json and before I've installed the cweagans/composer-patches plugin, with composer:

```
"patches": {
  "drupal/core": {
    "#3045171-140: Forms break Layout Builder saving.": "https://www.drupal.org/files/issues/2020-02-04/layout-builder-save-issue-3045171-140.patch"
    }
  },
"enable-patching": true

```

# Answer
> 4 votes
Once you removed the patch from composer.json and run updates, core directory will be overridden by the new release and here the "b" directory will be removed.

For best practices reasons, I invite you to manage your project patches using composer patches plugin, and to be more specific use external patch file method.

---
Tags: composer, layout-builder
---


# Question
Title: Change Classes in Nav-Tag of Custom Menu
On a Drupal 8 installation, I have a menu in the sidebar first region. I want to add classes to bootstrap classes to the different levels of that menu. For that I created a my own menu template, which looks like this:

```
{#
/**
 * @file
 * Theme override to display a menu.
 */
#}

{% import _self as menus %}

{{ menus.menu_links(items, attributes, 0, my_menu) }} {# 1. #}

{% macro menu_links(items, attributes, menu_level, my_menu) %} {# 1. #}
    {% import _self as menus %}
    {# 1. #}
    {%
    set menu_classes = [
    'navbar-nav', 'mr-auto' ~ my_menu|clean_class,
    ]
    %}
    {# 1. #}
    {%
    set submenu_classes = [
    'navbar-nav', 'mr-auto' ~ my_menu|clean_class,
    ]
    %}
    {% if items %}
        {% if menu_level == 0 %}
            <div class="navbar-collapse offcanvas-collapse open"><ul{{ attributes.addClass(menu_classes) }}> {# 1. #}
        {% else %}
            <ul{{ attributes.removeClass(menu_classes).addClass(submenu_classes) }}> {# 1. #}
        {% endif %}
        {% for item in items %}
            {# 1. #}
            {%
            set item_classes = [
            'nav-item' ~ my_menu|clean_class,
            item.is_expanded ? 'expanded' ~ my_menu|clean_class,
            item.is_collapsed ? 'collapsed' ~ my_menu|clean_class,
            item.in_active_trail ? 'trail' ~ my_menu|clean_class,
            ]
            %}
            {# 1. #}
            {%
            set link_classes = [
            'nav-link' ~ my_menu|clean_class,
            ]
            %}
            <li{{ item.attributes.addClass(item_classes) }}>{# 1. #}
                {# 1. #}
                {{
                link(
                item.title,
                item.url,
                item.attributes.removeClass(item_classes).addClass(link_classes)
                )
                }}
                {% if item.below %}
                    {{ menus.menu_links(item.below, attributes, menu_level + 1, my_menu) }} {# 1. #}
                {% endif %}
            </li>
        {% endfor %}
        {% if menu_level == 0 %}
            </ul></div>
        {% else %}
            </ul>
        {% endif %}

    {% endif %}
{% endmacro %}

```

This works fine. However, I also need to change the classes of the nav tag. I can't seem to figure out, how that can be done and I can't find any information anywhere explaining this. So how do I change the nav tag classes of that menu?

In the end I want it to be a bootstrap offcanvas menu like this one: https://getbootstrap.com/docs/4.0/examples/offcanvas/

But I just can't seem to change the nav tag classes, since I don't know how.

# Answer
You'll need to enable Twig template debugging output to do this. Once you do that you should see a number of template suggestions upward in the DOM for the `<nav>` tag. For example:

```
   * block--mainnavigation.html.twig
   * block--system-menu-block--main.html.twig
   * block--system-menu-block.html.twig
   * block--system.html.twig
   x block.html.twig

```

(Note this assumes you are using Drupal's block system to render the menu.) Above are a number of suggestions. If I look in a likely candidate from above, for example, `block--system-menu-block.html.twig`, I see markup like this:

```
<nav role="navigation" aria-labelledby="{{ heading_id }}"{{ attributes|without('role', 'aria-labelledby') }}>

```

You can grab any of these templates from core and then override by using a copy of the template in your theme and then alter the markup per your requirements.

If you are using Twig Tweak to render the menu, then in that case, you can just add your own custom `<nav>` tag like so, usually in a page template such as `page.html.twig`:

```
  <nav role="navigation" aria-labelledby="off-canvas-menu" class="main-menu" id="off-canvas-menu">
    {{ drupal_menu('main', 1, 4, TRUE) }}
  </nav>

```
> 0 votes

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


# Question
Title: Migrate sub_process plugin is not working
There are a couple of questions that are closely related to this on this forum that I have reviewed several times. None of them seem to address the issue specifically.

I have a target field (with subfields) that is set to unlimited.

The **Source** that I'm "migrating" from is JSON. The **Target**, in this case, is an address field on a node.

To simplify and debug the migration. I created a constant as a source for the values that I want to assign to *field\_locations/country\_code*.

The code in the migration configuration YAML is

```
source:
  constants:
    title_suffix: ' (Imported from remote file)'
    country: 'GB'
    countries:
      -
        country: US
      -
        country: CA
....

process:
  field_locations:
      plugin: sub_process
      source:
        - constants/countries
      process:
        country_code: country

```

If I replace the implementation of the ***sub\_process plugin*** and use ***get***, I update the target field (subfield actually) with:

```
field_locations/country_code: constants/country

```

The destination row is updated perfectly - though of course I can only et

For reference: This is what the entity should look like with repeating values set. How do I get that to work with this migration? I'm guessing there is something pretty simple I'm missing

# Answer
> 2 votes
OK - I spent far more time than I care admit debugging this one. (doesn't help that PHPStorm is very unfriendly when it comes to stepping through a migration (e.g. I have not found a way to do it). Hope this saves someone from the frustration I had.

**Problem one:** Source was not formatted correctly. It MUST follow the following structure:

```
$source = [
  'countries' => [
    0 => [
      'country' => 'US',
    ],
    1 => [
      'country' => 'CA',
    ],
  ],
];

```

The YAML for that is:

```
  constants:
    countries:
      - country: 'US'
      - country: 'CA'

```

**Problem two:** The implementation of sub\_process was a little off. And a little off is like being on the wrong planet. It should like this

```
  field_locations:
    plugin: sub_process
    source: constants/countries
    process:
      country_code: country

```

One thing that is not obvious (and would never be if you were actually "migrating" from D7 to D8 for example, is the source.

Here, I am not actually migrating. It is an import from JSON. And, as it turns out, importing JSON can be a little unpredictable. The final "gotcha" was that the key "country" had to relate to the source (which it usually does). I had tried to slap in a different constant. (bad idea - though it could be done if that is *really* what is wanted.

---
Tags: 8, migrations
---


# Question
Title: CKeditor doesn't work in controller response within a default theme
In a Drupal 8 project I've a controller which returns a form that contains a text\_format field.

CKeditor is working perfectly in my administration theme (Stable), but it does not on the default theme.

I've tried to attach ckeditor core module libraries to the controller returned response with no results.

The role which I test with has permissions "Use simple HTML text format", "Use full HTML text format", also the role is checked on `/admin/config/content/formats/manage/basic_html` also on `/admin/config/content/formats/manage/full_html`.

my\_module/src/Controller/MyController.php :

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\user\Entity\User;

/**
 * Provide user form.
 */
class MyController extends ControllerBase {

  /**
   * Return page content.
   */
  public function content() {
    // Load user edit form.
    $entity = User::load(\Drupal::currentUser()->id());
    $formObject = \Drupal::entityTypeManager()
      ->getFormObject('user', 'default')
      ->setEntity($entity);
    $form = \Drupal::formBuilder()->getForm($formObject);
    $render = \Drupal::service('renderer');
    $render_form = $render->renderPlain($form);
    return [
      '#theme' => 'customize_user_form',
      '#form' => $render_form,
      '#attached' => [
        // Attach ckeditor core module libraries.
        'library' => [
          'ckeditor/drupal.ckeditor',
          'ckeditor/drupal.ckeditor.stylescombo.admin',
          'ckeditor/drupal.ckeditor.admin',
          'ckeditor/drupal.ckeditor.plugins.drupalimagecaption',
        ],
      ],
    ];
  }

}

```

Results:

Any suggestions?

Many thanks.

# Answer
A form usually contains all libraries necessary, but you shouldn't render the form at this point in the controller.

Put it unrendered in the template variable

```
return [
  '#theme' => 'customize_user_form',
  '#form' => $form,
];

```

and when you print the form in the template `{{ form }}` the libraries should be attached automatically to the page.
> 1 votes

---
Tags: 8, wysiwyg
---


title: Feeds Importer running multiple times

text:
# Question
Title: Feeds Importer running multiple times
My feeds importer is acting very strange and running the same import multiple times..

This is what my importer looks like:

```
class FeedsASUNewCareer extends FeedsCSVParser {
  /**
   * Implements FeedsParser::parse().
   */
  public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) {
    global $user;
    $source_config = $source->getConfigFor($this);
    $state = $source->state(FEEDS_PARSE);

    // Load and configure parser.
    feeds_include_library('ParserCSV.inc', 'ParserCSV');
    $parser = new ParserCSV();
    $delimiter = $source_config['delimiter'] == 'TAB' ? "\t" : $source_config['delimiter'];
    $parser->setDelimiter($delimiter);

    $iterator = new ParserCSVIterator($fetcher_result->getFilePath());
    if (empty($source_config['no_headers'])) {
      // Get first line and use it for column names, convert them to lower case.
      $header = $this->parseHeader($parser, $iterator);
      if (!$header) {
        watchdog('CAREER IMPORT ERROR', "Could not parse header");
        return;
      }
      $parser->setColumnNames($header);
    }

    // Determine section to parse, parse.
    $start = $state->pointer ? $state->pointer : $parser->lastLinePos();
    $limit = $source->importer->getLimit();
    $rows = $this->parseItems($parser, $iterator, $start, $limit);

    // Report progress.
    $state->total = filesize($fetcher_result->getFilePath());
    $state->pointer = $parser->lastLinePos();
    $progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total;
    $state->progress($state->total, $progress);

    $careers = array();

    watchdog('careers', '<pre>' . print_r($rows, TRUE) . '</pre>');
    foreach($rows as $career) {
        // create career.
        $node = entity_create('node', array('type' => 'careers'));
        $entity = entity_metadata_wrapper('node',$node);
        // Set Entity properties
        $entity->title->set($career['alternate_title']);
        $entity->language = 'en';
        $entity->author = $user->uid;
        $entity->status = $career['status'];
        $entity->body->set(array('value' => $career['body']));
        $entity->field_alternate_title->set($career['alternate_title']);
        $entity->field_career_category_image->set($career['car_category_img']);
        $entity->field_careercategory->set($setCategoryId);

        // Save Career
        $entity->save(); //Save new Entity wrapper
        $node->tnid = $node->nid;
        $entity->save();
      }
    }

    // return empty set.
    $ret = new FeedsParserResult();
    return $ret;
  }
}

```

When I go to `Content > Import` and select this Feed Importer to use, it just gets hung up on the processing page and in my logs I can see my watchdog `watchdog('careers', '<pre>' . print_r($rows, TRUE) . '</pre>');` executes over and over until I stop it. Keep in mind that watchdog is not in a loop, so the feeds importer is just running endlessly until I stop it.

What could cause the importer to act with such behavior?

# Answer
It could be that there's a bug in the parser's reporting progress. As long as the parser doesn't tell Feeds parsing is done, Feeds will keep calling the parser over and over again.

**Workflow of Feeds**

1. Fetch data.
2. Parse 50 first items of data.
3. Process 50 items.
4. Feeds checks if the parser's progress is complete. If not, the next 50 items of data are parsed.
5. Process 50 items.

When there's nothing more to parse, Feeds checks if there's more to fetch. If so, above steps are repeated. If not, import finishes.
> 0 votes

---
Tags: 7, feeds
---


title: Taxonomy term parent widget alternative

text:
# Question
Title: Taxonomy term parent widget alternative
I have a huge hierarchical vocabulary of terms and adding a new child to a specific term can be hard using the default multi-value select list widget.

Can I use an autocomplete widget or -better- an entity browser instead?

# Answer
> 0 votes
Solved myself using Select2 contrib module \+ very little customization in my module:

```
function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if ($form_id == 'taxonomy_term_myvocabulary_form') {
    // Show parent select as select2 (if enabled)
    if (\Drupal::moduleHandler()->moduleExists('select2')) {
      $form['relations']['parent']['#type'] = 'select2';
    }
  }

  return $form;
}

```

This is the result:

Hope this helps someone.

# Answer
> 0 votes
I'm not sure if it would integrate with that widget automatically, but I really like Chosen. Doesn't work on mobile though.

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


# Question
Title: Modify user profile page, not login page
I'm trying to edit the user profile page, not the login page.

However, with Drupal 7, the template for the profile and the login page is the same.

I tried to modify page--user.tpl.php, but it also modifies the login page. And modify user--profile.tpl allow to modify the order of the fields but not the entire page.

Do you know how to do it ?

# Answer
For theming user profile page use `page--user--%.tpl.php` template file.

To see all possible template suggestions right in your code you can enable Theme debug mode in sites/default/settings.php:

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

```
> 0 votes

---
Tags: 7, theming
---