title: json migration to nodes

text:
# Question
Title: json migration to nodes
I have a json file with 572 items. I have created the migration script and it runs ok, except that the end results says

> processed 572 items (1 created, 571 updated)

It looks like instead of creating one node for each item, only one node is created and then overwritten, so that only the last item shows.

I am guessing that I have problems with the `item_selector: nlm` from my json file with starts with

```
{
  "nlm": [
    {RECORD # : .....},
    {RECORD # : .....},
    ...
  ]
}

```

But changing the `item_selector` to anything else gives an error and the script doesn't run.

Any idea of how to get the script to create 572 nodes will be helpful.

Thanks

Edit: my migration script looks like this:

```
langcode: en
status: true
dependencies: {  }
id: importjson3e
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags: null
migration_group: null
label: 'New JSON migration'
source:
  plugin: url
  data_fetcher_plugin: http
  data_parser_plugin: json
  include_raw_data: true
  urls: 'http://example.com/json/nlm_0119.json'
  track_changes: true
  item_selector: 'nlm'
  fields:
    -
      name: year_added
      label: YearAdded
      selector: YearAdded
    -
      name: month_added
      label: MonthAdded
      selector: MonthAdded
    -
      name: record_number
      label: 'RECORD # '
      selector: 'RECORD # '
    -
      name: Title
      label: 'TITLE '
      selector: 'TITLE '

  ids:
    record_number:
      type: text
process:
   type:
     plugin: default_value
     default_value: new_books
  title: Title
  field_year_added: year_added
  field_month_added: month_added
  field_record_number: record_number
destination:
  plugin: 'entity:node'
migration_dependencies: null

```

# Answer
Uncomment your selectors, and your `item_selector` should be:

`nlm/` and not just `nlm`.

I had this same issue when I was setting up a JSON migration and that was the first thing I ran into.
> 1 votes

---
Tags: migrations, 8
---


title: How to alter local tasks menu titles?

text:
# Question
Title: How to alter local tasks menu titles?
How can I override link title in the local tasks menu?

I tried like this, but didn't work:

```
function mymodule_menu_local_tasks_alter(&$data, $route_name) {
  // Override 'Revisions' label menu link
  $data['tabs'][0]['entity.node.version_history']['#link']['localized_options']['attributes']['title'] = t('View history');
}

```

# Answer
> 4 votes
I have had success with

```
$data['tabs'][0]['entity.node.canonical']['#link']['title'] = t('Overview');

```

# Answer
> 3 votes
For Drupal 8, this is what worked for me. I also adjusted the weights so I could re-order the items.

```
/**
 * Implements hook_local_tasks_alter().
 *
 * @inheritdoc
*/
function mymodule_local_tasks_alter(&$local_tasks) {

  $local_tasks['entity.user.canonical']['title'] = 'Account Details';
  $local_tasks['entity.user.canonical']['weight'] = -3;

  $local_tasks['entity.user.edit_form']['title'] = 'Edit Account';
  $local_tasks['entity.user.edit_form']['weight'] = -2;

}

```

---
Tags: 8, hooks
---


# Question
Title: Modify article body for one particular article to add data
How do I modify an article's body field before the end user sees it for one particular article?

Background: Currently the content editors are updating this data manually twice per week. We want to automatically update it every 8 hours with a cron job instead. We will get data from an external source, it comes to us in JSON format. We process the data into a render array.

When I'm ready to see some output on the page, how do I put it there?

# Answer
I ended up modifying the node when cron runs.

```
define("JMT_CLASSES_CLASSES_ED_NODE_ID", 574);
// 60 * 60 * 8 - measured in seconds.
define("JMT_CLASSES_EIGHT_HOURS", 28800);

/**
 * Implements hook_cron().
 */
function jmt_classes_cron() {
  // Check current config for time, if greater than 8hrs check for updates.
  $timeOfLastUpdate = \Drupal::configFactory()
    ->get('jmt_classes.settings')
    ->get('last_run');
  $currentTime = \Drupal::time()
    ->getCurrentTime();
  $intervalSinceLastUpdate = $currentTime - $timeOfLastUpdate;

  if ($intervalSinceLastUpdate >= JMT_CLASSES_EIGHT_HOURS || $timeOfLastUpdate == NULL) {
    // Check for updates.
    $raw = jmt_classes_get_classes('https://example.com/Client.WebApi/api/Route?url=query/get?url=jmt');
    if ($raw) {
      $newBodyValueHtml = jmt_classes_render_html($raw);
      $classesEdNode = Node::load(JMT_CLASSES_CLASSES_ED_NODE_ID);
      jmt_classes_update_class_node($classesEdNode, $newBodyValueHtml);

      \Drupal::configFactory()->getEditable('jmt_classes.settings')
        ->set('last_run', $currentTime)
        ->save();
    }
  }
}

/**
 * Update node with new html for the body field and log that it was updated.
 *
 * @param string $node
 *   The node (output page) that should be updated with new data.
 * @param string $newBodyValueHtml
 *   The HTML to set the body to.
 */
function jmt_classes_update_class_node($node, $newBodyValueHtml) {
  $node->body->value = $newBodyValueHtml;
  $node->save();
  \Drupal::logger('jmt_classes')->notice("Successfully updated body field of articles/upcoming-education-classes-field-days");
}

/**
 * Get raw json output for JMT classes. Log error or success.
 *
 * @param string $uri
 *   JMT api uri: should be something like:
 *   'https://example.com/Client.WebApi/api/Route?url=query/get?url=jmt'.
 *
 * @return string
 *   Raw json data or empty if nothing returned from request.
 *
 * @throws \GuzzleHttp\Exception\GuzzleException
 */
function jmt_classes_get_classes($uri) {

  try {
    $response = \Drupal::httpClient()->request('GET', $uri, ['timeout' => 120]);
  }
  catch (Exception $e) {
    \Drupal::logger('jmt_classes')->error("Attempted to get data
from $uri but failed. $php_errormsg");
    return '';
  }

  $data = (string) $response->getBody();
  $data_array = json_decode($data);

  // If this isn't json data return nothing.
  if (empty($data_array)) {
    return '';
  }
  // Otherwise, return raw json data.
  else {
    \Drupal::logger('jmt_classes')->notice("Successfully got data from $uri");
    return $data;
  }
}

```

This has the advantage that I don't do any preprocessing. The change happens when the data changes when cron runs, not on every page load. This is important because fetching the data is SLOW!
> 1 votes

---
Tags: 8, nodes
---


title: How to add strip tags in drupal 8?

text:
# Question
Title: How to add strip tags in drupal 8?
How to add strip tag in field template i am using ckeditor in my content type because of using it its automatically inserting p tags in Text.

Here is mine field template code

```
         {% for item in items %}
     <div{{ attributes.addClass(classes, 'field--item') }}>{{ item.content }}</div>
{% endfor %}

```

I was trying something like this for adding strip tags

```
{% for item in items %}
{% set conBody %}
 {{ item.content }}
 {% endset %}

{{ conBody|striptags }}

 <div{{ attributes.addClass(classes, 'field--item') }}>{{ conBody  }}</div>
{% endfor %}

```

**Only indexed value(conBody\[0\]) field tags are stripped(p tags removed) but remaining indexed value fields are remaining same not affected.**

How could i use above code in loop.

# Answer
> 2 votes
I ran across this today and figured I would circle back and provide an answer that worked for me.

```
{% for item in items %}
    {% set conBody %}
        {{ item.content }}
    {% endset %}
<div class="myClass">{{ conBody|striptags }}</div>
{% endfor %}

```

---
Tags: 8
---


# Question
Title: Drush Feature Update removing t() and l() function usages
I have a feature that currently has things like this:

```
'body' => '<h3>' . t('Welcome back') . '<span class="fname">%user:field_first_name</span>!</h3>',

```

However, using `drush fu myfeature` generates this:

```
'body' => '<h3>Welcome back<span class="fname">%user:field_first_name</span>!</h3>',

```

Why is this happening? (removal of t() and l() functions).

I did not create this original feature.

# Answer
> 0 votes
Isn't this a simple as the PHP code being executed? The original feature is created so it supports any language by translating text with the "t" function. However, when the feature is activated, just the text - the executed PHP code - is written to the database (for the given langauge), and you can't ever get back the original PHP code. A feature update will just return the string in the database.

---
Tags: 7, drush, features
---


# Question
Title: How to print an entity bundle field from one with multiple values
Struggling to find the answer to this. I have an entity called "school objects" which has a bundle called "homepage". One of the fields attached to this is called "Hero banners" and it allows multiple text values.

All I want to do is print each value. I don't need to check for conditions, I don't need NIDs, I just want each value. I am not really a php developer but understand the basics of what it is doing. I was looking into the `EntityFieldQuery` code, but cannot get anything to print on a tpl file I am using.

The output I need, based on image attached, is simply:

```
<div class="value_1">images/symbol.png</div>
<div class="value_2">Let's make a difference</div>
<div class="value_3">Start today</div>

```

All I can find after a lot of searching is complex bits of code checking for conditions and stuff that I do not need. I need some kind of array I think so that my template looks like:

```
<div class="value_1">Value[0]</div>
<div class="value_2">Value[1]</div>
<div class="value_3">Value[2]</div>

```

All I got so far is this:

```
query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'school_objects')
  ->entityCondition('bundle', 'homepage')
  ->range(0, 14);
$result = $query->execute();

```

I have read the link to this on the Drupal site but cannot understand it or how to print what I need.

# Answer
Try the following and load the actual entity to get its field values.

The code assumes you have drupals entityTypeManager injected via dependency injection. Otherwise use `\Drupal::entityTypeManager()` isntead of `$this->entityTypeManager()`

```
// Get the entity ids.
$entityIds = $this->entityTypeManager()->getStorage('school_objects')->getQuery()
  ->condition('type', 'homepage')
  // Add more conditions if you need.
  ->execute();
// I assume only one id is returned and reset the array. Otherwise go over
// each Id with a foreach() and do this in a loop.
$entityId = reset($entityIds);
$schoolObject = $this->entityTypeManager()->getStorage('school_objects')->load($entityId);
// Now get the values of your field. I assume the fields machine_name is 'field_hero_banners'. Adjust if needed.
$values = $schoolObject->get('field_hero_banners')->getValue()
// Loop over all values.
foreach ($values as $item) {
  $value = $item['value'];
}

```
> 0 votes

# Answer
```
<?php
$wrapper = entity_metadata_wrapper('school_objects', '353', array('bundle' => 'homepage'));
$homepage_hero_banners = $wrapper->field_hero_banners->value();
?>
<p><?php echo $homepage_hero_banners[1]; ?></p>
<p><?php echo $homepage_hero_banners[2]; ?></p>

```

It has taken 4 days for me to get this code. I truly hope this helps someone else!
> 0 votes

---
Tags: entities
---


# Question
Title: Calculate Database Field Value and Send to Views as New Field
I have a database field which stores a timestamp. This timestamp is sent to a custom views provider via `hook_views_data()`. This timestamp field is created as a date field to utilize the date format options from views.

```
$data['module']['timestamp'] = [
  'title' => t('Timestamp'),
  'help' => t('Timestamp from module'),
  'field' => [
    'id' => 'date',
  ],
  'sort' => [
    'id' => 'date',
  ],
  'filter' => [
    'id' => 'date',
  ],
];

```

---

In another views field (but with the same DB field), I would like to get the raw field value and run it through something like:

```
if (field_value > (time() - 800))

```

---

This is a custom module and would prefer not to have any more dependencies. Can this be achieved with `hook_views_data()` or `hook_views_pre_render()` or such?

I know there is a contributed module https://www.drupal.org/project/computed\_field, but again hoping there is a way in those hooks, or in the view...

The DB table is created with `hook_install()` and the desired timestamp field output after check would be markup. Happy if it is just sent as markup to the views field.

---

I've figured how to access the field values with `hook_views_pre_render()` as such:

```
function hook_views_pre_render(&$view) {
  $result = $view->result;
  foreach ($result as $key => $row) {
    kpr($result[$key]->field_name);
    if ($result[$key]->timestamp > (time() - 800)) {
      // Can I do anything here?
    }
    else {
      //
    }
  }
}

```

Unfortunately, that is not the most important piece of the puzzle. And it is not possible to just add `$data['module']['key']` to my `hook_views_data()` as this requires the unique DB field to exist.

In my use case, I'd be happy if I could rewrite the original timestamp field and append this markup to it.

# Answer
> 1 votes
Take a look at this, it shows how you can create custom fields that you can use within views https://www.webomelette.com/creating-custom-views-field-drupal-8

I've followed this recently and seems to work well

---
Tags: views, 8
---


# Question
Title: Save paragraph widget data in custom form
I am adding a node field widget in a custom form as described here and my code is:

```
$site_settings_node = Node::load($node_id);
$entity_form_display = \Drupal::service('entity_type.manager')->getStorage('entity_form_display')
  ->load('node.node_type.default');
if ($widget = $entity_form_display->getRenderer('field_my_field')) {
  $items = $site_settings_node->get('field_my_field');
  $items->filterEmptyItems();
  $form['#parents'] = array();
  $form['custom_form_field'] = $widget->form($items, $form, $form_state);
}

```

How do I update the paragraph field values in my submit handler? Is there something like the below that I can do?

```
$widget = $entity_form_display->getRenderer('field_my_field')
$widget->submit($items, $form, $form_state);

```

# Answer
I found the solution via this article. Though for the solution to work specifically for the paragraph field, I had to add a patch for an issue discussed here.

```
public function buildForm(array $form, FormStateInterface $form_state) {
  $form['#parents'] = array();

  $node_id = 1; // Some node
  $entity = Node::load($node_id);
  $form_state->set('entity', $entity);

  /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
  $form_display = \Drupal::service('entity_type.manager')->getStorage('entity_form_display')->load('node.node_type.default');
  $form_state->set('form_display', $form_display);

  foreach ($form_display->getComponents() as $name => $component) {
    $widget = $form_display->getRenderer($name);
    if (!$widget) {
      continue;
    }
    $items = $entity->get($name);
    $items->filterEmptyItems();
    $form[$name] = $widget->form($items, $form, $form_state);
    $form[$name]['#access'] = $items->access('edit');
    $form[$name]['#weight'] = $component['weight'];
  }

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'submit',
  );
  return $form;
}

public function submitForm(array &$form, FormStateInterface $form_state) {
  /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
  $form_display = $form_state->get('form_display');
  $entity = $form_state->get('entity');
  $form_display->extractFormValues($entity, $form, $form_state);
  $entity->save();
}

```
> 0 votes

---
Tags: forms
---


# Question
Title: how to change h2 tag for div in block_view
I've created a block like this

```
function mymodule_block_view($delta = '') {
    if($delta == 'myblock') {
        $block['subject'] = 'mytitle';
        $block['content'] = myfunction();
    }
    return $block;
}

```

but the output is like this:

```
<h2 class="block-title">mytitle</h2>

```

I need change `h2` to `div`

```
<div class="block-title">mytitle</div>

```

I've tried with `_preprocess_block` hook but i cant change that tag

could you please help me?

# Answer
> 0 votes
try with the following:

1. Implement `hook_theme_registry_alter` to take the templates from your module.

```

/**
 *  Implements hook_theme_registry_alter().
 */
function mymodule_theme_registry_alter(&$theme_registry) {
  // Defined path to the current module.
  $module_path = drupal_get_path('module', 'mymodule') . "/templates";
  // Find all .tpl.php files in this module's folder recursively.
  $template_file_objects = drupal_find_theme_templates($theme_registry, '.tpl.php', $module_path);
  // Iterate through all found template file objects.
  //test if this page isn't in BO page
  if (!path_is_admin(current_path())) {
    foreach ($template_file_objects as $key => $template_file_object) {
      // If the template has not already been overridden by a theme.
      if (!isset($theme_registry[$key]['theme path']) || !preg_match('#/themes/#', $theme_registry[$key]['theme path'])) {
        // Alter the theme path and template elements.
        $theme_registry[$key]['theme path'] = $module_path;
        $theme_registry[$key] = array_merge($theme_registry[$key], $template_file_object);
        $theme_registry[$key]['type'] = 'module';
      }
    }
  }
}

```
2. Copy `modules/block/block.tpl.php` and past it in `templates` folder of your module.
3. Rename it from `block.tpl.php` to `block--mymodule--myblock.tpl.php` to change only for your block.
4. Change the line from `<h2<?php print $title_attributes; ?>><?php print $block->subject ?></h2>` to `<div<?php print $title_attributes; ?>><?php print $block->subject ?></div>`
5. Clear cache.

---
Tags: blocks, hooks
---


# Question
Title: Is there a way to use grouping settings for Bootstrap Tabs in Views?
Is there a way to use grouping settings for Bootstrap Tabs in Views?

# Answer
> 2 votes
There isn't a way at the moment to use the built in views group by function, but luckily there is a way to accomplish similar behavior if you install a contrib module called views field view.

https://www.drupal.org/project/views\_field\_view

The premise being, tabs separate a listing of entities into multiple groups based on a common term.

Not like this: https://monosnap.com/file/K4W6m63A1jsy7frYdL8P0LfcFQPj29

But like this: https://monosnap.com/file/Q8WsRSgJU7f8AYFMMomDmcIjyOAXZE

In order to make this work, you need two views, One with the tab output, and another contextually filtered as a field within the first.

View 1 (list of taxonomy terms) would look like this to create the labels for the tabs: https://monosnap.com/file/h3fDlfgy2HwlHT2Y3Lywe8IroagDyE

View 2 (Use a relationship to call the nodes that are referencing each term and a contexual filter to limit the nodes per term id): The view field here is the key: https://monosnap.com/file/NtIumKYmsws62o4kTAnU72mt1LPZZq

Once you have the two views you can set the argument on view 1 The view field here is the key: https://monosnap.com/file/EzgRlcjLgr0au7TIWnTLbWEosCHwcP

# Answer
> 1 votes
Unfortunately my reputation is too low to comment on Chris' answer; however, there is one important piece missing that took me awhile to figure out is that in order to have your tabs show only the unique taxonomy terms as shown in his "not like this / but like this" photos, you'll need to set "Use aggregation" on the "View 1" view to Yes.

Also, I have to disagree with Antonio's comment - I did find that the Relationship (which in Drupal 7.63 is called "Content: Taxonomy terms on node") was necessary on both views.

---
Tags: 7, views, routes, theming
---


# Question
Title: setContainer Error When Registering an EventSubscriber Service
I am trying to create a basic event subscriber, but when I add the services.yml file and attempt to rebuild the cache with `drush cr`, I get this error.

> In Drupal.php line 130:
>
> `\Drupal::$container` is not initialized yet. `\Drupal::setContainer()` must be called with a real container.

If I clear the cache from Drupal, it works fine, but Drush always errors out. If I remove the services file, Drush works fine again.

Has anyone seen this before? I don't want to move forward without resolving this. I have added services and event subscribers in this project before without an issue. I double checked spacing structure, etc.

### module/gary\_custom.services.yml

```
services:
  gary_custom.custom_event_subscriber:
    class: Drupal\gary_custom\EventSubscriber\CustomEventSubscriber
    tags:
      - { name: event_subscriber }

```

### module/src/EventSubscriber/CustomEventSubscriber.php

```
namespace Drupal\gary_custom\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;

class CustomEventSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    \Drupal::logger('debug')->debug('get sub events');

    $events[KernelEvents::REQUEST][] = array('checkForRedirection');
    return $events;
  }

  /**
   * This method is called whenever the KernelEvents::REQUEST event is
   * dispatched.
   *
   * @param GetResponseEvent $event
   */
  public function checkForRedirection(GetResponseEvent $event) {
    \Drupal::logger('debug')->debug('hitting');
  }
}

```

I am using Drush 9.4.0.

# Answer
The problem is the logging line in `getSubscribedEvents`:

```
\Drupal::logger('debug')->debug('get sub events');

```

`Drupal::logger` queries the container for a service, but the container hasn't been set at the point the event subscriber discovery happens.

By the time the event handler is invoked, the container has been initialised, so the logging in `checkForRedirection` should work fine.
> 1 votes

---
Tags: 8, drush, event-subscribers
---


title: View all subscribed events?

text:
# Question
Title: View all subscribed events?
I have a feature where if a user navigates to a specific url (`www.mysite.com/special-content`) they are redirected to the login page, where we've appended a destination to the request (`www.mysite.com/user/login?destination=special-content`).

We created a custom module using a `checkAuthStatus` event subscriber to detect anonymous users and redirect them appropriately:

```
$ cat src/EventSubscriber/RedirectAnonymousSubscriber.php
<?php

namespace Drupal\anon_redirect\EventSubscriber;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Event subscriber subscribing to KernelEvents::REQUEST.
 */
class RedirectAnonymousSubscriber implements EventSubscriberInterface {

  public function __construct() {
    $this->account = \Drupal::currentUser();
  }

  public function checkAuthStatus(GetResponseEvent $event) {
    $paths = [
      '/special-content',
      '/more-special-content'
    ];

    if ($this->account->isAnonymous()) {
      foreach ( $paths as $path ) {
        if ( substr($_SERVER['REQUEST_URI'], 0, strlen($path)) === $path ) {
          $url = \Drupal\Core\Url::fromUri('internal:/user/login',[
            'query'=>['destination'=>$_SERVER['REQUEST_URI']],
          ]);
          $response = new RedirectResponse('/user/login?destination='.$_SERVER['REQUEST_URI'], 302);
          $response->send();
          return;
        }
      }
    }

  }

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

```

This has been working fine for a few months, but recently I got complains that people were not getting redirected. Upon investigation, I saw that they were getting 'access denied', as evidenced by the watchdog log. That is, when they are not logged in, they see our 301 page, instead of getting redirected.

Frustratingly, I've only been able to intermittently reproduce this problem. Sometimes I get the 301 page, sometimes I get the login page with the proper redirect query appended. I've tried both Firefox and Chrome, private sessions, clearing cookies, etc.

I suspect that whatever decides access also is listening to `checkAuthStatus` and *sometimes* having the final word about what page is ultimately sent to the end-user, and our module's behavior is not implemented, while other times, our event listener is invoked.

My question is if there is any way I can see what event listeners are subscribed to the `checkAuthStatus` event, and ideally, which one is having the final word as to the ultimate response from Drupal. I suspect another one is somehow getting prioritized over mine, and would like to confirm or deny that theory.

# Answer
> 5 votes
In the above code example the event is `KernelEvents::Request` and `checkAuthStatus` is the method called when the Request event is dispatched.

You can use Drupal Console `debug:event` command to list all subscribers for a given event:

`vendor/bin/drupal debug:event kernel.request`

And that will give you something like:

```
  Drupal\Core\EventSubscriber\OptionsRequestSubscriber                   onRequest: 1000
  Drupal\Core\EventSubscriber\RedirectLeadingSlashesSubscriber           redirect: 1000
  Drupal\Core\EventSubscriber\AuthenticationSubscriber                   onKernelRequestAuthenticate: 300
  Drupal\language\EventSubscriber\LanguageRequestSubscriber              onKernelRequestLanguage: 255
  Drupal\Core\EventSubscriber\RedirectResponseSubscriber                 sanitizeDestination: 100
  Drupal\Core\EventSubscriber\AjaxResponseSubscriber                     onRequest: 50
  Symfony\Component\HttpKernel\EventListener\RouterListener              onKernelRequest: 32
  Drupal\Core\EventSubscriber\AuthenticationSubscriber                   onKernelRequestFilterProvider: 31
  Drupal\user\EventSubscriber\MaintenanceModeSubscriber                  onKernelRequestMaintenance: 31
  Drupal\Core\EventSubscriber\MaintenanceModeSubscriber                  onKernelRequestMaintenance: 30
  Drupal\Core\Routing\RoutePreloader                                     onRequest: 0
  Drupal\Core\EventSubscriber\ReplicaDatabaseIgnoreSubscriber            checkReplicaServer: 0

```

If you use Drush and have the `devel` module installed, you can do:

```
vendor/bin/drush devel-event kernel.request

```

# Answer
> 1 votes
You can get a list of the subscribers to a particular event, sorted in order of priority, using the event dispatcher service:

```
$subscribers = \Drupal::service('event_dispatcher')
  ->getListeners(\Symfony\Component\HttpKernel\KernelEvents::REQUEST);

```

---
Tags: event-subscribers
---


# Question
Title: How to migrate content of one content type to another content type
I have two content types. `Content type A` and `Content type B`

I have some nodes of `content type A` and want to migrate them to `content type B` but the content of type A should remains in the system.

I have tried the node\_convert module but it simply changes the node type of the existing content as the node ids remains the same.

Is there any other module or some hint to move into a custom solution?

# Answer
> 1 votes
You can use Feeds module or Migrate module. First you export the Type A into a CSV for example, then build an importer that imports data into the Type B and use the exported CSV file.

Be careful you choose the correct bundle for the importer (Type B) and to create new nodes. Check that your Unique field really is unique.

---
Tags: 7
---


# Question
Title: How can I update the values of an exposed view filter when another filter changes value?
I know there are several examples of this around, on a view with two exposed select list filters, I need to update the value of the second based on the value selected on the first. I can't even seem to get any debugging info on my callback, but the request is throwing a `Drupal\Core\Form\Exception\BrokenPostRequestException`. Here's the simple form alter I'm trying.

```
use Drupal\Core\Form\FormStateInterface;

function MODULENAME_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if($form_id == "views_exposed_form"){
    $form['field_article_value1_value']['#options']  = _MODULENAME_get_update_value1_values();
    $form['field_article_value2_value']['#options']  = _MODULENAME_get_value2_values();

    $form['field_article_value1_value']['#ajax'] = [
     'callback' => ['_MODULENAME_get_value2_values_ajax_callback'],
     'event' => 'change',
     'wrapper' => 'edit-field-article-value-wrapper',
     'progress' => [
     'type' => 'throbber',
     'message' => NULL,
     ],
  ];
}

function _MODULENAME_get_value2_values_ajax_callback(array &$form, FormStateInterface $form_state) : array {
  $markup = '<h1>Testing!</h1>';
  return ['#markup' => $markup];
}

```

# Answer
> 0 votes
This module might help: Views Dependent Filters

If you really want a custom solution take a peek at the code there and see if it helps, or help the D8 version get released :)

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


title: Sort criteria by year for blog posts

text:
# Question
Title: Sort criteria by year for blog posts
I have a View set up for blog post content in Drupal 8. The blog posts were all posted at the same time but have different "year" tags attached to them based on when the post is relevant to the company, and I am trying to sort them starting with most recent year (2019 to 2014. I can't seem to get them to filter in the correct order based on the tags.

These are the steps I have already taken:

1. Added a relationship with "Taxonomy: Terms on node". Selected the tags vocabulary.

2. Added a sort criteria for taxonomy term - year (which is in the tags)

3. Tagged all blog posts with the correct year (ranging from 2014-2019)

But the posts are still in a completely random order. Am I missing a step somewhere?

# Answer
> 0 votes
You don't need a Relationship to add the Tags sort (use the actual Tags field reference, not the generic "Terms on node").

But this way the results will be sorted by TID, not by term names. If your tags have been added chronologically then their TIDs will also be chronological and you can use this sort criteria (it doesn't matter if asc. or desc.).

---

But if your TIDs for years terms are mixed up you have to sort by term name. This is an alphabetical sort, *not* a numerical sort, but luckily it will work correctly in your "years" case.

To do that you have to:

1. Add the Relationship for your tags field, you can require it since you only want nodes that have the years tag to appear
2. Add Sort criteria **Name** from the `Taxonomy term` Category (it will automatically use the Relationship from above)

Now your results will be sorted by **text** 2015, 2016 etc.

---
Tags: views, taxonomy-terms
---


# Question
Title: SSESS Cookie (Session ID) is being changed when loading images that don't exist
I have a Drupal 8.6.10 site which has a very confusing logout bug:

* I have a page that has various elements on it as images, js, css and so on.
* I load that page and everything works fine
* I add an image to that page
* I load the page again, everything fine, also the image is showing.
* *I delete the source image and the image style derivatives of that image*
* I reload the page -\> **I get logged out**!

I can see on the call to the image (which returns a 404 because the image is not existing), the value of the SSESS Session cookie is changed (so the session ID) thus I'm losing the connection to my session and get logged out.

I have already proven that this happens inside the execution of PHP and has nothing to do with varnish (logging at the very end of index.php, before the answer gets sent, shows already the changed session id using `session_id()` ).

I have a parallel installation which is still on Drupal 8.3.7, and which contains various fixes of this issue: https://www.drupal.org/node/2743931 When I remove the fixes for the issue, the bug does no more appear.

However after the update to 8.6.10, I removed all the fixes because the issue has been fixed in core, and despite the fixes being removed, the logout bug still appears.

How can the session id even be changed? Calling `session_start()` a second time does not work and `session_regenerate_id` (the only one in the symfony core) is never called.

Please help me on this one, as I'm currently at the end of my latin. Thanks!

# Answer
> 2 votes
I finally found out what was the exact problem in my case:

* I had varnish which per default, strips all cookies from the request to images. So when an image style is called, the request won't get any cookies and is thus an anonymous request.
* The image is not present, so PHP is called to generate it.
* A custom module invokes code that includes private tempstore (via Event listener but could also be `hook_init()` or something similar).
* The SessionStorage is not aware that there was already a session because varnish stripped the cookie away. It therefore just started a new session (with the same cookie name but with another value). That was the return cookie.

At least it's solved now. An alternate way could also be that varnish could also filter all returned cookies, but this has to be configured / coded in the varnish config.

---
Tags: 8, sessions, cookies
---


title: How do I integrate Google Adsense?

text:
# Question
Title: How do I integrate Google Adsense?
How do I integrate Google Adsense? I have installed the Google Adsense module but when I insert the publisher ID, it says I have to insert an ID similar to pub-9999999999999, but Google gave me an ID similar to ca-pub-9999999999999.

Is there a way to resolve this?

# Answer
In the issue queue of the Google AdSense integration module your problem is reported: Support current CSE code

You could try to create a patch using the suggested information, test it and report back in the issue queue.
> 1 votes

---
Tags: advertising
---


# Question
Title: Disable (Close) webform form dynamically
We would like to be able to put our site into a "read-only" mode prior to doing major releases etc. I was hoping to achieve this for forms on the site by enabling or disabling my custom module, which I could easily do from drush during our release process.

The module would use a hook to disable all forms and show the closed message instead.

This is what I had so far:

```
<?php

use Drupal\Core\Form\FormStateInterface;

/**
 * Implementation of hook_form_alter().
 *
 * Disables any webforms when this module is active. Include a custom config key
 * called `exempt_from_maintenance_mode` with any value to allow your form to
 * remain open during maintenance.
 *
 * E.g.
 *     exempt_from_maintenance_mode: 1
 *
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
function yvw_maintenance_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
    // Check for custom config key
    if (array_key_exists('#exempt_from_maintenance_mode', $form)) {
        return;
    }

    // Load the webform entity. This should prevent the module from disabling
    // all forms across the site.
    $webform_id = $form['#webform_id'];
    $webform = \Drupal::entityTypeManager()->getStorage('webform')->load($webform_id);

    // Only disable the webform if its currently enabled
    if ($webform->status() === true) {
        $webform->setStatus('closed');
        // Does not save. Maybe we need a different hook.
    }
}

```

The problem is I would need to call $webform-\>save(); which would permanently close the form. I was hoping there was a hook where I could modify the form configuration only at runtime, and not persist any of the changes to the database. But I haven't been able to find any hooks that look like they would do it.

I had a look at Close a webform when total seats reach a maximum which is close to what I want, but it appears that would only run on submission, and also permanently closes the form.

# Answer
> 2 votes
Webforms are config entities and you can use hook\_webform\_load() to close the webform before it is rendered and then altered. Instead of closing and resaving the webform, you can call `$webform->setPropertyOverride('status', FALSE);` which will safely close the webform and prevent it from being permanently closed.

---
Tags: webforms
---


title: Unable to add field on a view

text:
# Question
Title: Unable to add field on a view
**I am copying this question from https://stackoverflow.com/questions/25900553/unable-to-add-field-on-drupal-7-view as I can't see a move option sorry.**

This has been driving me crazy, so let me explain why.

I am building a Drupal 7 site using kickstart commerce, I have been adding fields to the view for checkout, cart and orders fine.

But all of a sudden it seems to do nothing. Let me explain further.

In the edit view page, I click on Add to add the field I want.

I then find the field I want to add and then click on 'Add and Configure fields'

Then normally I would be able to configure the field, however that has now stopped. Instead I just get the loading symbol and then nothing no configure pop-up or the field added.

I dont understand why this suddenly stopped working, I have cleared the cache and disabled non-required modules, no luck. The fields are configured/added in the same way apart from being different the method they were created in was the same, I have deleted the fields and re-created them still no luck.

Has anyone had this with Drupal 7 or can give me some indication which direction to go in next, thanks in advance.

---

As I stated on the stack overflow question, its not a relationship things as fields configured the same way are able to be added. Existing fields can be removed and added ok.

If I rename to something like test it still fails to add.

I have checked modules that were installed after i noticed the issue, the only one i could see was context disabling this had no effect.

All out of ideas, Google has been no help either :-(

---

A further update to my question I just updated to the latest commerce kickstart(commerce\_kickstart-7.x-2.17) and this did not help at all. The issue still remains.

# Answer
> 1 votes
I have run into this issue repeatedly and often the only way I have been able to add the missing field/relationship is to export the view, add the new field/relationship in a text editor, and then re-import the view.

# Answer
> 0 votes
I have faced a similar problem on my hosting environment and found out that disabling SUHOSIN php extension solved it.

Do you SUHOSIN on yours?

# Answer
> 0 votes
Renaming the field to a shorter name with this module solved the problem for me.

# Answer
> 0 votes
This has happened to me before.

I've solved the issue using shorter field names (It seems that long field names don't work as expected)

---
Tags: views, commerce
---


# Question
Title: Best way to insert video (vimeo and youtube) into content
What is the best way to embed videos into content? Often it's not ideal just to have video content at the beginning or end end of page content. More often then not it something like \[text\] \[video\] \[text\]

I'm looking at the best way to insert video content into a page while keeping a video content type field. I also want to avoid just adding video embed code into the full html body editor as then it's impossible to use the video in other places.

How do I go about adding a view field and then have a 'placeholder' for which to render the video in the middle of the text content?

# Answer
> 5 votes
The easiest way by far, is to use video embed field. I have built a video sharing site with a co-worker that generates very high rates of traffic. He built the site mostly by himself 80% in a couple of days, and the video embed module was used heavily for the management of video content types.

# Answer
> 3 votes
I am using Video Embed Field which is specifically made for this purpose. I've used it to embed Youtube videos so far, but I'm sure it works for Vimeo as well.

# Answer
> 2 votes
Media and its associated modules (Media Wysiwyg etc) is supposed to do that, but it still has issues.

Your best bet is Scald, as it allows for a library that you keep and you can drag and drop from that library into text fields that you predesignate to accept media atoms. You can do that with all media. It also has an Atom reference field allowing you to reference Media from any drupal entity the way nodereference or entityreference do. And there is a series of tutorials by the developers on Youtube.

# Answer
> 0 votes
Drupal 8.6+ now has integrated Media Library with Images and Video support.

Video Embed Field plugs into the video type as well if you wish to still use it.

Use the core Media library with Entity Browser, it works great once the setup is complete!

---
Tags: wysiwyg, files
---


# Question
Title: Show content type teaser only if posts available for the content type
I'm displaying a content type teaser view on the front page using Twig Tweak. But I want to show it only if there are posts available. Something like

```
{% if content type has posts %}
  <h1>Upcoming Events</h1>
  {{ drupal_view('home_upcoming_event_teaser') }}
{% endif %}

```

How can I achieve this in a Twig Template?

# Answer
You can use `drupal_view_result` to check if your view has result:

From Cheat sheet

> {# This might be useful to check if a view returns nothing. #}
>
> View results: {{ drupal\_view\_result('who\_s\_new', 'block\_1') }}

Your code will be something like:

```
{% if drupal_view_result('home_upcoming_event_teaser') is not empty %}
  <h1>Upcoming Events</h1>
  {{ drupal_view('home_upcoming_event_teaser') }}
{% endif %}

```
> 1 votes

---
Tags: 8, theming, nodes
---


title: Get default value of a node field

text:
# Question
Title: Get default value of a node field
I have a field on a node which has a default value set, I need to access the default value of that field. But, I don't want to load any nodes of that type and access the field definitions, nor do I want to manually write a `db_query` and fetch the value directly from the db, I know there is a proper way to do it I just don't know of it.

Drupal 8.6.x

# Answer
> 5 votes
Use FieldDefinitionInterface::getDefaultValueLiteral:

```
$definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'page');
if (isset($definitions['field_example'])) {
  $default_value = $definitions['field_example']->getDefaultValueLiteral();
}

```

---
Tags: database
---


title: How to change view REST export format

text:
# Question
Title: How to change view REST export format
This is my settings in view.

Data what I have is now in this format:

```
[{"created":"1551709414","field_iot_integer":"43"},
{"created":"1551709404","field_iot_integer":"98"},
{"created":"1551709392","field_iot_integer":"58"},
{"created":"1551709382","field_iot_integer":"4"},
{"created":"1551709373","field_iot_integer":"65"},
{"created":"1551709356","field_iot_integer":"23"}]

```

I would like to change this format in this, rid of all comments. :

```
[[1551709414,43],
[1551709404,98],
[1551709392,58],
[1551709382,4],
[1551709373,65],
[1551709356,23]]

```

How I can achieve this?

# Answer
> 11 votes
To change the structure of the `Serializer` output you should create a custom `Serializer` here is the steps of your use case:

1. Create `CustomSerializer` extends the `Drupal\rest\Plugin\views\style\Serializer` and update the `render` method to your needs.
    * Create `MY_MODULE/Plugin/views/style/CustomSerializer.php`

```

namespace Drupal\MY_MODULE\Plugin\views\style;

use Drupal\rest\Plugin\views\style\Serializer;

/**
 * The style plugin for serialized output formats.
 *
 * @ingroup views_style_plugins
 *
 * @ViewsStyle(
 *   id = "custom_serializer",
 *   title = @Translation("Custom serializer"),
 *   help = @Translation("Serializes views row data using the Serializer
 *   component."), display_types = {"data"}
 * )
 */
class CustomSerializer extends Serializer {

  /**
   * {@inheritdoc}
   */
  public function render() {
    $rows = [];
    // If the Data Entity row plugin is used, this will be an array of entities
    // which will pass through Serializer to one of the registered Normalizers,
    // which will transform it to arrays/scalars. If the Data field row plugin
    // is used, $rows will not contain objects and will pass directly to the
    // Encoder.
    foreach ($this->view->result as $row_index => $row) {
      $this->view->row_index = $row_index;
      $row_render = $this->view->rowPlugin->render($row);
      $iot_integer = 0;
      if (isset($row_render["field_iot_integer"]) && $row_render["field_iot_integer"] instanceof \Drupal\Core\Render\Markup){
        $iot_integer = (int) $row_render["field_iot_integer"]->__toString();
      }
     $rows[] = [
        $row_render["created"]->__toString(),
       $iot_integer
      ];
    }
    unset($this->view->row_index);

    // Get the content type configured in the display or fallback to the
    // default.
    if ((empty($this->view->live_preview))) {
      $content_type = $this->displayHandler->getContentType();
    }
    else {
      $content_type = !empty($this->options['formats']) ? reset($this->options['formats']) : 'json';
    }
    return $this->serializer->serialize($rows, $content_type, ['views_style_plugin' => $this]);
  }
}

```
2. Clear Cache:
3. Go to your view and change the format from `Serializer` to `Custom serializer` like
4. The result:

---
Tags: views, 8
---


# Question
Title: Search API - Acquia Search - Keyword Search
I'm using Acquia Search for searching within certain content types (articles, posts, etc). It seems to work for certain keywords but not others. For example, if I search: "Apple TV", I'm expecting the article title: "Spectrum Launches on Apple TV, Offers Apple TV 4K to Customers" to show up (which it does). However, if I search for "4K" the search API brings back "no results".

I reviewed our Acquia connector set up, re-indexed all content and tried with no success. The weird thing is, if I search "4K to customers" it shows the correct article with "4K" also being highlighted (in search results). Does any one have any idea why this would happen? It seems that our config is set up to read basically every field in each content type included and it does seem that this article is indexed. Does anyone have an idea to point me in the right direction?

I'm using the latest versions of Acquia connector, acquia search, search API and Drupal 8.

# Answer
> 0 votes
Set your Minimum keyword length to 2 in the filter criteria of your search-view

---
Tags: views, search
---


# Question
Title: Where is the configuration file for my custom plugins?
In my development environment, I create my first plugins that uses REST with a GET method. I use Rest UI to declare my plugins directly inside Drupal.

All is ok, the request sends me the json result as expected.

But, from here, my questions are :

* Rest UI avoid to declare manually a config file. Great. But after using Rest UI I'm not able to find the config file, where is the configuration saved ?
* In production, must I install Rest UI too, and re-configure my plugin ? Or is it possible to just copy/paste a configuration file ?

# Answer
For configuration to be found as a file (yml) you have to manually invoke/export it with any of the following methods

1. from the Drupal admin interface visiting the url `admin/config/development/configuration/single/export`. For this to work the core `Configuration Manager` module must be enabled.
2. drush with drush config-export and than finding the appropriate file manually
3. drupal console drupal config:export:single
4. contrib modules such as config\_single\_export or config\_partial\_export

All those methods above have also an import mechanism which you can use to import or see more details here

Also note you will not need the REST UI module to be enabled in production
> 3 votes

---
Tags: 8
---


# Question
Title: How can I import a CSV file to custom entity created using ECK module?
I have created a custom entity type using ECK module. I want to import a csv file with data to my custom entity. How do I do this?

# Answer
Content imports are often done with Feeds or Migrate modules.
> 0 votes

---
Tags: entities, importing-exporting
---


# Question
Title: Why getMimeType() is returning wrong value for xlsx file
Below is my 2 line code to get the Mime Type of an attachment in a preprocess function

```
$file = $node->get('field_attachment_file')->entity;
$variables['attach_type'] = $file->getMimeType();

```

The $variables\['attach\_type'\] is always getting the value of 'application/pdf' despite the attachment being an Microsoft Excel spreadsheet

# Answer
> 2 votes
The value returned as MIME type of a file is the value returned from the *file.mime\_type.guesser* service which, on a default Drupal installation, uses three classes to guess the MIME type:

It is also possible that a module implements `hook_file_mimetype_mapping_alter()` to change the value returned from the first class, the file used from `file` or `fileinfo_file()` contains the wrong values, or another module implements another guesser class that is used before the other classes and returns the wrong MIME type.

---
Tags: files
---


# Question
Title: Can a Webform display the last submitted version of instead of creating a new submission
I have a web form that is embedded into a field on a content type and wondering if the form has been already submitted can you display the webform/manage/webform\_name/submission/webforn\_numer/edit form instead?

# Answer
> 1 votes
Yes!!! Just go to Webform: Submissions: Settings and check off 'Limit total to one submission' per user or per submission.

---
Tags: webforms
---


title: Add Constraint to Paragraph Field

text:
# Question
Title: Add Constraint to Paragraph Field
I'm attempting to follow this documentation to add a custom constraint to a field in a Paragraph but I'm having trouble actually accessing that field.

Currently I have `my_content_type` with `paragraph_field`. This field accepts a number of different paragraph types. I'd like to be able to add a constraint to a field on a specific paragraph type that could be added to that field.

I've tried using `hook_entity_bundle_field_info_alter`, `hook_form_alter`, and `hook_field_widget_form_alter` but am having trouble actually accessing the proper field.

Is there a better way to do this?

# Answer
> 1 votes
@Vecta I hope this help you

```
function MYMODULE_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
  //with a node
  if ($entity_type->id() === 'node') {
    if ($bundle == 'article') {
      if (isset($fields['title'])) {
        // change constraint id
        $fields['title']->addConstraint('UniqueCode', []);
      }
    }
  }
  //with a paragraph
  if ($entity_type->id() === 'paragraph') {
    // use the paragraph machine name
    if ($bundle == 'paragraph_name') {
      if (isset($fields['field_name'])) {
        // change constraint id
        $fields['field_name']->addConstraint('ConstraintId', []);
      }
    }
  }
}

```

---
Tags: forms, paragraphs
---


title: Migrate files into dynamic paths

text:
# Question
Title: Migrate files into dynamic paths
I have a constant defined in my migration definition like so:

```
  constants:
    destination: "private://working_papers/"

```

There are 30,000 files that will come in as part of the migration. I would like to create directory destinations on the fly, based on source field values or whatever I want.

So:

`destination: constants/destination`

Would become:

`destination: constants/destination/@source_field_value/@source_field_value2`

This would be to reduce the raw number of files appearing in a given directory. When I try the above, nothing happens, even though the migration succeeds. The files don't go anywhere.

How can I do this? For reference, here is the field in the process section of the definition:

```
  field_paper_working_paper:
    plugin: file_import
    source: doc_format_url
    destination: constants/destination
    uid: 1
    rename: TRUE

```

# Answer
> 2 votes
You can chain a `concat` process plugin to your `destination` property so that it contains the result of concatenated source & constant values:

```
field_paper_working_paper:
  plugin: file_import
  source: doc_format_url
  destination:
    plugin: concat
    source:
      - constants/destination
      - '/'
      - source_field_value
      - '/'
      - source_field_value
  uid: 1
  rename: TRUE

```

---
Tags: 8, migrations
---


# Question
Title: \Drupal::database() ->insert - Error: Call to undefined method Using ->condition()?
I am trying to insert a new row based on conditions. The `->condition()` in `$database->update()` works fine, in `$database->insert()` they do not.

```
$database = \Drupal::database();

// Query our DB.
$queryDB = $database
  ->select('table_name', 'value3')
  ->fields('value3')
  ->condition('value1', $value1, "=")
  ->condition('value2', $value2, "=")
  ->execute()->fetchAll();

if (isset($queryDB[0])) {
  // Check if table row exists and overwrite.
  if ($queryDB[0]->value1 == $value1 && $queryDB[0]->value2 == $value2) {
    $database
      ->update('table_name')
      ->fields([
        'value3' => $value3,
      ])
      ->condition('value1', $value1, '=')
      ->condition('value2', $value2, '=')
      ->execute();
  }
}
// Create table row.
else {
  $database
    ->insert('table_name')
    ->fields([
      'value1' => $value1,
      'value2' => $value2,
      'value3' => $value3,
    ])
    // Without these conditions, I get a duplicate entry integrity restraint as value1 and/or value2 may already exist.
    // With them I get Error: Call to undefined method Drupal\Core\Database\Driver\mysql\Insert::condition().
    ->condition('value1', $value1, '!=')
    ->condition('value2', $value2, '!=')
    ->execute();
}

```

Very similar questions: 1. EntityQuery condition "is not equal to..." 2. How do I add a condition to a query?

But I am having no luck. Is it different with an insert?

What I want is that if value1 AND value2 don't both match, create an entirely new table row with all three values.

# Answer
> 5 votes
As described in Insert Queries, the object returned from `\Drupal::database()->insert()` doesn't have an `condition()` method. If the purpose of the code is creating a new database row if it doesn't exist, or update it if it already exists, the code should use the object returned from `\Drupal::database()->merge()`. See Merge Queries.

For example, the following code will create a new row if none of the existing rows contains the value `$name` for the *name* database column; otherwise, it will update the existing matching row. (`$connection` is the object returned from `\Drupal::database()` or a `Connection` object obtained via dependency injection.)

```
$connection->merge('example')
  ->key(['name' => $name])
  ->fields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->execute();

```

It is also possible to use a set of values when the row is created, and another set when the row is updated.

```
$connection->merge('example')
  ->insertFields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->updateFields([
    'field1' => $alternate1,
  ])
  ->key(['name' => $name])
  ->execute();

```

What that documentation page doesn't show is how to use multiple keys, as the following code does, using `Merge::keys()` instead of `Merge::key()`.

```
$connection->merge('example')
  ->insertFields([
      'field1' => $value1,
      'field2' => $value2,
  ])
  ->updateFields([
    'field1' => $alternate1,
  ])
  ->keys(['name' => $name, 'nickname' => $nickname])
  ->execute();

```

The only limitation is that the values passed to `keys()` are all used to match a single database row. In other words, the last snippet I shown doesn't look for a row containing `$name` in the *name* database column **or** a row containing `$nickname` in the *nickname* column.

In cases more complex, where the `Merge` class doesn't help, you need to first check what the database table contains and take the necessary action basing on the table content (which involves writing more PHP code to check the database content).

# Answer
> 2 votes
Yes, it is different. A SQL INSERT statement doesn't have `WHERE` clause, thus the `condition()` mentioned l method doesn't exist for the insert object.

You can add your conditional check in PHP code (e.g. `$queryDB[0]->value1 != $value1`) just as you've redundantly done for your `UPDATE` query.

---
Tags: 8, database
---


title: Get bundle's default publication status

text:
# Question
Title: Get bundle's default publication status
I would like to retrieve whether the bundle of a node is supposed to default to published. I am able to successfully get the bundle of the node in question.

```
$bundle = \Drupal::entityTypeManager()
      ->getStorage('node_type')
      ->load($node->bundle());

```

However, I am unable to retrieve information about default status of the bundle. When I use Devel's `dsm()` function in order to see the array for `$bundle`, the "field" `[status]`, which I would have thought was the value I want, doesn't change. It remains `1`. I tried changing the publication status of the node in question as well as changing the default value for the content type publication status, but neither of these affect this value.

How can I get the bundle's default publication status? What am I missing?

Edit: I am also now using `$bundle->get('status')` to get the specific field referenced above.

# Answer
> 1 votes
The default value is stored in the field's config, rather than the node type's. Currently it's not possible to get that value without having a node to work with.

This is alluded to in `NodeTypeForm::form()` (and also the `save()` method of the same class):

```
if ($this->operation == 'add') {
  $form['#title'] = $this->t('Add content type');
  $fields = $this->entityManager->getBaseFieldDefinitions('node');
  // Create a node with a fake bundle using the type's UUID so that we can
  // get the default values for workflow settings.
  // @todo Make it possible to get default values without an entity.
  //   https://www.drupal.org/node/2318187
  $node = $this->entityManager->getStorage('node')->create(['type' => $type->uuid()]);
}
else {
  $form['#title'] = $this->t('Edit %label content type', ['%label' => $type->label()]);
  $fields = $this->entityManager->getFieldDefinitions('node', $type->id());
  // Create a node to get the current values for workflow settings fields.
  $node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]);
}

```

It goes on to set the options arrays for the checkboxes using that node:

```
$workflow_options = [
  'status' => $node->status->value,
  'promote' => $node->promote->value,
  'sticky' => $node->sticky->value,
  'revision' => $type->isNewRevision(),
];

```

So, for now at least, you'll probably need to do the same thing.

---
Tags: 8
---


title: How do I use a settings.local.php file?

text:
# Question
Title: How do I use a settings.local.php file?
I couldn't find answer from previous questions nor drupal.org/pantheon.io.

There isn't a settings.php if I clone the repository from pantheon.io nor a settings.local.php.

If I create a settings.local.php file, it still thinks it's a fresh install and redirects to install.php, which means it doesn't recognize that file.

How do I use the settings.local.php file?

Naturally, all works if I create a settings.php file.

Can't I just create settings.php for the development site and add a reference to it in the .gitignore file to avoid it will be pushed on the remote repository?

# Answer
When installing Drupal, you need to copy the example.settings.php file in settings.php. After Drupal is installed, you need to include the following code in the settings.php file.

```
if (file_exists(DRUPAL_ROOT . '/' . conf_path() . '/settings.local.php')) {
  include DRUPAL_ROOT . '/' . conf_path() . '/settings.local.php';
}

```
> 5 votes

# Answer
There is an active issue for this that has already been committed to 8.x and 9.x, and it's being backported to 7.x. It adds the code in settings.php to include settings.local.php.

The code in the patch makes some improvements on the code in the other answer.

```
// Include a local settings file if it exists.
$local_settings = dirname(__FILE__) . '/settings.local.php';
if (is_readable($local_settings)) {
  include $local_settings;
}

```

See Add inclusion of a settings.local.php file in settings.php.

### Additional Notes:
> 3 votes

---
Tags: configuration, version-control
---


title: Paragraphs module decoupled structure

text:
# Question
Title: Paragraphs module decoupled structure
I'm looking to use the Paragraphs Drupal 8 module with a decoupled installation of Drupal 8 but would like the structure made in the admin area to be output in the JSON API responses.

How can I modify the JSON API responses from Drupal 8 to include this page structure data?

If anyone wants to know, having it decoupled & outputting structure information is a requirement I've been given.

# Answer
> 1 votes
It sounds like you want a compound document, the JSON:API mechanism that provides other referenced entities in a resource (e.g. a "page" content node that references other paragraphs). This is done via adding an `include` query parameter with a value that refers to a field's relational ID. An inclusion request will add an `included` array property with the related entity resource objects.

See the docs on Includes in the JSON:API docs for more concrete examples in action.

Since you mentioned it, ordering included resources isn't possible (IIRC); you might be able to infer order based on the Paragraph field. JSON:API is designed for minimal configuration and maximum adherence to the JSONAPI spec so you're limited to a couple of mechanisms to modify the output of the structured data.

---
Tags: 8, paragraphs
---


# Question
Title: Webform image select element is dispalying another image while used in webform handler
In drupal 8,

I have created a custom webform handler to create a new article node and copy the data and images from the webform element to the created article node.

In both artcle node and contact webform, i have created the required fields/elements.

Article node fields:

Contact webform element:

Now, after submitting the contact webform:

everything goes as expected and a new Article node is created with all fields filled in with data/images.

However, only the Webform element image select is displaying another image instead of the one selected while submitting the webform.

Below is the created article:

As you can see, the webform element **image** has been properly populated but the problem is within the webform element **image select** !!!

I am sure that my custom code is fine as all other fields are populated correctly.

Any idea/help why the picture is being replaced by another one ??!!

**Below is my custom handler code:**

```
<?php

namespace Drupal\my_module_name\Plugin\WebformHandler;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Form\FormStateInterface;

use Drupal\node\Entity\Node;

use Drupal\webform\WebformInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\webformSubmissionInterface;
use Drupal\webform\Entity\WebformSubmission;

/**
 * Create a new node entity from a webform submission.
 *
 * @WebformHandler(
 *   id = "Create a node",
 *   label = @Translation("Create a node"),
 *   category = @Translation("Entity Creation"),
 *   description = @Translation("Creates a new node from Webform Submissions."),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_UNLIMITED,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 *   submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_REQUIRED,
 * )
 */

class ExampleWebformHandler extends WebformHandlerBase {

  /**
   * {@inheritdoc}
   */

  // Create node object from webform-submission.

  // Function to be fired while submitting the Webform.
  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    // Get an array of the values from the submission.
    $values = $webform_submission->getData();

    // Before you actually save the node, make sure you get what you
    // want. So at first comment the line further down with
    // $node->save(), run the debug code, check the output and then
    // uncomment the $node->save() and delete the debug foreach loop.
    // You can use whatever debug method you prefer, this is just a
    // simple one-time example.
     foreach($values as $key=>$value) {
       drupal_set_message($key . ' -> ' . $value);
     }

    // This is the node creating/saving part.
      $node = Node::create([
     'type'        => 'article',
    // Use this format: 'node_machine_name_field' => $values('webform_machine_name_field') for below fields.
      'title' => $values['subject'],
      'body' => $values['message'],
      'field_image' => $values['picture'],
      'field_picture_select' => $values['picture_select'],
    // etc...
     ]);

    // Before you un-comment this line, make sure you get all the
    // values you need from the webform data (in the foreach loop).
    $node->save();
  }
}

```

# Answer
> 0 votes
Finally, I am decided to go with "Business rules" module which will allow to create any content type and transfer all data from webform submission to the created node by setting up a few actions to be triggered on the rule event: entity insert of type webform submission.

See video tutorials here: https://www.youtube.com/channel/UC3jgO5Yt-5y\__VVT74qRgSg

---
Tags: 8, nodes, media, webforms
---


# Question
Title: Cancelling user account set draft pages to published
When we cancelled a user account using the `Delete the account and make its content belong to the Anonymous user` method, we found that the author was set to `Anonymous` for the pages they were set as the `Author`, as expected. The problem is that many pages that were set to `Draft` were then updated to have their `Author` set to `Anonymous` and `published`, which is not a desired outcome. These drafts were never published and always kept in that state.

We have a view that pulls all pages that are published and content type = `Basic Page`. This started to pull in all the `draft` pages because they were set to `published` after the user account was cancelled.

**How can we cancel an account without publishing pages that were are set to `Draft` moderation state?**

Steps to reproduce:

1. Create 10 draft `Basic Pages` (do not publish) where the `Author` is set to `content admin`
2. Cancel the user account for `content admin` by using `Delete the account and make its content belong to the Anonymous user` method.
3. Under `/admin/content`, observe the pages are now in `published` state with `Author` set to `Anonymous`

Current modules being used for revision:

1. `workbench`
2. `workbench_moderation`

# Answer
> 0 votes
Just did a test with the steps you provided. I tried with just 1 node unpublished and cancelled the user and the node was assigned to the anonymous user BUT the node stayed unpublished. I don't see any reason why the result would be any different if I tried with 10 nodes.

I believe a contrib/custom module is at fault. See if you have any modules that deal with publishing/unpublishing content you have to disable them and test if the problem is gone.

If the above does not help I would try to disable all modules one by one and testing to see if the problem is gone on each step. Once you find the problematic module you can post the results in the issue queue and you might also discover a patch resolving the issue.

You can also post a list of your enabled modules and someone might be able to spot a module that could be a potential candidate to be causing this behaviour.

---
Tags: 8, nodes, users
---


title: Check if translation is new

text:
# Question
Title: Check if translation is new
I am working on a module that needs to send push notification through FCM, I use **Firebase Push Notification (FCM)** for this purpose and it works well.

So what I need to do is to send a push notification when a node of specific content type is created, and it's solved through **hook\_entity\_insert**, but problem is that I have multiple languages on site, and it works only when the node is created the first time.

So my question is how to know when translation is created for the first time for a specific node?

For example:

* node is created on English (in hook\_entity\_insert I check if the node belong to specific content type and call a function to send the notification to all users that have English as user language).
* now when we add the translation for other languages, how I can know that it's the first time translation is created, and not updated one?

# Answer
You can try using hook\_entity\_translation\_insert and use a common logic with hook\_entity\_insert
> 3 votes

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


# Question
Title: Custom user login in Facebook Auth modules
I try to run Facebook Login on my Drupal 8 site. I run it by Social API module and with Simple FB Connect, but both module generate user name from first and last name on Facebook. My user will not be happy with using real name, but I don't want to give them options to change username whenever they want.

For code examples I use Simple FB Connect, but the same logic is in Social API modules.

User go to path `user/simple-fb-connect` and is redirected by `Drupal\simple_fb_connect\Controller\SimpleFbConnectController->redirectToFb()`, and when he is back, go to `user/simple-fb-connect/return` which is handle by `Drupal\simple_fb_connect\Controller\SimpleFbConnectController->returnFromFb()`.

It checks permissions, get data from FB and then if email not exist in DB, registers user:

```
[...]
    // If there was no existing user, try to create a new user.
    $fbid = $fb_profile->getField('id');
    $fb_profile_pic = $this->fbManager->getFbProfilePic();
    if ($drupal_user = $this->userManager->createUser($fb_profile->getField('name'), $email, $fbid, $fb_profile_pic)) {
[...]

```

The main question is: How I can replace `$fb_profile->getField('name')` with custom, provided by user string ? I think about:

1. Replace simple link on login with form contains textfield and submit button, which send POST/GET data to `user/simple-fb-connect`. There store it Session, and use on `returnFromFb()` function to create user.

But I can't always show an additional field (eg. on homepage), and I don't know if user want to register or just login. It kills idea, just click, and get account.

2. After back from FB, show users one-time form, which they can't skip, and access page, before they fill it, like post-login registration in normal FB integrations, on which they can fill additional data, but only once per account.

But there I have no idea how to even start. Maybe I can replace function `returnFromFb()` code creating new user with register form, and after submit create user. Or leave module code in peace and base it on events from the module. But how I can lock page for user who don't fill this and secure it to be fill just one time (maybe boolean field on user entity?).

3. The simplest way, just leave it as it is, use display name and hide login, but I don't want to store user names and last names in database.

Thanks for help!

PS. I tried to ask the creators, but it looks like the modules work like they should work.

# Answer
Provided that you're using v8.3 or higher of the module, a possible solution would be to create a form where the user decides which values are stored according to his/her needs and your requirements of course.
Then, using the provided events in the module, you can redirect the user to this form which will accept the `$user` object and apply the changes accordingly.
You should add an EventSubscriber service which listens to `simple_fb_connect.user_created` event as per the module documentation linked above. Thus you're only showing this form to the user once after the account has been created and not with every login.
Hope this helps.
> 0 votes

---
Tags: 8, users, forms
---


# Question
Title: How to edit Menu primary nav tab in Drupal 8
Page contains two nav bars with primary having View, Edit, Notes, Resend, Devel tabs and a secondary nav bar with Definition, Render, Load, Tokens. I am using css to not display particular tabs in primary and totally hiding the secondary nav bar. But, one of the requirement is to edit the name of a tab. I tried using theme\_preprocess\_menu\_local\_task hook but I am not able to edit the protected object values. What is the approach I need to take to edit the name of the tab. In this case 'resend' to 'forward'.

```
    function theme_preprocess_menu_local_task(&$variables) {
     if($variables['item']->text =='Resend'){
        $variables['item']->text = 'Forward';
     }
    }

```

the above code bombs with error saying protected values cannot be accessed.

# Answer
> 1 votes
You may wish to use hook\_local\_tasks\_alter() and/or hook\_menu\_local\_tasks\_alter() to hide/rename local tasks.

---
Tags: 8
---


title: Delete in lieu of truncate?

text:
# Question
Title: Delete in lieu of truncate?
If my DB user doesn't have permission to truncate a table - would using delete instead without any parameters be equivalent? So like -

```
 $this->db->delete('data')->execute();

```

in lieu of

```
 $this->db->truncate('data')->execute();

```

I've never used the delete command this way in the Drupal DB API.

# Answer
Logically a truncate and a delete statement are very similar. They work a little different which allows truncate to be faster in many cases. For the specific code in question, it might be a little slower but it should perform the same purpose and the code should work fine.

However, if your site lacks the ability to TRUNCATE then it also lacks the ability to DROP tables. It's possible to run Drupal on sites like that for very specific purposes, but there are several Drupal features that will not work without the ability to DROP tables.
> 4 votes

---
Tags: database
---


# Question
Title: Print view header using the "Twig Tweak" module
I would like to print out the header for a view, but not the rest of the content using the Twig Tweak module. I've tried variations on `{{ drupal_view('VIEW_NAME', 'PAGE_NAME', 'view_header') }}`, but that prints out the entire view.

# Answer
I have create simple extension for that:

1. add the following to `MYMODULE.services.yml`

```

    services:
      MYMODULE.twig.render_view_header:
        class: Drupal\MYMODULE\Twig\HeaderView
        tags:
          - { name: twig.extension }

```
2. Create `HeaderView` class inside `MYMODULE/src/Twig`.
3. Copy the code from HeaderView.php
4. Clear cache.
5. In your twig call the extension like:

```

{{ render_view_header('VIEW_NAME', 'PAGE_NAME') }}

```
> 3 votes

# Answer
Main twig template for the **views** is `views-view.html.twig`. You can see **header**, **footer**, **content** , **attachment** variable in this file.So you can print your views in your method `{{ drupal_view('VIEW_NAME', 'PAGE_NAME') }}` then rename `views-view.html.twig` to `views-view--VIEW_NAME--PAGE_NAME.html.twig` and remove unwanted content.
> -1 votes

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


# Question
Title: {{ content.field_test }} doesn't work in node.html.twig
I created a field whose machine name is *field\_test*. I want to show this field in node.html.twig, but when I use `{{ content.field_test }}`, `{{ content.field_test.value }}`, or `{{ content.field_test[0] }}` the field is not printed.

How can I achieve this in Drupal 8.3.5?

# Answer
Uninstalling Field Layout module will solve this. (tested with Drupal 8.6.10, using subtheme built on Barrio Bootstrap 4).
> 4 votes

# Answer
```
{{ content.field_test }}

```

Should just work but make sure

* you the field is not hidden by going to `admin/structure/types/manage/CONTENTTYPE/display` and making sure the field is NOT in the disabled fields
* its not hidden because of some changes in `hook_preprocess_node` in your theme or a parent theme

Investigate further either by

* installing `devel` and `kint` modules (kint is a submodule of devel) and `{{kint(content)}}`
* within `hook_preprocess_node` using a xdebug or `print` or `print_r` statements
> 1 votes

---
Tags: 8, theming, nodes
---


# Question
Title: Where files are used if path entered by hand
I am brining a 100 or so static pages into my drupal install here. We are pasting the content from the static site into the body of a content type. I am using ICME to upload the images and documents. Unless I directly link from ICME to the document, I've noticed it does not record as being used (/admin/content/files \> USED IN). Is there a batch script to run to check if a file is used somehow?

We are adding the files, but only updating the path via code editor find and replace... I do not want to hightlight each image and find the file in Drupal. The files are being recorded in the system as IMCE does that and if we do actually use the ckeditor IMCE link it does show as used. Just to emphasize that.

# Answer
> 0 votes
inline\_image\_to\_field module promises turn your inline images into an image field (image entities).

> This module will take images that are embedded (copy/paste) or were uploaded via the wysiwyg and attach them to an image field.

This way you can have your Drupal installation being fully aware of any such images and take advantage of any **file or image entity** related modules.

**DISCLAIMER:** I have not used this module and it is new module with not many installs so use with caution on your DEV environment before commiting to your LIVE environment

---
Tags: 8, files
---


# Question
Title: looking for equivalent webform select view module on Drupal 8
I am a new to Drupal 8

I am trying to make select options with webform submission.

What module do I need? and How can I make this select options with that module?

Thank you very much!

implement

# Answer
> 2 votes
I believe what used to be webform\_views\_select module is part of Webform core for Drupal 8.

You can search for `entity` and choose any of the following elements

configure an entity reference view to be use as options

**NOTE1:** Due to perhaps this issue entity reference is not recognized by webform the way outlined above, but it should work if core patch in #7 is applied (as confirmed by reports in this issue)

**NOTE2:** Perhaps a work around would be to use `content` or `taxonomy term` instead of a `view` (since view reference is not working) if you don't have great need for views filtering capabilities.

# Answer
> -1 votes
The Webform module will do this out of the box.

1. Install webform module the usual way.
2. Install the webform\_ui module too. It helps a lot in creating new forms.
3. Build your new form.
4. Add Element "select" (to find in the list at "options elements").
5. Add Options you want.

As an alternative you can write your webform-definition in yaml-format.

This looks like:

```
class:
  '#type': select
  '#title': Class
  '#options':
    Geometry: Geometry
    Algebra: Algebra
    English: English

```

Webform module is complex, but can fullfill many needs. There are some helpful videos using webform module.

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


# Question
Title: When should I use the private file system instead of public file system?
I try to build a social network on Drupal 8 currently.

**And now I have to decide, which files (e.g. user pictures, uploaded user files) should be handled as private files and which as public files.**

As far as I know, the **public file** dir listing is deactivated by Drupal generated .htaccess and it returns a 403 server error. The file is only accessible if you know the exact URL.

The **private file** system sometimes is buggy (e.g. default user pictures) and doesn't it bloat the database with aliases? If I want to grab e.g. a picture from the site which is saved in private file system, but shown as content of a view or a node field, I can simply right click on it, and despite private file structure I can save it locally.
So, back to question, when does it make sense to use private file system?

# Answer
> 5 votes
You should use private file system for files to take under control of your drupal installation.

If you have some content with files and pictures you want to be visible only for certain users or groups, then you should save it in private file system. Perhaps paid content or sensitive content.

Content and images which is public to all do not need to be in private file system. For that it is better to use public file system to save server resources.

All files in public space are usable for everyone who knows the url. Files in private space are not. You can get them only if drupal serves it to you.

---
Tags: 8
---


# Question
Title: How to set the classes used in Drupal commerce buttons with Bootstrap theme
I am working on a site with Drupal commerce, I use the Bootstrap theme and a child theme.
I would like the \[add-to-cart\] button to have the "btn-default" class, instead of “btn-success". Actually, I want to get rid of the "info" and "warning" classes in many cases where I don't need them and replace them by "default" or "primary".

I saw in /sites/all/themes/bootstrap/bootstrap.api.php

```
/**
 * Allows sub-themes to alter the array used for colorizing text.
 * …
 * @see _bootstrap_colorize_text()
 */
 function hook_bootstrap_colorize_text_alter(array &$texts) {
   // This matches the exact string: "My Unique Button Text".
   $texts['matches'][t('My Unique Button Text')] = 'primary';

  // This would also match the string above, however the class returned would
  // also be the one above; "matches" takes precedence over "contains".
  $texts['contains'][t('Unique')] = 'notice';

  // Remove matching for strings that contain "apply":
  unset($texts['contains'][t('Apply')]);

  // Change the class that matches "Rebuild" (originally "warning"):
  $texts['contains'][t('Rebuild')] = 'success';
}

```

So I tried in /sites/all/themes/\[my-sub-theme\]/template.php

```
function hook_[my-sub-theme]_colorize_text_alter(array &$texts) {
  // Let's try a dummy change for a test
  $texts['contains'][t('Update cart')] = 'success';
}

```

But I can't see anything changed.

I also saw that /sites/all/themes/bootstrap/includes/common.inc sets a number of values based on the contained string, in which I find th “Update” I am looking for. the function is
`function _bootstrap_colorize_text($string, $default = '') {…}`
it ends with

```
// Allow sub-themes to alter this array of patterns.
    drupal_alter('bootstrap_colorize_text', $texts);

```

But I still haven't found how to do what I want in my sub theme. and what I read in /sites/all/themes/bootstrap/templates/system/buttons.vars.php won't help me.

Can somebody please explain where to start?

# Answer
> 1 votes
I'm having the same type of issue (which I will post elsewhere). I'm not sure I have the best answer, but from what I read in the Bootstrap API documentation, I believe your code should read as follows.

```
function [my-sub-theme]_colorize_text_alter(array &$texts) {
  // Let's try a dummy change for a test
  $texts['contains'][t('Update cart')] = 'success';
}

```

The preceding "hook" needs to be entirely replaced by your \[my-sub-theme\] name. From what I read, that should be what is needed for this to work. However, I'm having trouble getting it to work myself.

---
Tags: 7, theming, bootstrap-theme
---


title: Use of render array in theme layer

text:
# Question
Title: Use of render array in theme layer
Why does the theme layer uses render arrays when all the theming functionalities can be implemented with `print` statements in templates files? Is there any analogy that explains the use of render array in the theme layer and how it interacts with the template files?

# Answer
Drupals render arrays are a great invention which make it possible to alter the output of content by others (modules, themes etc.).

If you would hard-code your output in variables to print, no one other can alter it. But if you use render arrays, then other modules can implement hooks to alter the rendering of your output if they need to do so.

For this flexibility it is best practice to use render arrays until the very last moment and let the twig template build the html from it.
> 1 votes

# Answer
A render array is a classic Drupal structured array that provides data (probably nested) along with hints as to how it should be rendered (properties, like #type).

**render($content\['body'\])** contains everything in a structure in which the render function can turn it into display. This includes all your fields.

**print $body\[0\]\['value'\]** simply prints the value of that one field bypassing any rendering functionality such as "weight".

Rendering is a fun thing in Drupal, especially when you get to Drupal 7. Think of what you're passing into "render" as instructions on how to output, whereas the value is simply... a string... a value.

Nice documentation regarding Render Arrrays in Drupal 7 on Drupal.org
> 0 votes

---
Tags: theming
---


# Question
Title: Replacing Private message module with nodes
I was looking for a quick answer to the problem of allowing members to write each other messages. The Private message module looked like the most complete solution.

However, it has some significant downsides.

1. I can't find an API for it anymore. All the links are dead.
2. It uses awful HTML output which is not responsive so refer to problem 1.
3. It's not integrated with views!

So I wonder if a poor man's messaging system that simply uses nodes and views would be a more versatile, future proof and potentially more performant replacement. Is private messages dramatically more performant(such that it's downsides are worth it) than using nodes and views for private conversations, of which there would be potentially many?

# Answer
> 0 votes
If by API you mean documentation, there is a documentation for the module in the following link: https://www.drupal.org/documentation/modules/privatemsg
For actual API file: https://cgit.drupalcode.org/privatemsg/tree/privatemsg.api.php?h=7.x-1.x
In the same code repository, the module contains views folder with views integration, so I don't understand what you mean by no views integration?
And here is an example on how to theme the new messages block, you should check this file for more theming functions.
Hope that helps.

---
Tags: 7, privatemsg
---


# Question
Title: Is applyUpdates() really needed in hook_install()?
I maintain a contributed module which defines two base fields, but these are not added to any content type on installation, as this is done from administrator users. The module uses the following line in in `hook_install()` and `hook_uninstall()`.

```
// Add our base fields to the schema.
\Drupal::service('entity.definition_update_manager')->applyUpdates();

```

Now that this function is deprecated in Drupal 8.7, as described in Support for automatic entity updates has been removed, I've tried removing the lines and installing, and it seems to work OK.

Is removing the calls to `applyUpdates()` OK?

I think there were problems with fields not being deleted in the early days of Drupal 8, but maybe that works better now.

# Answer
> 3 votes
The change record you've linked is about update hooks for already installed modules, not hook\_install().

You've never needed `applyUpdates()` in an install hook. If your custom module is adding a new field, it will be added automatically when the module is enabled, and removed when the module is uninstalled. There was only an issue with base fields containing data, but this is resolved since Drupal 8.5. See this change record: Base fields with existing data can now be uninstalled.

---
Tags: hooks, installation, 8
---


# Question
Title: What was the motivation for developing the plugin API?
I am trying to wrap around my head as to what was the need for the Plugin API when the module system extends the Drupal core.

# Answer
It is not modules vs. plugins. Plugins are competing against hooks, which they will eventually replace entirely, together with event subscribers and services. By the way, all are implemented by modules because you are not allowed to insert them in core directly.
> 6 votes

---
Tags: 8, plugins
---


# Question
Title: How do I correctly implement hook_bootstrap_colorize_text() to alter button colors in a Bootstrap sub-theme?
I have read similar questions on here, but I'm still struggling for an answer for this.

I'm trying to implement hook\_bootstrap\_colorize\_text() to alter button colors in a Bootstrap sub-theme.

I would like to add some specific text items to the array that dictates how the buttons are colorizes. For example, I have some buttons that have the "btn-default" class, and I would like to indicate specific texts to which should have “btn-success" or "btn-warning" instead.

The bootstrap.api.php describes this process:

```
/**
 * Allows sub-themes to alter the array used for colorizing text.
 * …
 * @see _bootstrap_colorize_text()
 */
 function hook_bootstrap_colorize_text_alter(array &$texts) {
   // This matches the exact string: "My Unique Button Text".
   $texts['matches'][t('My Unique Button Text')] = 'primary';

  // This would also match the string above, however the class returned would
  // also be the one above; "matches" takes precedence over "contains".
  $texts['contains'][t('Unique')] = 'notice';

  // Remove matching for strings that contain "apply":
  unset($texts['contains'][t('Apply')]);

  // Change the class that matches "Rebuild" (originally "warning"):
  $texts['contains'][t('Rebuild')] = 'success';
}

```

Therefore, I have attempted to implement the following code in my sub-theme (methodsTheme) template.php file without success.

```
<?php
// Implements hook_bootstrap_colorize_text_alter() to alter button colors.
  function methodstheme_bootstrap_colorize_text_alter(array &$texts) {
    $texts['matches'][t('Request Rotation')] = 'success';
    $texts['contains'][t('Notify')] = 'success';
    $texts['contains'][t('Set')] = 'success';
    $texts['contains'][t('Mark')] = 'success';
    $texts['contains'][t('Assign')] = 'success';
    $texts['contains'][t('Report')] = 'warning';
    $texts['contains'][t('Request')] = 'info';
  }
?>

```

I've also tried:

```
<?php
// Implements hook_bootstrap_colorize_text_alter() to alter button colors.
  function methodstheme_bootstrap_colorize_text_alter(&$texts) {
    $texts['matches'][t('Request Rotation')] = 'success';
    $texts['contains'][t('Notify')] = 'success';
    $texts['contains'][t('Set')] = 'success';
    $texts['contains'][t('Mark')] = 'success';
    $texts['contains'][t('Assign')] = 'success';
    $texts['contains'][t('Report')] = 'warning';
    $texts['contains'][t('Request')] = 'info';
  }
?>

```

And, I've also tried:

```
<?php
// Implements hook_bootstrap_colorize_text_alter() to alter button colors.
  function methodstheme_bootstrap_colorize_text_alter(&$texts) {
    $texts = array(
      'matches' => array(
        t('Request Rotation') => 'success',
      ),
      'contains' => array(
        t('Notify') => 'success',
        t('Set') => 'success',
        t('Mark') => 'success',
        t('Assign') => 'success',
        t('Report') => 'warning',
        t('Request') => 'info',
      ),
    );
  }
?>

```

And, yes, after each attempt, I'm clearing the caches to see if the changes to the code are implemented to the desired result. However, I'm still emptyhanded. I'm placing the template.php file in my sites/all/themes/methodstheme/templates folder. The sub-theme was already established and working well (i.e., it is set-up properly, I believe).

I'm using Drupal 7.64 (with install profile varbase, but I've mostly removed all usage of the varbase profile and modules) and latest version of Bootstrap 3 theme as the base theme.

Can anyone offer some help or suggestions on what the issue may be?

# Answer
> 2 votes
Well, I really thought I had tried everything before posting. I didn't think I'd be answering my own question, but I'll put it up here in the case it is helpful to others. Here is what eventually worked for me:

```
<?php
  //Implements hook_bootstrap_colorize_text_alter() to alter Bootstrap button colors.
  function methodstheme_bootstrap_colorize_text_alter(&$texts) {
    $texts['matches'][t('Request Rotation')] = 'success';
    $texts['contains'][t('Notify')] = 'success';
    $texts['contains'][t('Set')] = 'success';
    $texts['contains'][t('Mark')] = 'success';
    $texts['contains'][t('Assign')] = 'success';
    $texts['contains'][t('Report')] = 'warning';
    $texts['contains'][t('Request')] = 'info';
  }
?>

```

I had tried this earlier, and had no result after clearing caches. I had tried placing the template.php file in my sites/all/themes/methodstheme/templates folder as well as the sites/all/themes/methodstheme (not the templates sub-folder) folder.

Regardless of the folder I placed it in, it was still not working - I had no result after clearing the caches initially.

Placing the file in the sites/all/themes/methodstheme (not the templates sub-folder) folder was part of the solution. I had brushed up on the Bootstrap Starterkit file structure, and I was fairly certain the template.php file should not be in the templates sub-folder, so I started trying other things. Using Drush I cleared the theme-registry cache, the theme list cache, then cleared all caches. I cleared those caches again a second time, and viola! My site is now functioning as expected.

Lesson learned - clearing caches multiple times is sometimes necessary/helpful!

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


# Question
Title: Pass argument when overriding controller in RouteSubscriber
I am having the issue of overriding the default taxonomy controller /taxonomy/term/{tid}.

I have created my own controller which takes {tid} as a parameter and I want to use it instead, so I overrode the default taxonomy controller in the RouteSubscriber like this:

```
    <?php

namespace Drupal\my_module\EventSubscriber;

use Drupal\Core\Routing\RouteSubscriberBase;
use Drupal\Core\Routing\RoutingEvents;
use Symfony\Component\Routing\RouteCollection;

class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    foreach ($collection->all() as $route) {
      if ($route = $collection->get('entity.taxonomy_term.canonical')) {
        $route->setDefault('_controller', '\Drupal\my_module\Controller\PagerController::handleDefaultPage');
      }
    }
  }

  public static function getSubscribedEvents() {
    $events = parent::getSubscribedEvents();
    $events[RoutingEvents::ALTER] = array('onAlterRoutes', -250);
    return $events;
  }

}

```

My sample page controller is this:

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class PagerController.
 */
class PagerController extends ControllerBase {

  /**
   * Handlepage.
   *
   * @return string
   *   Return Hello string.
   */
  public function handleDefaultPage($tid) {
    return [
      '#type' => 'markup',
      '#markup' => 'term: ' . $tid,
    ];
  }
}

```

And its routing is this:

```
my_module.pager_controller_handleDefaultPage:
  path: '/taxonomy/term/{tid}'
  defaults:
    _controller: '\Drupal\my_module\Controller\PagerController::handleDefaultPage'
    _title: 'Taxonomy Pager'
  requirements:
    _permission: 'access content'
    _entity_access: 'taxonomy_term.view'
    taxonomy_term: \d+

```

But then, when I open the taxonomy page, I get this error which means, that I need to pass the $tid param somehow.

RuntimeException: Controller "Drupal\my\_module\Controller\PagerController::handleDefaultPage()" requires that you provide a value for the "$tid" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one. in Symfony\Component\HttpKernel\Controller\ArgumentResolver-\>getArguments() (line 78 of /var/www/html/vendor/symfony/http-kernel/Controller/ArgumentResolver.php).

How to resolve it?

# Answer
> 1 votes
Actually, I have found an error in my code. Everything works normally, when the param name and type are set properly. So the final code should be:

My sample page controller is this:

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\taxonomy\TermInterface;

/**
 * Class PagerController.
 */
class PagerController extends ControllerBase {

  /**
   * Handlepage.
   *
   * @return string
   *   Return Hello string.
   */
  public function handleDefaultPage(TermInterface $taxonomy_term) {
    return [
      '#type' => 'markup',
      '#markup' => 'term: ' . $taxonomy_term->getName(),
    ];
  }
}

```

And its routing is this:

```
my_module.pager_controller_handleDefaultPage:
  path: '/taxonomy/term/{taxonomy_term}'
  defaults:
    _controller: '\Drupal\my_module\Controller\PagerController::handleDefaultPage'
    _title: 'Taxonomy Pager'
  requirements:
    _permission: 'access content'
    _entity_access: 'taxonomy_term.view'
    taxonomy_term: \d+

```

---
Tags: views, 8, taxonomy-terms, routes, page-controller
---


title: Cannot edit new View

text:
# Question
Title: Cannot edit new View
Since I updated to 8.6.10, I can no longer edit a new view. I can create a view but when I go to the main interface after clicking Save & Edit, nothings works. No matter what I click on, aside from the brief display of turning wheel, nothing happens.

I have checked the log and no error messages and strangely, existing views are working well.

**Update:** Error message from DevTool console shown below

# Answer
> 0 votes
If the views are working but you cannot edit, then could something wrong with the views\_ui module.

There are two differend modules:

* Views: for views functionality
* Views\_ui: for changing views with the web browser at admin section.

Views do not need the Views-ui module activated. This is only for changing existing views. Therefore you can try to deactivate views\_ui module and reinstall it.

(Cache clearing is always a good idea, but I think this have you done.)

---
Tags: views, 8
---