# Question
Title: How to delete all translations when deleting a node using default language?
I'm trying to delete all translations when deleting a node using default language?

For that purpose, I am using the hook\_node\_delete, but I am not able to invoke node\_delete() from it. It cause a fatal error and the process can't terminate. Even the first node I am deleting isn't deleted preoperly.

```
 function hook_node_delete($node){
        $translation_list = translation_node_get_translations($node->tnid);
        $default_language = language_default()->language;

        if($translation_list!=""){
           foreach($translation_list as $translation_list_item){
              if ($translation_list_item->language!=$default_language){
                  node_delete($translation_list_item->nid);
              }
           };
        };
    }

```

So I am forced to simply unpublish the translations by doing something like that:

```
 function hook_node_delete($node){
                $translation_list = translation_node_get_translations($node->tnid);
                $default_language = language_default()->language;

                if($translation_list!=""){
                   foreach($translation_list as $translation_list_item){
                      if ($translation_list_item->language!=$default_language){
                          $node_translated = node_load($translation_list_item->nid);
                          $node_translated->status = 0;
                          node_save($node_translated);
                      }
                   };
                };
            }

```

Why can I not invoke node\_delete() from hook\_node\_delete()??

# Answer
> 0 votes
The "Gert van den buijs" answer doesn't work for me. So I managed to do it by deleting the content directly with db\_delete. I'm not sure it's the best way to do it but at least it works.

Like that, hook\_node\_delete isn't called recursively and the function can terminate properly.

```
function hook_node_delete($node){
   $all = translation_node_get_translations($node->tnid);
     unset($all[$node->language]);
     if(isset($all)){
            foreach($all as $del){
                    if($node->nid != $del->nid){
                        $nids[] = $del->nid;
                            db_delete('node')
                                ->condition('nid', $nids, 'IN')
                                ->execute();
                            db_delete('node_revision')
                                ->condition('nid', $nids, 'IN')
                                ->execute();
                            db_delete('history')
                                ->condition('nid', $nids, 'IN')
                                ->execute();
                            db_delete('node_access')
                             ->condition('nid', $nids, 'IN')
                             ->execute();
                    }
            }
     }
}

```

# Answer
> 3 votes
you first have to remove the nodes from the translation set before you can delete them. So do something like this:

```
function hook_node_delete($node){
    $all = translation_node_get_translations($node->tnid);

    foreach($all as $del){
        if($node->nid != $del->nid){
            translation_remove_from_set(node_load($del->nid));
            node_delete($del->nid);
        }
    }
}

```

# Answer
> 2 votes
The answer provided by 118218 doesn't work for me because if you are deleting the source node (first node created of the translation set) the function `translation_node_get_translations` will return `null`, since the `tnid` of the other nodes of this translation set will be updated before the execution of `hook_node_delete`.

The solution for me was to overwrite the `node/%node/delete` menu item like this:

```
/**
 * Implements hook_menu_alter().
 */
function my_module_menu_alter(&$items)
{
    $items['node/%node/delete']['page arguments'] = array('my_module_custom_node_delete', 1);
    $items['node/%node/delete']['file path'] = drupal_get_path('module', 'my_module');
    $items['node/%node/delete']['file'] = 'my_module.module';
}

```

and then implement the delete confirmation form and submit function creating a callback before the node deletion like this:

```
function my_module_custom_node_delete($form, &$form_state, $node) {
    $form['#node'] = $node;
    // Always provide entity id in the same form key as in the entity edit form.
    $form['nid'] = array('#type' => 'value', '#value' => $node->nid);
    return confirm_form($form,
        t('Are you sure you want to delete %title?', array('%title' => $node->title)),
        'node/' . $node->nid,
        t('This action cannot be undone.'),
        t('Delete'),
        t('Cancel')
    );
}

function my_module_custom_node_delete_submit($form, &$form_state) {
    if ($form_state['values']['confirm']) {
        $node = node_load($form_state['values']['nid']);
        drupal_alter('before_node_delete', clone $node);
        node_delete($form_state['values']['nid']);
        watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title));
        drupal_set_message(t('@type %title has been deleted.', array('@type' => node_type_get_name($node), '%title' => $node->title)));
    }
    $form_state['redirect'] = '<front>';
}

```

implement the deletion of the other nodes:

```
function my_module_delete_child_nodes($node) {
    if($node->language == SOURCE_NODE_LANGUAGE) {
        $all = translation_node_get_translations($node->tnid);
        if(isset($all[SOURCE_NODE_LANGUAGE]))
            unset($all[SOURCE_NODE_LANGUAGE]);
        if(count($all) > 0) {
            $nids = array();
            foreach($all as $t) {
                $nids[] = $t->nid;
            }
            node_delete_multiple($nids);
        }
    }
}

```

and finally, you can call the deletion function from any module you want just implementing the hook `MODULE_NAME_before_node_delete_alter($node)`

```
/**
 * Implements hook_before_node_delete_alter().
 */
function MODULE_NAME_before_node_delete_alter($node)
{
        my_module_delete_child_nodes($node);
}

```

# Answer
> 1 votes
As "filipedelmonte" answer says, if the source node of the translation set is deleted, then the function `translation_node_get_translations` will return null since the `tnid` of the other nodes of the translation set will be updated before the execution of `hook_node_delete`. However, his approach is too complicated. So I improved "Gert van den buijs" answer to work in all cases. The idea is to preload the translation set in all nodes:

```
/**
 * Implements hook_node_load().
 */
function hook_node_load($nodes, $types) {
  if (!is_array($nodes)) {
    return;
  }
  foreach ($nodes as $node) {
    $node->translation_set = translation_node_get_translations($node->tnid);
  }
}

/**
 * Implements hook_node_delete().
 */
function hook_node_delete($node) {
  if (is_array($node->translation_set)) {
    foreach ($node->translation_set as $del) {
      if ($node->nid != $del->nid) {
        translation_remove_from_set(node_load($del->nid));
        node_delete($del->nid);
      }
    }
  }
}

```

---
Tags: 7, nodes, hooks
---


# Question
Title: How to upload media to S3 using entity browser and Flysystem S3 module
My site is configured to upload media images to S3 using the flysystem module.

However when I want to use the entity browser it's default configuration is to upload images to the filesystem.

Is there a way to change the upload location to use the same S3 location?

What syntax should be used in the "Upload location" field below?

# Answer
Upload location was simply "s3://"
> 2 votes

---
Tags: 8
---


# Question
Title: How to sort taxonomy facets alphabetically in views?
I have created an expose filter using facet indexed field. Added an sort expose filter to it. There is a taxonomy term field. User need to sort that field ASC/DESC alphabetically order.

But it sort depends on taxonomy ID.

# Answer
> 1 votes
For those who drop by here check this issue here

> Just make sure to have "Display value" at top and checked, put the order as "Ascending" and you are good to go!

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


# Question
Title: Output the term title on page--custom.html.twig
I'm pulling my hair out trying to create a custom page--custom.html.twig for a content type and getting taxonomy terms to display.

I'm currently using the following piece of code:

```
{% if node.field_work__services.0 %}
   <ul>
      {% for key, item in node.field_work__services %}
         <li>{{ item.title }}</li>
      {% endfor %}
   </ul>
{% endif %}

```

The if statement resolves, so I get a UL with an equivalent number of LIs to the number of taxonomy terms for that node... however, I can't get it to output the actual taxonomy term.

Anyone have any idea how to do this?

# Answer
Try with:

```
{% if node.field_work__services|length %}
      <ul>
        {% for item in node.field_work__services %}
          <li>{{ item.entity.label }}</li>
        {% endfor %}
      </ul>
{% endif %}

```
> 1 votes

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


# Question
Title: Implement hook_menu_block_tree_alter() to change CSS classes
I have installed the Menu block module. I am very happy with the result, but I'd like to change some classes in the structure.

This is what I get right now.

```
<div class="content">
  <ul class="menu">
    <li class="first last expanded">
      <a class="active" href="http://example.com">News</a>
      <ul class="menu">
        <li class="first last leaf">
          <a class="active" href="http://example.com">Test</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

```

This is what I want.

```
<div class="content">
  <ul id="nav-list">
    <li class="first last expanded has-submenu">
      <a class="active" href="http://example.com">News</a>
      <ul class="sub-menu">
        <li class="first last leaf">
          <a class="active" href="http://example.com">Test</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

```

Basically, I want to:

1. Change the `<ul>`'s classes and attributes (This is level specific, so it's not the same for the primary/secondary `<ul>`.)
2. Add the *has-submenu* class to an `<li>` if it contains another submenu

As explained in Menu Block's documentation, I implemented `hook_menu_block_tree_alter()` in the *template.php* file.

```
function THEME_menu_block_tree_alter(&$tree, &$config) {
  foreach ($tree as $key => &$value) {
    if ($tree[$key]['link']['access'] && !$tree[$key]['link']['hidden']) {
      $items[] = $tree[$key];
    }
  }

  $num_items = count($items);

  foreach ($items as $i => &$data) {
    $class = array();

    if ($data['link']['has_children']) {
      $class[] = 'has-submenu';
    }
    $element['#attributes']['class'] = $class;
  }
}

```

Any help would be much appreciated. I don't really have deep understanding of how and where to implement this hook function. Also my impression is that more detailed documentation is missing for this specific hook.

# Answer
> 0 votes
Other than the regular clear cache I am not sure why that would not be called. I do not have much experience with that hook. However I am fairly certain `theme_menu_link` would work here as well. Take a look at the answer here. A test for `$vars['element']['#below']` should allow you to accomplish what you want.

**Note:** If you have a small menu you can always add classes to menu items through the UI.

**EDIT:** To answer part 1 try something like this (taken from bootstrap\_menu\_link):

```
if ($element['#below']) {
  if ((!empty($element['#original_link']['depth'])) && ($element['#original_link']['depth'] == 1)) {
    // Add our own wrapper.
    unset($element['#below']['#theme_wrappers']);
    $sub_menu = '<ul class="dropdown-menu">' . drupal_render($element['#below']) . '</ul>';
    // Generate as standard dropdown.
    $element['#title'] .= ' <span class="caret"></span>';
    $element['#attributes']['class'][] = 'dropdown';
    $element['#localized_options']['html'] = TRUE;

    // Set dropdown trigger element to # to prevent inadvertant page loading
    // when a submenu link is clicked.
    $element['#localized_options']['attributes']['data-target'] = '#';
    $element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
    $element['#localized_options']['attributes']['data-toggle'] = 'dropdown';
  }
}

```

# Answer
> 0 votes
`HOOK_menu_block_tree_alter(&$tree, &$config)` is not a theme hook. You have to use it in a custom module and then it will work. So if you create a module called "mymodule, then put the following code in the `myModule.module` file, it should print the arguments:

```
/**
 * Alter the menu tree and its configuration before the tree is rendered.
 *
 * @param $tree
 *   An array containing the unrendered menu tree.
 * @param $config
 *   An array containing the configuration of the tree.
 */
function mymodule_menu_block_tree_alter(&$tree, &$config) {
  dsm($config);
  dsm($tree);
}

```

I'm not really sure if you can qualify it further with the menu block name--it didn't work when I tried that. You might have to just conditionally select the menu block you want on that page, if there's more than one.

# Answer
> 0 votes
In the 7.x-2.x branch, that hook is invoked using the following code. (See menu\_block.module.)

```
  // Allow alteration of the tree and config before we begin operations on it.
  drupal_alter('menu_block_tree', $tree, $config);

  // Localize the tree.
  if (module_exists('i18n_menu')) {
    $tree = i18n_menu_localize_tree($tree);
  }

```

Since `drupal_alter()` contains the following code, even a theme can implement that alter hook.

```
// Allow the theme to alter variables after the theme system has been
// initialized.
global $theme, $base_theme_info;
if (isset($theme)) {
  $theme_keys = array();
  foreach ($base_theme_info as $base) {
    $theme_keys[] = $base->name;
  }
  $theme_keys[] = $theme;
  foreach ($theme_keys as $theme_key) {
    $function = $theme_key . '_' . $hook;
    if (function_exists($function)) {
      $functions[$cid][] = $function;
    }
    if (isset($extra_types)) {
      foreach ($extra_types as $extra_type) {
        $function = $theme_key . '_' . $extra_type . '_alter';
        if (function_exists($function)) {
          $functions[$cid][] = $function;
        }
      }
    }
  }
}

```

The theme implementing the hook must be the theme used to render the page, or one of its parent themes. Differently, the alter hook would not be invoked.

The same is true for the 7.x-3.x branch of the module. (See its menu\_block.module.)

If you edited an already enabled theme, or one of its parent themes to add the alter hook, then Drupal will not notice you added a new hook, since it saves in its cache the list of implemented hooks.
For Drupal to notice the new hook, you should visit the page listing all the modules, and install a module that you then uninstall, or disable a module you then re-enable. In this way, Drupal will clear the cache containing the list of the implemented hooks, and it will notice the new hook.

It could also be the alter hook has been implemented for the wrong theme, for example one that is never used for any page, or that is not the parent theme of any theme used for the page shown in your site.

---
Tags: 7, hooks
---


# Question
Title: *.module file not included, even after cache clear
I added a \*.module file to a custom module, to implement some hooks.

I found that the \*.module was never included, even after cache clear (via devel menu "Cache clear". Even putting a "die()" statement at the top of the file did not crash anything.

Only after drush pmu + drush en, was the \*.module file included in every request.

What am I missing? Is this a bug?

# Answer
> 6 votes
Here are my own observations. It contains some details that were not mentioned in @kiamlaluno's answer.

**Things that need rebuilding**

There are two "caches" that need to be rebuilt, if a \*.module file with hook implementations was just created, in a module that previously did not have such a file.

1. The `"container.modules"` container parameter, which we can inspect with `dpm(\Drupal::getContainer()->getParameter('container.modules'));`.
Each entry has a `['filename' => *]` key, which can be either `null` or `'MODULENAME.module'`.
If it is `null`, then Drupal has not found the \*.module file yet, and will not include it when looking for hook implementations.
2. The hook implementations, which we can inspect with `dpm(\Drupal::moduleHandler()->getImplementations($hook_name));`.

**Operations that rebuild those things - or not**

The first part, the container parameter, is not rebuilt on devel cache clear, or on `drush cr`. This has been the real problem.

The second part, the module\_implements cache, is not rebuilt on devel cache clear, but it is rebuilt on `drush cr`.

To rebuild the first part, the container parameters, one can, as suggested by @kiamlaluno, uninstall and re-enable the module with the new hooks. But this can be quite impractical, because uninstalling can cause data loss.

**Solution:**

Luckily there is an easier solution: Enable *any other module* that was previously not installed, and then uninstall it again.

E.g. for me it was "statistics" module. But can be any other.

```
drush pm-list | grep "Not installed"
drush en statistics
drush pmu statistics

```

**EDIT: NOT SO FAST!**

I have to correct myself, for now:

* The above method of enabling and uninstalling any other module does fix the container parameter 'filename' setting, at first.
* However, flushing the cache again afterwards removes the 'filename' setting again.

This means that this setting is stored in a more persistent place somewhere.

**The reason: APCu file cache: cli vs web**

ExtensionDiscovery uses a cache to store discovered extension files. In my case, this is `Drupal\Component\FileCache\FileCache`, with a `Drupal\Component\FileCache\ApcuFileCacheBackend` apcu backend.

The problem: The APCu cache has isolated realms for cli and for web. This means, if the file cache is cleared on cli, e.g. via drush, the entries in web are still there.

This problem seems to apply only to the file cache in ExtensionDiscovery. Other caches are not affected. Probably this is because this file cache sits on a lower level within Drupal bootstrap.

Another part of the problem, possibly, is that the file cache is never cleared completely. At least, I cannot find such a place. Instead, individual entries are deleted by key.

# Answer
> 1 votes
Drupal 8 is not different from Drupal 7: Both versions keep a list of hooks implemented from modules in a cache entry. If you edit the code of an enabled module, Drupal will not know there are new hooks, and they would not be invoked.

To make Drupal check again the hooks implemented by modules, you should clear the cache bin Drupal uses for that purpose, which is not cleared from the *Clear cache* link the Devel module provide, which uses the following code.

```
  /**
   * Clears all caches, then redirects to the previous page.
   */
  public function cacheClear() {
    drupal_flush_all_caches();
    drupal_set_message('Cache cleared.');
    return $this->redirect('<front>');
  }

```

`drupal_flush_all_caches()` doesn't clear the cache bin containing the list of all the hooks implemented by the modules.

Using only the Drupal UI, Drupal 7 will know there are new hooks implemented by a module you edited when you go to the modules page and disable a module, or enable a module (or both the operations, in any order).
Since Drupal 8 doesn't allow to enable/disable modules anymore, you just uninstall the module you edited, and then install it again. Possibly, you uninstall the module before editing its code.

If you want to do it programmatically, you need to clear the *module\_implements* bin, which is the one used from `ModuleHandler::getImplementationInfo()`. Once Drupal is bootstrapped, the code to clear that bin is simply the following line.

```
\Drupal::moduleHandler()->resetImplementations();

```

As side note, keep in mind there are hooks that are invoked in specific cases, and not at every page request. If you create one of them, it's normal not seeing the module being invoked for every page request.

# Answer
> 0 votes
I ran into this with the following steps:

* Installed module from Contrib via `composer require drupal/modulename`
* Enabled module via `drush pm:enable <modulename>`
* *modulename* showed up as enabled at `admin/modules`
* `modulename.module` was not being loaded on HTTP requests (eg I could insert `die('x');` to that `.module` file and the site still loaded OK)
* `modulename.module` *was* however being loaded via Drush (changes to the `.module` file were effective, but only via Drush)

I found the following workaround was effective:

* Uninstall the module via Drush: `drush pm:uninstall modulename`
* Visit `admin/modules` and enable the module via web UI

---
Tags: 8
---


# Question
Title: how to just print the value of author in node template
There are some variables like author\_name in node.html.twig of Drupal 8. `{{ author_name }}` will print something like below:

```
 <div><span><span>Basic</span></span></div>

```

I tried using codes like below: `{{ author_name.0 }} plan to print: Basic` or `{{ author_name|field_value }} plan to print: Basic`

Above codes NOT work. How can I achieve above result?

# Answer
> 2 votes
For most cases How do I get the raw field value in a twig template? will do. But since here according to node.html.twig

> author\_name: **Themed** author name field.

I believe you can get the unthemed author name by using `{{ node.getOwner.getDisplayName }}`

---
Tags: 8, theming
---


# Question
Title: Class not found error on creating a custom service inside a module
I want to create a class with list of helper functions, so I created a module and placed the helper functions inside it. I created a service.yml inside that module folder.

```
services:
  helpers.helpers:
    class: Helpers

```

Helper class file:

```
class Helpers {
   public function buildPage($page_template, $template_variables) {
      echo "Dheivamey oru vazhiya"
   }
}

```

I make it as a dependency inside another module.

```
dependencies:
  - helpers:helpers

```

I tried using it inside a controller file like this

```
public function buildSomePage(Request $request) {
  $helper = \Drupal::service('helpers.helpers');
}

```

But I am getting a **Helpers class not found error**. Someone help me before my head explode.

# Answer
This issue resolved after I included the full namespace from Drupal\module-name and placed the file inside the src folder. I included the namespace earlier, but I missed placing the corresponding "Helper" file in the src directory.
> 0 votes

---
Tags: 8
---


# Question
Title: Hook menu url giving access denied for post method but working for get method
I defined a custom url using hook\_menu and a custom delivery callback that returns json output.

I wanted the url to work on the post method but it is giving access denied for requests done using the post method but it is working without issues for get method.

How do I debug and see why post methods are being denied access?

```
/**
 * @file
 * Implements menu functions for returning json output.
 */

/**
 * Implements hook_menu().
 */
function mymodule_menu() {
  $items['api/json/select/programs'] = array(
    'access callback' => TRUE,
    'access arguments' => array('access content'),
    'page callback' => 'mymodule_api_return_aid_program',
    'delivery callback' => 'mymodule_api_json_output_wrapper',
    'type' => MENU_CALLBACK,
    'access callback' => TRUE,
  );
 return $items;
}

/**
 * Custom page callback function - Retuns the uid of the user on passing
 * valid username and passowrd returns error otherwise
 *
 * @return $uid
 *   Uid of the user on success, NULL if other wise
 *
 * @return $status
 *   success of the user on success, failure if otherwise
 */
function mymodule_api_return_aid_program() {
  try {

    // Fetching the primary parameters
    //product code
    $product = $_POST['product'];
    //country code
    $country = $_POST['country'];
    // language code
    $language = $_POST['language'];

    // age
    //citizenship
    // veteran_status
    $values = _find_product_specific_to_country($product, $country);

    return array('message' => array('nodes' => $values));
  }
  catch(Exception$e) {
    return array('status' => FALSE, 'message' => $e);
    watchdog('Aid API ERROR', $e);
  }
}

/**
 * Custom delivery callback function
 *
 * @param $var
 *   The argument to the delivery callback function
 *
 * @return array
 *   Contains json encoded format of $var on succes,
 */
function mymodule_api_json_output_wrapper($var) {
  // If the access callback is FALSE
  // it will pass MENU ACCESS DENIED to the
  // delivery callback function
    //return drupal_json_output($var);
  if ($var == MENU_ACCESS_DENIED) {

    return drupal_json_output(array('status' => FALSE, 'message' => 'Invalid Token. Access Denied'));
  }
  else {
    return drupal_json_output($var);
  }
}
e

```

# Answer
your code works for me:  Try to move watchdog before return if there is any exception, will log into your report log.
Change your function to like this:

```
function mymodule_api_return_aid_program() {
  try {
    // Fetching the primary parameters
    //product code
    $product = $_POST['product'];
    //country code
    $country = $_POST['country'];
    // language code
    $language = $_POST['language'];
    // age
    //citizenship
    // veteran_status
    $values = _find_product_specific_to_country($product, $country);
    return array('message' => array('nodes' => $values));
  } catch (Exception $e) {
    watchdog('mymodule', 'Aid API ERROR ' . $e->getMessage(), array(), WATCHDOG_NOTICE, NULL);
    return array('status' => FALSE, 'message' => $e->getMessage());
  }
}

```

**Update: debug**
Getting `access denied` maybe another module add/alter your menu and add another `access arguments` then `access content` so in your callback function print you menu object and see something like :

```
  $menu_item = menu_get_item('api/json/select/programs');
  // print the menu array
  print_r($menu_item);
  // Print access arguments
  print_r($menu_item['access_arguments']);
  // Print access callback
  print_r($menu_item['access_callback']);

```
> 3 votes

# Answer
You need to setup a REST API endpoint and assign/authorize it to use the POST API calls. the `/api` should be setup as a REST API endpoint on your website first. Follow this guide on how to use the Services module.

Update: Do not forget to use the CSRF token with a POST request. Check the guide above for more details on how to obtain that.
> -1 votes

---
Tags: 7
---


# Question
Title: How to change a field value in a product variation when someone edited the order manually?
I had implemented a "Event Subscriber" controller to change the stock value in the product variation. Stock is a field in product variation.

Depending upon the quantity in order items I am decreasing the value of stock by subscribing to Drupal 8 event order `$events['commerce_order.place.post_transition']`. Similarly I increased stock value if he cancels the order using the event `$events['commerce_order.cancel.post_transition']`.

***If somebody revise the order quantity from Back-office that time, stock should be increased or decreased accordingly. How can we achieve that? Is there any event when order items is edited? we are currently decreasing stock when order is placed... how can we decrease/increase when somebody edit the order from backend manually?***

# Answer
> 1 votes
> Is there any event when order items is edited?

You could use hook\_ENTITY\_TYPE\_update

```
/*
 * Implements hook_ENTITY_TYPE_update()
 */
function mymodule_order_update(\Drupal\commerce_order\Entity\OrderInterface $order) {
  // your code goes here
}

```

---

If you don't want to use a hook, then consider using the Hook Event Dispatcher module.

> This module dispatches events for several Drupal core hooks. This allows you to use the D8 Event Subscriber system, instead of the outdated hook system, to react on certain events. The module includes events for the most common hooks.

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


title: Solr search views cache issue

text:
# Question
Title: Solr search views cache issue
I have views for solr search result and I have highlight processor enabled. There seems to be cache issue effecting search result. Search results are rendered array of entities. For example: If I search 'content'. I see my result highlighting word 'content' correctly but when I search for result 'extraction', in the page with both words 'content' and 'extraction', it highlights 'content'. I used

```
\Drupal::service('page_cache_kill_switch')->trigger();

```

in views pre\_render but didn't work as expected. Views advanced setting already has caching set to none.

Can anyone help me disabling cache for this particular view?

Thank you.

# Answer
> 2 votes
When you go to /admin/config/search/search-api and then click to edit your index, there is a checkbox for "Index items immediately" under the "Index Options" section. That is the only way I've found to get Solr Views to output new content immediately after it's created.

# Answer
> 0 votes
Issue was it was entity cache interfering with result. So, I ended up invalidating cache for entities when it is search result using hook\_entity\_view\_alter. This might not be good idea but it fixes the problem. I am considering going with javascript approach to highlight so that I don't need to invalidate cache.

```
$build['#cache']['max-age'] = 0;
\Drupal::service('page_cache_kill_switch')->trigger();

```

---
Tags: views, 8, search, caching
---


title: Filter nodes by entity reference

text:
# Question
Title: Filter nodes by entity reference
I have an `article` content type linked to an `event` content type via entity reference.

In the `Articles` view, I would like to offer a filter allowing to filter articles by linked event title.

With Drupal 7, we used to manage it with better\_exposed\_filters module but I can't find a way to do it in Drupal 8.

# Answer
> 6 votes
Here is the my solution inspired from:

Thanks to Danny Sipos

I already had a dedicated custom module for this project where I added the following:

`mymodule.views.inc`

```
<?php
/**
 * Implements hook_views_data_alter().
 */
function mymodule_views_data_alter(array &$data)
{
    $data['node_field_data']['related_content_titles'] = array(
        'title' => t('Related content titles'),
        'filter' => array(
            'title' => t('Related content titles'),
            'help' => t('Specify a list of titles an content node can have.'),
            'field' => 'nid',
            'id' => 'mymodule_related_content_titles'
        ),
    );
}

```

`src/Plugin/views/filter/RelatedContentTitles.php`

```
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\filter\ManyToOne;
use Drupal\views\ViewExecutable;

/**
 * Filters by given list of event title options.
 *
 * @ingroup views_filter_handlers
 *
 * @ViewsFilter("mymodule_related_content_titles")
 */
class RelatedContentTitles extends ManyToOne
{
    /**
     * {@inheritdoc}
     */
    public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL)
    {
        parent::init($view, $display, $options);
        $this->valueTitle = t('Allowed event titles');
        $this->definition['options callback'] = array($this, 'generateOptions');
    }

    /**
     * Helper function that generates the options.
     * @return array
     */
    public function generateOptions()
    {
        $storage = \Drupal::entityManager()->getStorage('node');

        $relatedContentQuery = \Drupal::entityQuery('node')
            ->condition('type', array('event', 'story'), 'IN')
            ->condition('status', 1);

        $relatedContentIds = $relatedContentQuery->execute();

        $res = array();
        foreach ($relatedContentIds as $contentId) {
            $res[$contentId] = $storage->load($contentId)->getTitle();
        }

        return $res;
    }
}

```

When ceating the view listing my articles where I want to expose the `related event` filter I had to :

* add a relationship `field_article_associated_event: Content`
* add a filter criteria of my type `Related content titles`, select the perviously cerated relationship for the field `Relationshi`, check `Expose this filter to visitors, to allow them to change it`

# Answer
> 0 votes
You can use the Entity Reference Exposed Filters module.

> A module for those who need their Entity Reference Exposed Filters to have titles in Select Lists.

---
Tags: 8, views
---


# Question
Title: Programmatically fill the "Publish On" date field value provided by the Scheduler Module
I'm using the Scheduler Module to schedule the publishing date of the content in my Drupal 8 site. I would like to programmatically fill the value of the **Publish On** date field provided by the scheduler module.

In Drupal 7, I used the following code

```
function hook_form_alter (&$form, $form_state) {
     $date_format = (_scheduler_use_date_popup()) ? SCHEDULER_DATE_FORMAT : variable_get('scheduler_date_format', SCHEDULER_DATE_FORMAT);

      $form['scheduler_settings']['publish_on']['#default_value'] = format_date($querydate, 'custom', $date_format);
}

```

This code doesn't work in Drupal 8, since the **\_scheduler\_use\_date\_popup()** function and the **SCHEDULER\_DATE\_FORMAT** constant are not available.

I'm using the following code in Drupal 8 which doesn't work:

```
function hook_form_id_alter(&$form, FormStateInterface $form_state) {
    $form['scheduler_settings']['publish_on']['#default_value'] = \Drupal::service('date.formatter')->format($contest_start_date, 'custom', 'Y-m-d H:i:s');
}

```

# Answer
> 2 votes
You should be able to provide a default value using a `hook_field_widget_form_alter()` to modify the `#value_callback` of the `TimestampDatetimeNoDefaultWidget` that scheduler uses to a custom one, and this is how you can pass custom logic for a default value. Here's some sample code that could go in your custom module, you could add/modify conditions and logic as needed, but this should at least get things moving in the right direction:

```
<?php

/**
 * @file
 * Publish On Default module file.
 *
 * This module provides a default value for the "Publish On" value
 * for nodes.
 */

use Drupal\Core\Datetime\Element\Datetime;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\scheduler\Plugin\Field\FieldWidget\TimestampDatetimeNoDefaultWidget;
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_field_widget_form_alter().
 */
function mymodule_field_widget_datetime_timestamp_no_default_form_alter(&$element, FormStateInterface $form_state, $context) {
  // Only alter the callback for the "Publish On" instance of the `datetime_timestamp_no_default` widget.
  if (isset($element['#title'])) {
    if ($element['#title']->__toString() == "Publish on") {
      $element['value']['#value_callback'] = 'mymodule_publish_on_default_value_callback';
    }
  }
}

/**
 * Callback function to add default time to the publish on widget.
 */
function mymodule_publish_on_default_value_callback(&$element, $input, $form_state) {
  // If no default value, set the default to the current date/time.
  if (empty($element['#default_value'])) {
    $date_format = $element['#date_date_format'];
    $time_format = $element['#date_time_format'];
    $timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL;
    $date_time_format = trim($date_format . ' ' . $time_format);
    $date_time_input = date('Y-m-d H:i:s');
    $date = DrupalDateTime::createFromFormat($date_time_format, $date_time_input, $timezone);
    $element['#default_value'] = $date;
    $input = FALSE;
    return Datetime::valueCallback($element, $input, $form_state);
  }
  // Fallback to the original valueCallback() method.
  else {
    return TimestampDatetimeNoDefaultWidget::valueCallback($element, $input, $form_state);
  }
}

```

---
Tags: 8
---


# Question
Title: Managing multiple versions of files on nodes
The client needs to be able to upload numerous files to each node. They would like only the new versions of files to be searchable/in the search results and for the previous document versions to be versioned, available on the page but not searchable.

I was thinking of adding a file field type to the content type with unlimited number of values. But I cannot figure out a way to disable the search from searching through the previous version.

Any tips on how to do this would be greatly appreciated.

# Answer
You could try either Revision All

> Revision All allows for centralized management of content type revisioning. Revisioning can be turned on/off individually by type or enabled for all simultaneously. There is also support for enabling automatic revisioning of future content types and the disabling of the "create new revision" checkbox on node and/or content type forms.

or Document modules

> A Document Management System for Drupal.

Features:

1. Complete integration with Drupal node system. This module adds a custom Node Type, Document. Each Document you create is a Drupal node, and hence enjoys all features available to a node.
2. Support for Document revisions/versioning - This module allows you to maintain multiple versions/revisions of the same document.
3. Views 2 Integration - The custom fields added by the module to the Document node type are accessible in Views, plus the module provides some useful out-of-the box Views.
4. Theming support
5. Searching - The documents being nodes are fully indexable by the Drupal search system. In addition, the module provides its own custom search for Documents.
6. A couple of blocks are available for document search that can be placed flexibly in your theme layout.
> 1 votes

# Answer
This information appears out-dated. Please review the media initiative for Drupal 8:

https://dri.es/a-plan-for-media-management-in-drupal-8 https://dri.es/an-update-on-the-media-initiative-for-drupal-8-4-8-5

Also check out Lightning: https://www.drupal.org/project/lightning

Thunder: https://dri.es/thunder-a-drupal-distribution-for-publishers

and NP8: https://www.md-systems.ch/en/blog/md-systems/2016/08/09/md-systems-introduced-np8-to-the-big-apple
> 0 votes

---
Tags: files
---


title: Increase session timeout

text:
# Question
Title: Increase session timeout
So I have a requirement that I'm getting close to stumped on how to complete in Drupal 8.

I'm going to attempt to simplify the requirements. I have two roles. They are essentially mutually exclusive. Let's call them "Internal" and "Client".

The request is to have Clients logged in for an indefinite period of time... let's call it *years*. Internal users need to be logged in for a short period of time, say 1 day, or even just the session. (*Note: I didn't make these requirements, just coding them... haha*)

My understanding of the Drupal login is that there are really two things controlling this... there is the cookie lifetime of a user, and the session lifetime (on the server). If I set the cookie lifetime to 1 week, but the session lifetime is 1 day, the user will essentially be logged out after 1 day, b/c their cookie will match a session that doesn't exist after a day... is that right?

So, I think I have to start with the upper limit. If I want my user to be logged in for 1 year, I need my server session to be 1 year. One of my questions is: **what are the risks/downsides/etc to setting my server session to 1 year?** Let's say my server gets 50k visits a month. What if it's not 1 year, and I want it at 2 years? I can't seem to find a definitive guide to what the upper limit of server session should be? It seems like there's a lot of factors that could clear out that session as well...

Ok, so the above is one question... assuming I can set the server session, how can I have the cookie lifetime visit based on user role? I'm getting to the point where it seems like it just might not be possible to vary this setting, and I might have to do some kind of route subscriber and custom cookies and whanot to detect the internal users, and log them out when I see they've been logged in too long...

Any help would be much appreciated...

# Answer
> 2 votes
I have achieved this goal in the past for Drupal 7 using a bit of custom code.

1. Set the cookie lifetime and server session timeout to the larger of the 2 numbers, in your case I guess that's 2 years.
2. Write a custom script (e.g. in drush) that will find stale sessions and delete them.

For item #2 for you that means it has to find the Internal users with a short lifetime and delete their session if the `sessions.timestamp` is beyond a limit. According to `system.install`, that column contains `The Unix timestamp when this session last requested a page.`

The limit of your sessions table depends on database server hardware, but my experience on a fairly large site is that you can have millions of sessions records and it's not a huge problem for performance. That said, I also found that user interaction followed a power-curve. 90% of users who committed and got engaged did so within the first day. 95% were within the first week and going out to 3 months got up to 98%. Saving the cookie data beyond that for what amounts to a rounding error is generally not super useful.

I found that trying to do a sql delete directly does not scale well. Instead, I wrote a loop that would find records to delete and then run individual delete queries with a condition `WHERE sid = :sid` so it was using a primary key. This had the greatest performance while having minimal impact. You can even run the select against a read-replica database to reduce the performance impact further. For my scenario, 1 class of users who had not been active in the last hour were logged out so that job ran every hour. The other class of users who got deleted after 3 months would be deleted in a job that ran overnight as it performed more operations and had more impact on server resources.

If you truly need to store session data for 2 years that's fine. However, you might consider if you can instead store the data in the cookie instead of in the session. That way your sessions table stays lightweight and you can still do tracking of the user inside the cookie. For example, if your goal is to track a channel that brought the user to the site you could simply store that channel information in their cookie instead of the `$_SESSION`. If you can avoid generating/keeping a session then the scalability problem goes away.

Beware that many spiders and bots generate significant traffic and are poorly behaved a it relates to sessions: they may discard cookies, effectively generating a new session for every page request if your app does that. You can either place a bot-blocking/caching network in front (like Cloudflare) or just plan to periodically analyze the sessions table and delete sessions from these bots based on something like IP address.

I would not suggest memcache for this purpose, but instead a sql database (perhaps a dedicated database instance) or Redis. Memcache is optimize as a temporary data store. You purposefully want a persistent data store, which sql or redis do provide.

# Answer
> 0 votes
**Approach one,**

1. Increase the session and cookie lifetime as required.
2. Move session from file-based sessions to Memcached. This can be done in php.ini.

So basically you give the longest session for all users. And then maybe you can write a rule or cronjob for invalidating sessions of the users of the roles you need shorter span.

**Approach two, I guess better** https://www.drupal.org/project/persistent\_login

See: http://www.jaspan.com/improved\_persistent\_login\_cookie\_best\_practice

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


# Question
Title: How to make author name hyperlinked to its profile in node template
There is a variable `{{ author_name }}` in node.html.twig, it will print something like below:

```
<span>Your author name</span>

```

But I would like to print something like that:

```
<a href='/user/10'>Your author name</a>

```

How can I get this done in node.html.twig?

# Answer
> 5 votes
Normally `{{ author_name }}` already comes as renderable markup containing the linked author name. But there's also `{{ node.getOwnerId }}` (the author's user ID) and `{{ node.getOwner.label }}` (the author's user name) you could simply use to build the link yourself.

```
<div class="foobar">
  <a href="/user/{{ node.getOwnerId }}">
    <span>{{ node.getOwner.label }}</span>
  </a>
</div>

```

Note you can easily inspect what variables are available for a template by installing the Devel sub-module Kint and then in your template print `{{ kint() }}`, flush cache and reload. You now will get all available variables pretty-printed to easily find out which ones you could use to solve your problem.

---

To make that snippet a little bit more sustainable use the `path()` function to build the link target. By that also path aliases (built with Pathauto for example) will be taken into account.

```
<div class="foobar">
  <a href="{{ path('entity.user.canonical', {'user': node.getOwnerId}) }}">
    <span>{{ node.getOwner.label }}</span>
  </a>
</div>

```

# Answer
> 3 votes
Use `{{ node.getOwnerId() }}`.

```
<a href='/user/{{ node.getOwnerId() }}'>Your author name</a>

```

---
Tags: 8, theming
---


# Question
Title: Which events are invoked when an order is removed or cancelled?
I have already an event subscriber class with *commerce\_order.place.post\_transition* defined. I need to remove nodes when an order is deleted or canceled.

What event could I use in that case?

# Answer
> 2 votes
```
$events = [
  // State change events fired on workflow transitions from state_machine.
  'commerce_order.place.post_transition' => ['onOrderPlace', -100],
  'commerce_order.cancel.post_transition' => ['onOrderCancel', -100],
  // Order storage events dispatched during entity operations in CommerceContentEntityStorage.
  // ORDER_UPDATE handles new order items since ORDER_ITEM_INSERT doesn't.
  'commerce_order.commerce_order.update' => ['onOrderUpdate', -100],
  'commerce_order.commerce_order.predelete' => ['onOrderDelete', -100],
  /* OrderEvents::ORDER_ITEM_UPDATE => ['onOrderItemUpdate', -100],
  OrderEvents::ORDER_ITEM_DELETE => ['onOrderItemDelete', -100], */

  'commerce_payment.filter_payment_gateways' => ['onPayment', -100],
  ];
return $events;
}

```

# Answer
> 0 votes
You can use $events\['commerce\_order.cancel.post\_transition'\] for subscribing to order cancel event.

---
Tags: commerce, event-subscribers
---


title: Plugins before event subscribers

text:
# Question
Title: Plugins before event subscribers
Not sure if there's a way out of this problem but...

I have a custom log module which listens for events that could come from multiple sources. All it does is listen for an event, and if it occurs logs an entry in the DB.

But there could be different recorded data coming from different modules and I want to separate concerns so there's no complex web of dependencies.

If Module L is the listener it might get EventA from module A and EventB from module B. The events have a common base but each module stores slightly different data in the log which needs to be set-up in each case.

**Option 1)** Module L could be set up to listen for "module\_a.event" and "module\_b.event" and process them separately but that is a "bad thing" because the listener is dependent on each of the other modules. The Listener shouldn't need to know how the data is stored, it doesn't care.

**Option 2)** Or Module L could have a specialised event "listener.event" that Module A and Module B calls having set up the data in the event correctly. But that means those modules have a dependency on the listener.

I don't like either option because of the dependency requirements in one direction or the other.

**Bright idea:** Create a plugin in Module L that builds the log structure for a particular module. So Module A has a plugin that handles its requirements, and Module B has another plugin that handles its needs.

There's no dependency in either direction because if Module L is not running then A and B don't care (the plugins will never be scanned or loaded). And if either or both of A and B are missing, Module L doesn't care.

And if I then need a Module C I just give it its own plugin.

But Module L still needs to listen for events from A, B and C (module\_a.event, module\_b.event and module\_c.event). How does it know what events it should listen for?

Easy: Set a value in the annotation of each plugin giving the name of the event to listen for. We can load all the plugin definitions in the EventSubscriber and set it up. Fantastic. Problem solved. No dependency but every event type can be listened for and handled.

Except it doesn't work because: apparently event subscribers are initialised before plugin services.

My "module\_l.services.yml" looks like this:

```
services:
  notifications_log.notifier:
    class: Drupal\notifications_log\EventSubscriber\NotifierSubscriber
    arguments: ['@plugin.manager.notifier', '@entity_type.manager',
                '@current_user', '@logger.factory']
    tags:
      - { name: event_subscriber }

  plugin.manager.notifier:
    class: Drupal\notifications_log\Plugin\NotifierManager
    parent: default_plugin_manager

```

Which seems fine (doesn't matter which way round they go BTW - I've tried) but we get a fail here, in the EventSubscriber:

```
  static function getSubscribedEvents() {
    /** @var NotifierManager $notifierManager */
    $notifierManager = \Drupal::service('plugin.manager.notifier');

    $events = [];
    foreach ($notifierManager->getNotifierEventNames() as $eventName => $plugin_id) {
      $events[$eventName] = ['onNotification', 0];
    }

    return $events;
  }

```

This is a static function so we have to fetch the plugin manager directly, and it can't find it.

Is there any way around this? I could find write some code to find all the plugins myself but that's a lot of faffing about.

What I really need is a way of dynamically adding to the Event subscribers, but I haven't found a way to do that.

If I could carry the plugin\_id across as well, that would be useful but it's not a big problem to find the right plugin in the "on Notification" method.)

# Answer
The solution to the the problem is to dynamically add event subscribers later in the page load process, so for example:

```
  /**
   * {@inheritdoc}
   *
   * We can't return the plugin-based events here, but we set up
   * a response to do that at a later stage
   *
   */
  static function getSubscribedEvents() {
    // Subscribe to kernel request very early.
    $events[KernelEvents::REQUEST][] = ['onRequest', 900];

    return $events;
  }

  /**
   * Add the plugin events at this stage - early in the process.
   *
   * @param GetResponseEvent $event
   */
  public function onRequest(GetResponseEvent $event) {
    // Find every event mentioned in a plugin...
    foreach ($this->notifierManager->getNotifierEventNames() as $eventName => $plugin_id) {
      // Add the event to the dispatcher as a listener, to call that routine...
      $this->dispatcher->addListener($eventName, [$this, 'onNotification']);
    }
  }

```

The list of event names is cached in `getNotifierEventnames()`.
> 0 votes

---
Tags: 8, plugins, event-subscribers
---


title: htaccess for Angular app in a subfolder

text:
# Question
Title: htaccess for Angular app in a subfolder
I have an Angular 6 app living in a subfolder on a D8 installation. I have no issues navigating to the app and the angular routing doing it's thing as I navigate the app. My issues is I get a Drupal 404 if I try to hit the sub routes directly in the address bar.

What do I need to add to my htaccess that will let Drupal ignore the folder and the angular routing still work?

Drupal: `localhost:8888`

Angular: `localhost:8888/my-app`

**Things I've tried:**

Adding: `RewriteCond %{REQUEST_URI} !^/my-app/.*$` **\<- I get Not Found**

Changed `DirectoryIndex index.php index.html index.htm` to `DirectoryIndex index.php`

Adding the following to httpd.conf:

```
<Location "/my-app">
 FallbackResource /my-app/index.html
</Location>
<Directory /my-app>
 FallbackResource disabled
</Directory>

```

# Answer
> 1 votes
You need to add the following rewrite in your Drupal .htaccess

```
RewriteCond %{REQUEST_URI} !/APP-FOLDER-NAME/.*

```

Then in the root of the angular application folder you need the following in your .htaccess

```
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) /APP-FOLDER-NAME/index.html [NC,L]

```

---
Tags: .htaccess
---


# Question
Title: How to override a module theme function in a custom module but still allow themes to override the template file?
I'm writing a fairly simple module which allows the removal of colons from field output on a per field basis and I need to override the core field module's theme\_field function in my module.

I can modify the theme registry with hook\_theme\_registry\_alter() and change the field function to point to my custom function. Unfortunately once I do that I'm no longer able to override field.tpl.php in a theme.

The cascade I'd like to achieve is in order of template preference (most important first):

1. Active theme's field.tpl.php
2. My custom module's field.tpl.php (or custom\_field theme function)
3. Field module's theme\_field function

Is this possible?

This answer comes close but requires a differently named template which I don't want. I'd like to keep things clean for the themer so if they override field.tpl.php in their theme the output is as expected, rather than having to copy a different tpl file from my custom module.

# Answer
Think what you describe could work without falling back to the field module's function:

1. Add `<?php function MODULENAME_preprocess_field($variables) ?>` and set a $colon variable with either `':'` or `''`
2. Copy the theme\_field function in your module and rename it `<?php MODULENAME_field(&$variables) ?>`
3. Replace the code that renders the label with: `<?php $output .= '<div class="field-label"' . $variables['title_attributes'] . '>' . $variables['label'] . $variables['colon'] . ' </div>';?>`

Might also just document for themers that in the template file they should use $colon for the module to work.
> 0 votes

# Answer
There are multiple ways to achieve this. I am just going to post from the top of my head.

## Replacing the theme function

> I can modify the theme registry with hook\_theme\_registry\_alter() and change the field function to point to my custom function. Unfortunately once I do that I'm no longer able to override field.tpl.php in a theme.

You can use hook\_theme\_registry\_alter() for this. You just need to make it conditional. Something like this:

```
function mymodule_theme_registry_alter(&$registry) {
  if (!isset($registry['field'])) {
    // Perhaps field module is not even enabled, or something else is wrong.
    return;
  }
  if (!isset($registry['field']['function'])
    || 'theme_field' !== $registry['field']['function']
    || isset($registry['field']['template']
  ) {
    // Apparently a theme has overridden the theme hook.
    return;
  }
  // Override with custom module-based template.
  $registry['field']['template'] = ...
}

```

This has a limitation if other modules or the theme itself also use hook\_theme\_registry\_alter() to modify the same hook. But otherwise it should be ok.

You need to experiment a bit with the code above, I wrote this without any testing. Let me know if something can be corrected.

## About the "cascade"

Some additional explanation.

> The cascade I'd like to achieve is in order of template preference (most important first):
>
> * Active theme's field.tpl.php
> * My custom module's field.tpl.php (or custom\_field theme function)
> * Field module's theme\_field function

The good thing is that this cascade is rather "fixed". The theme registry is stored and calculated per theme, and within a theme the cascade always has the same outcome. The theme template either exists or not. The template in your custom module always exists. So the "Field module's theme\_field function" is completely out of the picture.

It gets a bit more complicated if we are dealing with theme overrides like field--body.tpl.php, but we don't need to go into his territory here I think.

## Alternative: Display suite field templates

> I'm writing a fairly simple module which allows the removal of colons from field output on a per field basis and I need to override the core field module's theme\_field function in my module.

I should point out that alternatives exist to what you attempt to achieve.

Display suite is an excellent module which provides settings for how a field should be rendered. Especially, if you enable ds\_extras, go to admin/structure/ds/list/extras, and enable "Field Templates". This is a very powerful tool worth learning more about.

Renderkit has "field display processor" plugins, but this goes far beyond what you probably need.
> 0 votes

---
Tags: 7, theming
---


# Question
Title: How can I override the Calendar module's theme functions?
I'm trying to override Calendar module's theme functions. Specifically, I'm trying to override `template_preprocess_calendar_month()` and `template_preprocess_calendar_mini()`.

The override seems to work, but the problem is that the variables are processed/modified by `template_preprocess_calendar_month()` and `template_preprocess_calendar_mini()` before they reach the functions I implemented.

I need access to some of the theme variables before they are processed. Is there a way to do so?

# Answer
You can create your own custom module and define your own copies of these preprocess functions.

For this example we'll call your module `mysite`.

In your mysite.module file you would define:

```
mysite_preprocess_calendar_mini(&$variables)
mysite_preprocess_calendar_month(&$variables)

```

And then modify the contents of the variables in these functions as needed. Copying the existing preprocess functions might be a good place to start if you're not sure what you want to modify.

Check out the preprocess documentation for some more information about how this system works.
> 1 votes

# Answer
You cannot, since `template_preprocess_calendar_month()` is executed before `mytheme_preprocess_calendar_month()`, assuming that *mytheme* is the machine name of the theme you implemented.

The order of execution of those functions is described in the documentation for `theme()`, which shows the following order, where *MODULE* is the machine name of any enabled module, *ENGINE* is the machine name of the theme engine used, and *THEME* is the machine name of the theme used to render the page.

* `template_preprocess(&$variables, $hook)`
* `template_preprocess_HOOK(&$variables)`
* `MODULE_preprocess(&$variables, $hook)`
* `MODULE_preprocess_HOOK(&$variables)`
* `ENGINE_engine_preprocess(&$variables, $hook)`
* `ENGINE_engine_preprocess_HOOK(&$variables)`
* `THEME_preprocess(&$variables, $hook)`
* `THEME_preprocess_HOOK(&$variables)`
> 1 votes

# Answer
It may help to play with the modules weight (execution order). Switching the execution order of the custom module and the calendar module might help.

The order may be changed at the system table (e.g. `update system set weight = -10 where name='mymodule'`) , or via the modules\_weight module.
> 0 votes

---
Tags: theming
---


title: Display custom variables

text:
# Question
Title: Display custom variables
We have a twig template, `node--page.html.twig` where we want to display the custom variable `ns-custom-template`. The variable is created from a custom module, `mymodule` with the following code below.

**How can I create a variable, populate it using the `ns-custom-template` variable, and display it in the `node--page.html.twig` template?**

Here is what I tried, but when using `kint(test_var)` I get `NULL` returned.

**mymodule.module**

```
function mymodule_theme($existing, $type, $theme, $path) {
  return [
    'ns_custom_template' => [
      'variables' => [
        'test_var' => NULL,
      ],
    ],
  ];
}

```

**Inside mymodule's template folder is `ns-custom-template.html.twig`**

```
<p> Testing my variable {{ test_var }} </p>

```

**MyModuleController class**

```
class MyModuleController extends ControllerBase {
  public function content() {
    $config = $this->config('mymodule.settings');
    $config_value = $config->get('my_config_value');
    return [
      '#theme' => 'ns_custom_template',
      '#test_var' => $config_value,
    ]
  }
}

```

**mymodule's routing file:**

```
mymodule.module_controller_content:
  path: '/mymodule/content'
  defaults:
    _controller: '\Drupal\mymodule\Controller\MyModuleController:content'
    _title: 'content'
  requirements:
    _permission: 'access content'

```

**MyModuleForm**

```
class MyModuleForm extends ConfigFormBase {
  protected function getEditableConfigName() {
    return [
      'mymodule.setting',
    ],
  }

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

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('mymodule.setting');
    $form['my_config_value'] = [
      '#type' => 'textarea',
      '#title' => $this->t('My config value'),
      '#description' => $this->t('Enter some value'),
      '#default_value' => $config->get('my_config_value'),
    ];
    return parent::buildForm($form, $form_state);
  }

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

    $this->config('mymodule.setting')
      ->set('my_config_value', $form_state->getValue('my_config_value'))
      ->save();
  }
}

```

**node--page.html.twig**

```
<article>
  {{ ns_custom_template }} {# returns null #}
  {{ kint(ns_custom_template }} {# returns null #}
</article>

```

For reference, I am trying to emulate the steps on Define a custom template for module output page.

# Answer
> 2 votes
The variable you are looking for is not `ns_custom_template` but `test_var`

To get all variables in your twig file, you can try `{{ kint() }}`

To get the variable you have previously declared in `mymodule_theme`, you can try `{{ kint(test_var) }}`

BUT there is another mistake:

The twig file in which you will find `test_var` is not `node--page.html.twig` but only `ns-custom-template.html.twig`

if you want to have `test_var` inside `node--page.html.twig`, you can use a preprocess function : function template\_preprocess\_node with a code like:

```
$var['test_var']='my value';

```

EDIT:It seems that you would like to use the template `ns_custom_template` in a node template: to achieve this, you need to populate your variable `test_var` with a render array having the name defined in `mymodule_theme` as a value of the `#theme` key.

```
function mymodule_preprocess_node(&$var) {
  $var['my_free_var_name'] = ['#theme' => 'ns_custom_template', '#test_var' => 'your value'];
}

```

After doing this, you can display your template inside `node--page.html.twig` bu using the following code:

```
{{ my_free_var_name }}

```

# Answer
> 0 votes
if you want to display twig template inside another, for instance `ns-custom-template.html.twig` inside `node--page.html.twig` you should use `include` instead of `{{ some-twig-name }}`:
In your case **node--page.html.twig** will be something like:

```
<article>
  {% include  '/modules/custom/mymodule/templates/ns-custom-template.html.twig' %}
</article>

```

I assume that your module reside in `/modules/custom` folder.

---
Tags: theming
---


# Question
Title: How to get a rendered output field from view object programatically
I can get the value of the field from the view object like this:

```
foreach ($view['#view']->result as $row){
      $field_slide_banner = $row->_entity->get('field_slider_banner')->getValue();
    }

```

However, in this case I get the target\_id of the referenced image file, but I need to get the full rendered output data, which depends on format that I set for this field at the view display, for example, that should be the URL of the image in my case.

In other words, I want to be able to get final output data or HTML markup programmatically for any view field from the given row of executed view object.

# Answer
> 3 votes
Use the following code.

```
foreach ($view->result as $row) {
  // Change the full view with your view mode.
  $render_array = $row->_entity->field_slider_banner->view('full');
  $field_slider_banner_markup = \Drupal::service('renderer')->renderRoot($render_array);
}

```

Alternatively, you can use the following code.

```
foreach ($view->result as $id => $row) {
  $my_field_value = $view->style_plugin->getFieldValue($id, 'field_name');
}

```

---
Tags: views, 8
---


# Question
Title: Programmatically alter a field collection field item not yet saved in the database
Updating field collection field item gives error when one item is added.

I have the following code which works well when just changing values of a field already saved in the database but if I add a new field collection item to the node it throws an error (I guess because the value hasn't been saved yet in the database)

> EntityMetadataWrapperException: Unknown data property field\_date :

```
function pdf_app_node_presave($node) {

 $node_wrapper = entity_metadata_wrapper('node', $node);

foreach ($node_wrapper->field_chapitres->value() as $library) {
$library_wrapper = entity_metadata_wrapper('field_collection_item', $library);
 $library_wrapper->field_pdf_title->set('newtitle');
                $library_wrapper->save();
  }
 unset($library);
 }

```

# Answer
> 1 votes
I might try removing `$library_wrapper->save()`. Calling `$entity_wrapper->save()` within `hook_node_presave()` is problematic for the exact reason you're stating -- the field collection item doesn't exist yet so it doesn't have the data needed to allow it to be created/saved. Calling `$entity_wrapper->save()` inside of `hook_node_presave()` can also sometimes cause issues on its own. By setting the value but not saving it, it should act as though you entered the value in the field on the edit form and should be saved when the parent node is saved.

Alternatively, you might try `hook_node_update()` or `hook_node_insert()` instead of `hook_node_presave()`. These fire later in the saving process, at which point your field collection item may already exist, in which case you won't have any problem saving it

---
Tags: database
---


title: REST: 403 forbidden for file entities

text:
# Question
Title: REST: 403 forbidden for file entities
Ok, so this is a weird one...

I have a HEADless Drupal that I'm using to serve webform submissions. The webform module stores all files as private files.

The issues I'm having is if I view the submission in the angular app as the user that submitted the webform (owner) all the files come back fine. If I try to view the submission as a different user the files come back 403 forbidden. All of the other REST data comes back fine.

Then if I go back and view the submission as the owner again the files are now 403 forbidden for the owner as well. The only way I can get the owner to get a 200 response and see the files again is to flush the cache.

Other users viewing those files seem to lock the files down for the owner as well.

Viewing the webform submission in the actual Drupal has no issues.

# Answer
> 0 votes
Well, found my issue. I didn't enable the File entity module under Media which exposes the permission I needed to set for viewing private files.

---
Tags: files, webforms
---


# Question
Title: How do I programmatically load an order by its properties?
I know how to load an order by its ID using `\Drupal\commerce_order\Entity\Order::load($order_id)`. I added a custom field (*Token ID*) to the orders.

How can I load the orders knowing the value of that field? If I want to get the state of the order, how can I achieve it?

# Answer
The best way to do this is by using by `loadByProperties` based on Token field:

```
$orders = \Drupal::entityTypeManager()
  ->getStorage('commerce_order')
  ->loadByProperties(['field_token_id' => 'TOKEN VALUE']);
$order = reset($orders);
$state = $order->get('state')->value;
$total_price = $order->getTotalprice()->getNumber();
$currency = $order->getTotalprice()->getCurrencyCode();

```

Here assuming token as a unique value.
> 7 votes

# Answer
you will need to use Drupal EntityQuery to get the order id and load order using its id, the following code might help :

```
$query = \Drupal::entityQuery('commerce_order')
->condition('field_token_id.value', VALUE_OF_TOKEN);
$order_ids = $query->execute();
foreach($order_ids as $order_id) {
  \Drupal\commerce_order\Entity\Order::load($order_id);
}

```
> 5 votes

# Answer
I believe the Most efficient and Fast way to get all the Orders is

```
$orders = \Drupal::entityTypeManager()->getStorage('commerce_order')->loadMultiple();

```

if you want to get the Completed Orders then you can use the loadByProperties() as like:

```
$orders = \Drupal::entityTypeManager()->getStorage('commerce_order')->loadByProperties(['state' => 'completed']);

```
> 4 votes

---
Tags: 8, commerce
---


# Question
Title: Update the date field to the date & time of the node being updated
I am sure that I am missing something very simple here, so I hope somebody can put me on the right track.

**Use Case:**

1. I have a simple content type **"Article"**
2. A date field of type: "Date and Time" is attached to this content type.
3. Using any of "Rules" or "Business rules" module, I need when updating a node of type "Article", **to set the value of the "date field" to be equal to the "date and time" of the node being updated.**

What is the right token that must be used ?

**So far:**

I have been trying for days with no success, I have tried to use the below token but yet no sucess:

* \[node:changed:custom:D-M-Y-H:i:s\]
* \[node:changed:custom:D-M-Y H:i:s\]
* \[node:changed:custom:D/M/Y H:i:s\]
* \[node:changed:custom:DMYHis\]

Any help PLEASE!!

**UPDATE #1:**

The real use case:

I am using the "Field Timer" module in my project which provides field formatters for core module Datetime to display timer or countdown as a formatter.

So every time the node is updated, I want to set the "date field" to the current "date and time" of the node being updated (+) 20 minutes.

For Example if the current date & time of the node being updated is: 31/12/2018 15:00:00 so I want to set the "date & time" field value to: 31/12/2018 15:20:00

So the countdown formatter will start from 20 minutes and down until 0 minute.

Thank you,

# Answer
> 1 votes
Nodes already have a 'changed' property that would track this. Any reason why you don't want to use that? You can use `{{ node.getChangedTime() }}` in a Twig template for the raw value, or you can preprocess the node and take the changed value and format the date to your need into a new variable for the template. This way you don't need another field and Rules and reduce a lot of overhead.

---
Tags: 8, rules, datetime, tokens
---


title: Language switcher doesn't work

text:
# Question
Title: Language switcher doesn't work
I have a fresh D8.64+Bootstrap 3 installation, after enable multilingual modules, add languages and config language dection and content/menu translation, I placed the defualt language switcher to the primary sidebar. Then I translated some contents and menus to other languages. Strangely, when I switch languages, nothing happened, even no changes in the admin interface (only the default English)! I changed the theme, changed the language detection order, cleared cache...it was the same. I downloaded a dropdown language block, it even doesn't show up when I place it on the sidebar (but can show in bartik theme). I searched on internet for hours, but no luck. Could anybody have clue of solution?

# Answer
> 0 votes
I finally sort this out：in the language detection and selection set the url first then others. Deleted the languages and reinstalled them. It suddenly worked. I even don't know why. Thank you @jdrupal very much for your patience and help!!

---
Tags: i18n-l10n
---


# Question
Title: Cannot print View title in View template
How can I print the title of my view in views-view.html.twig?

I have tried both `{{ title }}` and `{{ label }}` but neither work.

You can see the title is set in the View, and the template is using `{{ title }}`

# Answer
You have to use `{{ view.title }}`.
> 11 votes

# Answer
The title is only available in the admin preview, see the documentation of the template:

*views-view.html.twig*

```
{#
/**
 * @file
 * Default theme implementation for main view template.
 *
 * Available variables:
 ...
 * - title: Title of the view, only used when displaying in the admin preview.

```

In other cases add it in preprocess:

*mytheme.theme*

```
/**
 * Implements hook_preprocess_HOOK() for views templates.
 */
function mytheme_preprocess_views_view(&$variables) {
  $view = $variables['view'];

  $variables['title'] = [
    '#markup' => $view->getTitle(),
  ];
}

```
> 2 votes

# Answer
An easy workaround is to add a "Global: Text area" field in the view header and use :

```
<h1>[view:title]</h1>

```

This will do the trick in most cases if you don't use the header for something else.
> 2 votes

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


title: How to clear all caches with Drush 9?

text:
# Question
Title: How to clear all caches with Drush 9?
https://drushcommands.com/drush-9x/cache/cache:clear/ this doesn't give any option to clear all caches. All you get is to choose from 0-7, old `drush cc all` or `cr all` are gone.

Eg.

```
root@dev:/var/www/example.com/htdocs# drush cc --cache-clear

 Choose a cache to clear:
  [0] Cancel
  [1] drush
  [2] theme-registry
  [3] router
  [4] css-js
  [5] render
  [6] plugin
  [7] bin
  [8] views
 > 7

 [success] 'bin' cache was cleared.

```

How to clear all options below with one command? I can't find it documented.

# Answer
> 7 votes
To clear drupal caches using drush 9x use the following command:

```
drush cache:clear

```

Command aliases:

* `drush cc`
* `drush cache-clear`

To clear all caches you can use:

```
drush cache:rebuild

```

Command aliases:

* `drush cr`
* `drush rebuild`
* `drush cache-rebuild`

---
Tags: 8, drush
---


title: Add classes to the menu item <li>?

text:
# Question
Title: Add classes to the menu item <li>?
In `hook_preprocess_menu()`, I want to add custom classes to the `<li>` tag.

I tried the following lines of code, one at a time.

* `$item['attributes']->addClass('section');`
* `$item['attributes']->setAttribute('class', array('section'));`
* `$item['attributes']->setAttribute('class', 'section');`

In any case, this is the HTML markup I get.

```
<li class="Array class">

```

How do I add the desired classes?

# Answer
Assuming your theme extends Classy, you can add a `menu.html.twig` file in your theme to override the menu twig used:

https://api.drupal.org/api/drupal/core%21themes%21classy%21templates%21navigation%21menu.html.twig/8.6.x

This block here:

```
{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
  ]
%}

```

Simply add a new line:

```
{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    'section'
  ]
%}

```

If your theme does not use Classy as a base, then you have to refer to the Stable theme twig file which does not do this:

https://api.drupal.org/api/drupal/core%21themes%21stable%21templates%21navigation%21menu.html.twig/8.6.x

In this case, you would have to add the `set` block within the `for item in items` loop just like the Classy file does, and add `addClass(classes)` method on the `li` item:

```
{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    'section'
  ]
%}
<li{{ item.attributes.addClass(classes) }}>

```

This will add the 'section' class on every single `li` in the menu though, so, if you only want it to apply to the top level menu items for example, you could do:

```
{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    menu_level == 0 ? 'section'
  ]
%}

```

Additionally, if you only want this to apply to a *particular* menu and not all menus, then your Twig file needs to be named `menu--MENU_NAME.html.twig`. Clear caches to see any changes.
> 2 votes

---
Tags: 8, navigation
---


# Question
Title: How to hide the "trimmed version" from the preview page?
When I "preview" a node add/edit form it shows a "trimmed version" and a "full version". I don't want to show the trimmed version.

The fix suggested for D6 doesn't work for D7. Any ideas?

# Answer
> 4 votes
You tried CSS?

```
.preview h3 , .preview .node.node-article.node-teaser {display: none}

```

In my case the content type is an article and worked.

# Answer
> 1 votes
You can also override this page by using drupal 7's templating system.

Go to your modules/node/node.pages.inc file and find this function. It's line 422 for me.

```
function theme_node_preview($variables) {
  $node = $variables['node'];

  $output = '<div class="preview">';

  $preview_trimmed_version = FALSE;

  $elements = node_view(clone $node, 'teaser');
  $trimmed = drupal_render($elements);
  $elements = node_view($node, 'full');
  $full = drupal_render($elements);

  // Do we need to preview trimmed version of post as well as full version?
  if ($trimmed != $full) {
    drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication.<span class="no-js"> You can insert the delimiter "<!--break-->" (without the quotes) to fine-tune where your post gets split.</span>'));
    $output .= '<h3>' . t('Preview trimmed version') . '</h3>';
    $output .= $trimmed;
    $output .= '<h3>' . t('Preview full version') . '</h3>';
    $output .= $full;
  }
  else {
    $output .= $full;
  }
  $output .= "</div>\n";

  return $output;
}

```

Then go to your template.php file of your theme and rename and modify the function to something like this:

```
function your_theme_node_preview($variables){
  $node = $variables['node'];

  $output = '<div class="preview">';

  $preview_trimmed_version = FALSE;

  $elements = node_view($node, 'full');
  $full = drupal_render($elements);

  // Do we need to preview trimmed version of post as well as full version?
  $output .= '<p>You may make further edits below or click save when finished.</p><hr/>';

  $output .= $full;

  $output .= "</div>\n";

  return $output;

}

```

# Answer
> 0 votes
Simple answer

1. go to admin/structure/types/manage/ on your site,
2. Select manage display fields for your desire content type ,
3. go to the teaser tab - set it to hidden at the format and save .

next time when you edit the content just close the summary by click on the link (Hide summary)

# Answer
> 0 votes
Actually the CSS that worked for me was the following one.

```
.preview h3 , .preview article.node-teaser {display: none;}

```

# Answer
> -1 votes
You can use this also:

```
jQuery(document).ready(function($) {
  $("#console").hide();
  $(".preview h3").hide();
  $(".preview .node-teaser").hide();
});

```

---
Tags: 7, forms
---


# Question
Title: Content export and import / content deployment
It's easy to deploy configuration of content types, views and so on...

What are the options for deployment of content (nodes) between different environments?

# Answer
The Default Content module uses cores REST/HAL/Serialisation API's to export content to JSON. You put the content into you\_module/content/\[entity\_type\]/anything.json and the content is automatically imported when you enable your module.
> 3 votes

# Answer
Historically you had options such as leveraging the Migrate module or Feeds to achieve this (Migrate introduced the idea of *continuous migration of content*). While this would still be viable options (once contrib is ready), it seems the common preferred approach nowadays would be to have a 'content hub' from which you can pull content to various sites over RESTful web services. By leveraging Drupal 8's RESTful capabilities, you can totally define a deployment strategy over JSON/HAL+JSON, granted you'd lock down authentication/permissions enough to not expose your content to unprivileged resources.
> 1 votes

# Answer
Also see the Deploy module:

> The Deploy module is designed to allow users to easily stage and preview content for a Drupal site. Deploy automatically manages dependencies between entities (like node references).

This screencast shows it's amazing capabilities.
> 0 votes

# Answer
For continuous content deployment not using Deploy's Web services, there's Content Synchronization.

> The content synchronization module provides a mechanism to export single content items, or all content items, from an environment, and move them to another, effortlessly.
> 0 votes

---
Tags: 8, nodes, importing-exporting, deployment
---


title: Convert node URL to absolute

text:
# Question
Title: Convert node URL to absolute
We are using Drupal Core v8.6.2 and we have a `url` variable in our `node--page.html.twig` template. While using `ksm()` and `{{ kint() }}` we are finding that if we use `hook_preproces_node($variables)` that the `url` is inserted into the `$variables` array. Unfortunately this `url` is `relative`, but we need an `absolute` URL in our `twig` template.

How can we convert this `url` variable from our `node--page.html.twig` template to be absolute?

**`node--page.html.twig`**

I have reduced the comments section to only include comments that were relevant to the question.

```
{#
/**
 * @file
 * Theme override to display a node.
 *
 * Available variables:
 * - node: The node entity with limited access to object properties and methods.
 * - label: The title of the node.
 * - content: All node items. Use {{ content }} to print them all,
 * - url: Direct URL of the current node.
 * - attributes: HTML attributes for the containing element.
 * @see template_preprocess_node()
 *
 */
#}

<a href="{{ url }}> {# url is the variable we want to be absolute #}
  <h2> {{ label }} </h2>
  {{ content.body }}
</a>

```

# Answer
> 1 votes
You can use `hook_preprocess_node` to passe `base_url` to your twig like the following:

```
function mymodule_preprocess_node(&$variables) {
  global $base_url;
  $variables['base_url'] = $base_url;
}

```

in `node--page.html.twig` you will get the absolute `url` by:

```
{{ base_url ~ url }}

```

---
Tags: theming, hooks, uri
---


# Question
Title: Creating a table with pagination in a Node Edit form
I have a content type `article` that has a field for Category. In order to help our editors find related articles, I included a table on the `article` Edit page that pulls in other `article` entities that have the same category as the current one.

I did this by implementing a `hook_form_alter` hook and adding some markup to the `$form` object after querying for all related articles.

```
// Query for matching articles
$query = \Drupal::entityQuery('node');
$query->condition('type', 'article');
$query->condition('field_articles_category.entity:taxonomy_term.tid', $categoryId);
$query->sort('created', $sortDirection);
$query->range($offset, $limit);
$query->latestRevision();

/* Omitting logic to load the Node objects by revision ID's */
// $articles is an array of Node objects of type article

$articlesTable = []
foreach ($articles as $index => $article) {
   $articlesTable[$index] ['articleTitle'] = [
      '#type' => 'link', '#title' => $article->getTitle(), '#url' => $article->toUrl()
   ]
}

$form['related_articles'] = [
   '#type' => 'details',
   '#title' => 'Articles of the Same category',
   'articlesTable' => $articlesTable
];

```

The table displays just fine and shows the expected articles. But there are sometimes hundreds of articles in a particular category so I would like to paginate this table for performance reasons (and to make sure the page is not too long to scroll through). How can I paginate such a table?

I've seen some articles mention creating a pagination controller and somehow setting the AJAX callback for that controller, but haven't found a concrete example yet to follow.

# Answer
You can use `tableselect` instead of `details` something like:

```
   $query = \Drupal::database()->select('node', 'n')
      ->condition('type', 'article', '=');
    $query->fields('n', ['nid']);
    $query->innerJoin('node__field_articles_category', 'category', 'category.field_articles_category_target_id = ' . $categoryId);
    //For the pagination we need to extend the pagerselectextender and
    //limit in the query
    $pager = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender')
      ->limit($limit);
    $article_ids = $pager->execute()->fetchAll(\PDO::FETCH_OBJ);
    $rows = [];
    foreach ($article_ids as $index => $article_id) {
      $article = Node::load($article_id->nid);
      $rows[$index + 1] = [
        'title' => $article->getTitle(),
        'url'   => Drupal::l($article->getTitle(), $article->toUrl()),
      ];
    }

    $form['related_articles']['table'] = [
      '#type'    => 'tableselect',
      '#header'  => ['title' => t('title'), 'url' => t('Url')],
      '#options' => $rows,
      '#empty'   => t('No users found'),
    ];
    // Finally add the pager.
    $form['related_articles']['pager'] = array(
      '#type' => 'pager',
    );

```

Result will be like:
> 2 votes

---
Tags: 8, ajax, paging, page-controller
---


# Question
Title: Routinely import LimeSurveys into custom tables
Our Research company has got 3 servers (in house), 1 hosts Drupal - outward facing, 2nd hosts LimeSurvey - outward facing, 3rd is the database server (db for Drupal and LimeSurvey) - sits inside institute's firewall.

Drupal contains Participant's database, LimeSurvey hosts multiple Surveys (which are really long surveys varying from 200 - 400 questions!).

I want to import the survey responses from each survey into separate custom tables in Drupal **EVERYDAY**. (custom tables because don't want to create Content type which in turn creates 200 tables, 1 for each field!)

**QUESTION:** What is the best way to achieve this?

Work done so far:

1. was able to automate daily csv export from LimeSurvey and copy to Drupal server in a private secure folder.
2. tried multiple Contrib modules for Drupal to import csv:

**LimeSurvey Sync** was the better solution out of all other. works fine without having to automate csv export, copying, etc., except it's real time and don't really want to connect Drupal - LimeSurvey real time (want Drupal to be separate and super secure, and not connected to any other system!) This also had some glitches with very long surveys. (random errors connecting to LimeSurvey)

**Import CSV Data** Could create only 1 custom table, could not find out how to create separate custom tables for each survey

**Data** along with **Feeds** module. Could not get this working! Created a new custom table using Data module config page. This was reflected in Feeds Imported config page. Configured to Attach to "Use standalone form" in basic settings, file uploader, csv parser, Node processor. And didn't know what to do next, how do I schedule import?

Please suggest if I am in the right way OR if there is any other better way of achieving this?

# Answer
> 1 votes
I am the author of the Drupal LimeSurvey Sync module. **You definitively need that module !** About LimeSurvey Sync module :

* You don’t have to use the « realtime » feature. You can simply start answering survey from your LimeSurvey site. Just create a simple rule (using the Rules UI module) to fire LimeSurvey synchronization on Cron event on your Drupal site in order to import.
* Your Drupal site will still be secure : the LimeSurvey Sync module provides protections from sql injection and datas are sanitized before being imported.
* About issue for very very big surveys : that can be solved by appropriate server settings. Look at this issue on the Drupal module issues section to get the good configuration.

Keep me In touch !

---
Tags: 7, nodes
---


# Question
Title: Can't find cookie for validation in EventSubscriber
There's this module Splash Redirect in which `src/EventSubscriber/SplashRedirectEventSubscriber.php` is supposed to check if the cookie `$config_cookie` exists or not, if it already exists then the user continues onto the requested node (`$config_source`), but if it does *not* exist then the user is sent to `$config_destination` and it creates the cookie (`$config_cookie`).

It succeeds in creating the `$config_cookie` and the redirect to `$config_destination` but it never seems to acknowledge the existence of the cookie once created and continues to redirect the user to `$config_destination`.

Any clues? On Drupal 8.6

```
<?php

namespace Drupal\splash_redirect\EventSubscriber;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Routing\TrustedRedirectResponse;

/**
 * Splash redirect Event Subscriber.
 */
class SplashRedirectEventSubscriber implements EventSubscriberInterface {

  /**
   * Triggered when system sends response.
   */
  public function modifyIntercept(GetResponseEvent $event) {
    $config = \Drupal::config('splash_redirect.settings');
    $config_enabled = $config->get('splash_redirect.is_enabled');
    $config_source = $config->get('splash_redirect.source');
    $config_destination = $config->get('splash_redirect.destination');
    $config_cookie = $config->get('splash_redirect.cookie_name');
    $config_duration = $config->get('splash_redirect.duration');

    // If splash config is not enabled then we don't need to do any of this.
    if ($config_enabled == 1) {
      // Current request from client.
      $request = \Drupal::request();
      $current_uri = $request->getRequestUri();
      $http_host = $request->getHost();
      // Current response from system.
      $response = $event->getResponse();
      $route = (\Drupal::routeMatch()->getParameter('node')) ? \Drupal::routeMatch()->getParameter('node')->id() : null;
      $has_cookie = $request->cookies->has($config_cookie);

      // If splash-cookie has not been set, and user requesting 'source' page,
      // set cookie and redirect to splash page.
      if ($config_source == $route) {
        // Kill cache on this route or else cookie might not be read with VCL.
        \Drupal::service('page_cache_kill_switch')->trigger();

        if (!$has_cookie) {
          // Set redirect response with cookie and redirect location.
          $redir = new TrustedRedirectResponse($config_destination, '302');
          $cookie = new Cookie($config_cookie, 'true', strtotime('now + ' . $config_duration . 'days'), '/', '.' . $http_host, false, true);
          $redir->headers->setCookie($cookie);
          $redir->headers->set('Cache-Control', 'public, max-age=0');
          $redir->addCacheableDependency($config_destination);
          $event->setResponse($redir);
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // Listen for response event from system and intercept.
    $events[KernelEvents::REQUEST][] = ['modifyIntercept'];
    return $events;
  }

}

```

# Answer
Some ideas:

Like for the config you have to add a cache dependency for the cookie, too:

```
  $response->getCacheableMetadata()->addCacheContexts(['cookies:' . $config_cookie]);

```

Or use an uncacheable `RedirectResponse` to simplify things.

And try to set a priority for the event subscriber, for example 31, because your code depends only on routing, which has 32:

```
  $events[KernelEvents::REQUEST][] = ['modifyIntercept', 31];

```

You don't need to get a response in an request subscriber, because there isn't one yet. Get the request instead and make sure that you are in a master request. So this would be how the subscriber starts most times:

```
  public function onKernelRequest(GetResponseEvent $event) {
    if (!$event->isMasterRequest()) {
      return;
    }
    $request = $event->getRequest();
    ...

```

---

Simplifying a bit more and using dummy values for testing:

```
  public function onKernelRequest(GetResponseEvent $event) {
    if (!$event->isMasterRequest()) {
      return;
    }
    $route_match = \Drupal::routeMatch();
    if (!$route_match->getRouteName() == 'entity.node.canonical') {
      return;
    }
    $request = $event->getRequest();
    if ($route_match->getRawParameter('node') == '1') {
      \Drupal::service('page_cache_kill_switch')->trigger();
      if (!$request->cookies->has('foo')) {
        $redirect = new RedirectResponse($request->getBasePath() . '/node/2', 302);
        $redirect->headers->setCookie(new Cookie('foo', '123', '+30 seconds'));
        $event->setResponse($redirect);
      }
    }
  }

```

This is working on my local dev environment.

---

Complete code (including dependency injection and code updated to D9/10):

*/src/EventSubscriber/MymoduleSubscriber.php*

```
<?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Cookie;

/**
 * mymodule event subscriber.
 */
class MymoduleSubscriber implements EventSubscriberInterface {

  /**
   * The route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * Constructs event subscriber.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   */
  public function __construct(RouteMatchInterface $route_match) {
    $this->routeMatch = $route_match;
  }

  /**
   * Kernel request event handler.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   The request event.
   */
  public function onKernelRequest(RequestEvent $event) {
    if (!$event->isMainRequest()) {
      return;
    }
    if (!$this->routeMatch->getRouteName() == 'entity.node.canonical') {
      return;
    }
    $request = $event->getRequest();
    if ($this->routeMatch->getRawParameter('node') == '1') {
      \Drupal::service('page_cache_kill_switch')->trigger();
      if (!$request->cookies->has('foo')) {
        $redirect = new RedirectResponse($request->getBasePath() .'/node/2', 302);
        $redirect->headers->setCookie(new Cookie('foo', '123', '+30 seconds'));
        $event->setResponse($redirect);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::REQUEST => ['onKernelRequest', 31],
    ];
  }

}

```

*mymodule.services.yml*

```
services:
  mymodule.event_subscriber:
    class: Drupal\mymodule\EventSubscriber\MymoduleSubscriber
    arguments: ['@current_route_match']
    tags:
      - { name: event_subscriber }

```
> 7 votes

# Answer
Original splash\_redirect module dev here. Thanks for joining me in the caching rabbit hole! (Sorry, can't make 'comments' yet so I have to put this in an answer)

Thanks to @4k4 for the great suggestions, I will likely implement some of those in the next release, but OP's issue looks to be specific to Pantheon's global CDN, which sets the `Vary: cookie` header, and caches the source redirect.

\*So, if you're using splash\_redirect on Pantheon, please prefix your Splash Cookie name with "SESS", e.g. `SESSsplash` *
> 4 votes

---
Tags: 8, cookies, event-subscribers
---


# Question
Title: How to nested paragraph in container paragraph template?
I have a paragraph called User Info and inside that there are two fields:

1. `field_test (Text field)`
2. `field_para_text_title (Paragraph field)`  Both the field values are printing when I print `{{ content }}` in `paragraph--user-info.html.twig`.

But I could not print `field_para_text_title` field alone like below:

`{{ content.field_para_text_title }}`

nothing giving for `field_para_text_title` but `{{ content.field_test }}` is working fine.

# Answer
Have you tried: `{{ content.field_field_para_text_title.0 }}` or, if that doesn't work, I would try:

* Create a template file for your paragraph field. So it would be paragraph--field-field\_para\_text\_title.html.twig

In paragraph--field-field\_para\_text\_title.html.twig you do: `{{ content.field_field_para_text_title }}`
> -3 votes

---
Tags: 8, theming
---


title: New sub-theme not showing in appearance

text:
# Question
Title: New sub-theme not showing in appearance
I am working with Drupal's Open social framework where in I copy socialblue theme so that i can do my modifications in the new theme. I followed the below steps, cleared cache, yet I am not able to see my new theme in admin/appearance section.

Steps I followed:

1) I duplicated the theme socialblue (html/profiles/contrib/social/themes/socialblue) to newtheme (html/profiles/contrib/social/themes/newtheme)

2) I did a search (socialblue) and replace (newtheme) inside of “newtheme” directory

3) I changed the names of the following files from “socialblue” to “newtheme"

```
newtheme.info.yml
newtheme.libraries.yml
newtheme.theme
config/install/newtheme.settings.yml

```

4) I created a /html/sites/default/services.yml file from default.services.yml and made the following changes

```
twig.config -> debug: true
twig.config -> auto_reload: true
twig.config -> cache: false

```

5) html/profiles/contrib/social/themes/newtheme$ yarn install

6) html/profiles/contrib/social/themes/newtheme$ sudo npm install -g gulp-cli

7) html/profiles/contrib/social/themes/newtheme$ gulp

I do not get any error. I made sure that my newtheme.info file has name newtheme. I also copied this new theme in html/themes/custom/newtheme still no luck. Am I missing something?

# Answer
> 1 votes
I solved it. Turns out it was because my base theme was mentioned as 'socialblue'. I changed it to 'socialbase' and it worked out. I don't know if a parent theme can have more than one child themes in drupal 8.

---
Tags: theming
---