title: Is there a hook for node after save?

text:
# Question
Title: Is there a hook for node after save?
How do I unpublish translations when the english content is unpublished? I tried to unpublish the language content programmatically when I am unpublishing the english content in the `hook_node_update()` but it returns below error.

```
$languages = getLanguageList();
$currLanguage = \Drupal::languageManager()->getCurrentLanguage()->getId();

if (!$node->status->value) {
    foreach ($languages as $languageId => $language) {
        if ($languageId != 'en' && $currLanguage == 'en') {
            if ($node->hasTranslation($languageId)) {
                $transNode = $node->getTranslation($languageId);
                $transNode->setPublished(false);
                $transNode->save();
            }
        }
    }
}

```

Error :

```
Uncaught PHP Exception Drupal\\Core\\Entity\\EntityStorageException: "Update existing 'node' entity revision while changing the revision ID is not supported."

```

So I guess if I can do this after saving the node it would work. Is there a hook for node after save. Or is there a way to unpublish language contents of a node while unpublishing the source language(English)?

# Answer
> 4 votes
In Drupal 8 you should use **hook\_entity\_update()**.
This hook runs once the entity storage has been updated.

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook\_entity\_update/8.3.x

# Answer
> 2 votes
Could it be this you are looking for:

Entity::postSave(EntityStorageInterface $storage, $update = TRUE)

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21Entity.php/function/Entity%3A%3ApostSave/8.6.x

# Answer
> 2 votes
You could try in hook\_pre\_save so that should be before the main node has been effected

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook\_entity\_presave/8.6.x

---
Tags: 8, nodes, hooks
---


# Question
Title: Route callback for RegisterForm results in Call to a member function getEntityTypeId() on null
**My objective**: Let say there is a role named "author". I would like to have a registration form having this path: `/register/author`, when the user submit, he/she will get the author role (same for any other roles like `/register/another_role`)

Here is what I have done:

1-Creating a route: last argument will be the role name

```
mymodule.register:
  path: '/register/{role}'
  defaults:
    _form: 'Drupal\mymodule\Form\RegisterByRole'
    _title: 'Register by role'
  requirements:
    _permission: 'access content'

```

2-Extending the RegisterForm Class

```
class RegisterByRole extends RegisterForm
{
    public function form(array $form, FormStateInterface $form_state, $role = null)
    {
        $form = parent::form($form, $form_state);
        if (role_is_allowed($role)) {
            $form['test'] = [
                '#markup' => '<p>Test:' . $role
            ];
        }
        return $form;
    }
}

```

Of course I must change the submit function to assign the role, but I already have the following error when visiting the /register/author path:

```
Error: Call to a member function getEntityTypeId() on null in Drupal\Core\Entity\EntityForm->getBaseFormId() (line 111 of core/lib/Drupal/Core/Entity/EntityForm.php).

```

I found that if I add the `__construct` and the `create` functions in the `RegisterByRole` class definition, the `getBaseFormId` error disappears... But I don't understand why?... And more annoying, I couldn't get the value of my $role argument (last arg of the route).

What is wrong in my plan?

# Answer
I believe the problem is here:

```
_form: 'Drupal\mymodule\Form\RegisterByRole'

```

You need to use `_entity_form` rather than `_entity`, as the `RegisterForm` is actually an entity form for the User entity, as described in the Entity declaration for `\Drupal\user\Entity\User`:

```
"form" = {
  ...
  "register" = "Drupal\user\RegisterForm"
},

```

But to do this, you'll have to register a new form op for that class. You can do this in hook\_entity\_type\_alter():

```
function hook_entity_type_alter(array &$entity_types) {
  $user = &$entity_types['user'];
  $user->setFormClass('role_registration', 'Drupal\example\Form\RegisterByRole');
}

```

Then, back in your route, you'll remove `_form` and instead implement`_entity_form`, setting it to to user.role\_registration:

```
_entity_form: 'user.role_registration'

```
> 4 votes

---
Tags: 8, forms
---


# Question
Title: How to display an alternative text if the comments are closed for the node?
in my node type template, how do I display alternate text if comments are closed for the node ?

```
  {% if content.comment %}
    <div class="card mb-5 p-3 shadow">
      {{ content.comment }}
    </div>
  {% else %}
    <div class="card mb-5 p-3 shadow">
      {{ content.field_link }}
      {{ content.field_code }}
    </div>
  {% endif %}

```

EXAMPLE

> If comments are open :
>
> {{ content.comment }}
>
> If comments are closed :
>
> TEXT

# Answer
> 1 votes
Assuming you're using the default field definitions installed by the standard profile, what you want is the `status` property of the `comment` field of the node, which is accessible in twig via `node.comment.status`.

```
{% if node.comment.status == 2 %}
   {# comments are open #}
{% elseif node.comment.status == 1 %}
   {# comments are closed & visible #}
{% elseif node.comment.status == 0 %}
   {# comments are closed & hidden #}
{% endif %}

```

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


title: Extend the Scheduler module forms

text:
# Question
Title: Extend the Scheduler module forms
Hi i'm trying to extend scheduler module forms. The one i need is included as fieldset in node as extra field refer to image

```
/**
 *  Implements hook_form_node_type_form_alter().
 */

 function nodequeue_scheduler_form_node_type_form_alter(&$form, $form_state) {

    //This  node type configuration form with schedule options

    $form['scheduler']['nodequeue_sheduler'] = array(
      '#type' => 'fieldset',
      '#title' => t('Nodequeue Scheduler Settings'),
      '#collapsible' => FALSE,
      '#group' => 'scheduler',
      '#weight' => 10,
    );

   }

/**
 * Implements hook_form_FORM_ID_alter().
 */
function nodequeue_scheduler_form_scheduler_node_form_alter(&$form, $form_state) {

   //feldset or vertical tab for scheduler to ammend
$options = array (1,2,3);
// Adding few custom fields
$form['scheduler_settings']['publish_nodequeue'] = array(
 '#type' => 'fieldset',
 '#title' => t('Nodequeue Scheduling settings'),

);
$form['scheduler_settings'] ['publish_nodequeue']['schedule_nodequeue'] = array(
 '#type' => 'checkbox',
 '#default_value' => 1,
 '#title' => t('Add to nodequeue when published')
);

$form['scheduler_settings']['publish_nodequeue']['nodequeue_position'] = array(
 '#type' => 'select',
 '#options' => $options,
 '#title' => t('Position')

);
$form['scheduler_settings']['publish_nodequeue']['publish_on'] = array(
 '#type' => 'textfield',
 '#title' => t('Publish on'),
 '#maxlength' => 30,

);
// function scheduler_mail_form_scheduler_node_form_alter(&$form, $form_state) {
//    $email_enabled = variable_get('scheduler_mail_enable_' . $form['type']['#value'], 0);
//    if (!$email_enabled) {
//      return;
//    }

//    $node = $form['#node'];
//    $settings = _scheduler_mail_load($node);

//    $form['scheduler_settings']['scheduler_mail'] = array(
//      '#type' => 'fieldset',
//      '#title' => t('Email settings'),
//    );
//    $form['scheduler_settings']['scheduler_mail']['scheduler_mail_send'] = array(
//      '#type' => 'checkbox',
//      '#title' => t('Send an email notification when this node is (un)published'),
//      '#default_value' => $settings->send,
//    );
//    $form['scheduler_settings']['scheduler_mail']['scheduler_mail_address'] = array(
//      '#type' => 'textfield',
//      '#title' => t('Use this email address'),
//      '#description' => t('If left blank, email will go to the original author of this node'),
//      '#default_value' => $settings->address,
//      '#maxlength' => 255,
//      '#states' => array(
//        'visible' => array(
//          "input[name='scheduler_mail_send']" => array("checked" => true)
//        ),
//      ),
//    );
//    $form['#validate'][] = '_scheduler_mail_validate';
//    $form['#submit'][] = '_scheduler_mail_submit';
  }

```

I have found module scheduler mail and it alters the node type form and add some configuration fields as checkbox but not getting the form which is in node edit form . How do i do it in drupal 7

# Answer
If scheduler is using hook\_form\_alter() on a form, and your module is also using hook\_form\_alter() on the same form, the order of execution of these two hook\_form\_alter() functions matters. Evidently, your module's hook\_form\_alter() is getting called before scheduler can add the new form elements you're trying to modify.

Drupal executes these hooks in order of module weight. If you do not set the module weight, then I believe they all default to the same value and hooks with the same weight will get called in alphabetical order (but this is not guaranteed).

To ensure that your module gets called after scheduler, you need to set your module's weight to be greater than the scheduler's module weight. This is how you do that in your module's install file:

```
/**
 * Implements hook_install().
 */
function my_module_install() {
  // Because we need to alter a form that is also altered by the scheduler
  // module, we need to ensure this module gets loaded AFTER the scheduler.
  $weight = db_query('SELECT weight FROM {system} WHERE name = :name', array(':name' => 'scheduler'))->fetchField();
  db_update('system')
    ->fields(array(
      'weight' => $weight + 1
    ))
    ->condition('name', 'my_module')
    ->execute();
}

```
> 0 votes

---
Tags: 7
---


title: How to load an entity using the uuid?

text:
# Question
Title: How to load an entity using the uuid?
I have created a custom resource which extends the `EntityResource` class. This way I can use all build in functionality that Drupal core provides on the default entity resource, but I can still add some extra checks. This works perfectly fine.

I defined my canonical route in my resource as /api/my-endpoint/{node}. In this way, I can fetch and patch nodes by the node ID. After careful consideration, I want to implement /api/my-endpoint/{node\_uuid} or even /api/my-endpoint/{node\_custom\_field} to fetch (and patch) a node by UUID.

Of course, Drupal doesn't know this param and cannot load the corresponding node object, which results in fatal errors.

How can make I this work?
I tried to implement a custom `RoutingParamConverter` class, but I didn't got it to work.

# Answer
As long as you have the uuid of an entity you can use Drupal's entity storage interface to load it given that property. It should be as simple as using the loadByProperties method.

```
$node_loaded_by_uuid = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['uuid' => $your_uuid]);
$node_loaded_by_uuid = reset($node_loaded_by_uuid);

```

UPDATE: milkovsky is correct. loadByProperties returns an array. If you want the actual node object at the top of it you will have to use the reset function.
> 17 votes

# Answer
You can use EntityRepositoryInterface::loadEntityByUuid():

```
$entity = \Drupal::service('entity.repository')->loadEntityByUuid('node', $uuid);

```
> 17 votes

---
Tags: 8
---


# Question
Title: Filter by taxonomy parent using Json api
In drupal 8.5 I have a taxonomy term list like this:

```
Term A (12 items)
  Term 1 (3 items)
  Term 2 (8 items)
  Term 3 (1 items)
Term B (3 items)
  Term 4 (1 items)
  Term 5 (2 items)

```

I want to use the json api to fetch all data within `term B`. So I expect a result set of 3 items. But when I do:

```
https://www.some-api.com/jsonapi/node/test?
  _format=api_json&
  filter[taxFilter][condition][path]=field_regio&
  filter[taxFilter][condition][operator]=IN&
  filter[taxFilter][condition][value][]=2 (=> id of term B)

```

I get a response with `"data": [],` This is probably because the term id of these nodes are set to the children (term 4 and 5).

But isn't drupal supposed to return all nodes in the children of term B?

Otherwise how can I get all nodes in Term A or B?

# Answer
The term-ID 2 belongs to "Term B", not to "Term 4" or "Term 5". To check if term belongs to Term B you may include the term parent and check if it has id 2:

```
https://www.some-api.com/jsonapi/node/test?
_format=api_json&
include=field_regio.parent
filter[taxFilter][condition][path]=field_regio.parent&
filter[taxFilter][condition][operator]=IN&
filter[taxFilter][condition][value][]=3 (=> id of term B)

```

This should work at least for the simple example provided it the question.

**See also D.A. question How do you correctly filter on taxonomy terms to get all nodes matching term or parent term? for more details and potential issue with permissions.**
> 0 votes

---
Tags: 8
---


# Question
Title: how to pass a parameter to a route of type _entity_form
With some help I could create a route to an extended register form: as this form is an "entity form", my route have this type and the definition of this new form has been made in hook\_entity\_type\_alter

The last part of the path of the route is a role name; and the user submitting this form (registering itself) should get this role.

Here is the code:

1-Extending the register form

```
class RegisterByRole extends RegisterForm
{
    public function form(array $form, FormStateInterface $form_state, $role = null)
    {
        $form = parent::form($form, $form_state);
        if ($role) {
            $form['test'] = [
                '#markup' => '<p>Test:' . $role
            ];
        }
        return $form;
    }
}

```

2-Adding a new entity form to the entity\_type definition/annotation

```
function my_module_entity_type_alter(array &$entity_types) {
    $entity_types['user']->setFormClass('role_registration', 'Drupal\my_module\Form\RegisterByRole');
}

```

3-Creating the route

```
my_module.register:
  path: '/register/{role}'
  defaults:
    _entity_form: 'user.role_registration'
    _title: 'Register by role'
  requirements:
    _permission: 'access content'

```

Unfortunatly, the $role parameter is not transmitted...

# Answer
> 1 votes
With the help of 4k4 who have all the credit for this answer, I have created a controler which, in turn, build my register form (I no longer need to **extend** the register form). Before building the form, the controller must create a user and assign the role (coming from the parameter).

Here is the code

1-Create the route with rid as the parameter and a \_controler key:

```
my_module.register:
  path: '/register/{rid}'
  defaults:
    _controller: '\Drupal\my_module\Controller\RegisterByRoleController::content'
    _title: 'Register by role'
  requirements:
    _permission: 'access content'

```

2-Create the controller with rid as the parameter (src/Controller/...):

```
    public function content($rid=null) {

      $user_with_role = \Drupal\user\Entity\User::create();
      $roles = Role::loadMultiple();
      if ($rid && isset($roles[$rid])){
          $user_with_role->addRole($rid);
      }else{
          throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
      }

      $form = \Drupal::entityTypeManager()
      ->getFormObject('user', 'register')
      ->setEntity($user_with_role);

      $form_build=\Drupal::formBuilder()->getForm($form);

      //here is the trick I used to check the role
      $form_build['account']['roles'][$rid]['#checked']=TRUE;
      return $form_build;
  }

```

Everything works well: the form is displayed, the rid is transmitted to the controller but the is still a problem:

The "transmitted" role's checkbox **is not checked** in the register form!

Any Hint?

I answer myself: it seems there is no way to achieve this "automatically", I will have to check "myself" the check boxes... see the last comment here: Default value for form entity

This is why is have added this line in the code `$form_build['account']['roles'][$rid]['#checked']=TRUE;`

---
Tags: entities, forms
---


# Question
Title: Bootstrap 3, how disable auto-added Glyphicon?
I use Bootstrap (v3) with Drupal 8. When I create a button named "**Search** something", bootstrap adds automatically a "Search" Glyphicon. I do some web searches, but I don't find how "disable" (or hide?) the 'search'auto-added glyphicon of my button.

When I create a sample submit button from a Form Class custom module :

```
public function buildForm(array $form, FormStateInterface $form_state) {
...
$form['submit'] = [
  '#type' => 'button',
  '#value' => 'Search something',
];

```

If I go to the page where there is my form, the button have automatically a magnifying glass glyphicon :

I want display my button without any glyphicon, how can I do that ? I must add a class to my button ? which ?

Thank you !

# Answer
> 3 votes
I have just tested this thing using the Examples module which already provides the sample example form.

Now if you see the example of simple form it will shown,

>

*Code for above image(just submit button part)*,

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

```

NOW, if I change the `t('Submit')` to `t('Search something')`, so code change will be,

```
$form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Search something'),
    ];

```

Now, you can see the out-put image,

>

Did you surprise..:)...Just changing the String causing this all problem. Now why this is happening, this is all due to Bootstrap theme, ideally it should not happen. Now, if you read the first line of @remy's answer on this question:How can I theme the Bootstrap base theme search block?, it states that,

> Bootstrap theme is deeply bundled with glyphicons .. it guesses the icon from the button text.

Hence, what is happening, Bootstrap theme taking that `Search...` word and automatically applying the icons and corresponding classes for color and etc because code has been set-up that way in that theme.

Now, if you do not want to use `Search` word, it will not show up as shown below,

>

Now, you can see the BLUE color disappeared, to get that, just add the `#button_type`, so it again can take appropriate classes. Now see, in following image everything is Ok.

```
$form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Something'),
      '#button_type' => 'primary',
    ];

```

>

Further, you can read that question provided in link, where they have discussed more on this, probably you may get idea to tackle this more in code way, but I think now, you can tackle this as we knew what causes this.

# Answer
> 9 votes
I haven't tried it for Drupal 8, but its works for drupal 7. It should work for drupal 8 as well.

In your bootstrap theme setting, under bootstrap setting there is tab of General setting. Inside that tab the are settings for different bootstrap components. You will see Buttons there. Just open that section and un-check Iconize Buttons option. That's it.

This will disable all the auto icons in buttons.

# Answer
> 0 votes
This works for Drupal 7. In your subtheme's template.php, you can do this :

```
function YOUR_THEME_bootstrap_iconize_text_alter(&$texts) {
  // We apply the glyphicon ONLY when the element matches "Search"
  $texts['matches'][t('Search')] = 'search'; // The alias of the glyphicon

  // When the element only "contains" the term "Search", it does not apply an icon anymore :
  unset($texts['contains'][t('Search')]);
}

```

Sorry, I haven't tried for D8.

# Answer
> 0 votes
To disable glyphicons in Drupal 8 (because you are using the Bootstrap theme, or a theme which relies upon Bootstrap theme) simply go to: Home \>\> Administration \>\> Appearance \>\> Appearance settings. Under the Generalize tab on the left there will be options for Buttons. You can uncheck the boxes for Colorize and Iconize.

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


# Question
Title: How to prevent Devel module to be installed on production environments
Using the new Drupal 8 Configuration manager, how can I prevent it from installing the Devel module on certain environments? As far as I know, installing it on my local means the next time I export the configuration and move it to my other environments (dev, test, prod), it will automatically be enabled.

# Answer
**Method: Drush**

* Drush can ignore the enabled states of extensions when synchronizing configuration.

`drush cex --skip-modules=devel`

`drush cim --skip-modules=devel`
* With Drush CMI tools you can operate with a list of configuration to ignore.

`drush cexy --ignore-list=/path/to/config-ignore.yml`

`drush cimy --delete-list=/path/to/config-ignore.yml`

**Method: Modules**

* You can use the Configuration Split module that allows you to:

1. Split off some configuration to dedicated folder
    2. Blacklist configuration
    3. Ignore a set of configuration
    4. Configured by configuration entities
* Configuration Read-only mode module

> This module allows to lock any configuration changes done via the Drupal admin UI. This can be useful in scenarios where for example configuration changes should not be done on the production environment, but only on staging or local environments.

`$settings['config_readonly'] = TRUE;`
* And another module is the Environment Config that allows you to override configuration on a per-environment basis.
> 18 votes

# Answer
**Update**: The feature described below was removed lately https://www.drupal.org/project/config\_split/issues/2926505

---

If you are using drush in your deployment process you can do the following:

Create a `drushrc.php` file in the same directory as your `settings.php` (for example: `docroot/sites/default`) and put the following:

```
$drush_ignore_modules = array(
  'devel',
  'webprofiler',
  'devel_generate',
  'kint',
  'yaml_editor',
);

$command_specific['config-export']['skip-modules'] = $drush_ignore_modules;
$command_specific['config-import']['skip-modules'] = $drush_ignore_modules;

```

This means, that you can manipulate the `drush cex` / `drush cim` commands to skip modules, during their process.

You can read more about Using the Configuration Module Filter in Drush 8.
> 7 votes

# Answer
For Drupal 8.8.0 and higher releases, there is a core setting to exclude configuration values without using any contributed module.

Just add the following line in your *web/sites/default/settings.php* file.

```
$settings['config_exclude_modules'] = ['devel', 'webprofiler'];

```

If you are using Drush to import/export configuration, you will need Drush 10+.

Run `drush cex`.

Read more on the change record, the documentation, or a discussion with people having problems using it.

**NOTE:** For more than two environments / configuration sets (*dev*, *stage*, *live*), this simple setting will not probably be enough.

`drush cex --skip-modules` was removed in favor of the Configuration Split module as explained in drush cex --skip-modules was removed in favor of config\_split, but config\_split is not feature-equivalent; thus, the solutions based on Drush have not worked for me.

For Drupal releases before Drupal 8.8.0, this the solution I suggest.

* Install the Config Exclude module using `composer require --dev`, and configure it.
* Add the following lines in the *settings.php* file.

```
if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  include $app_root . '/' . $site_path . '/settings.local.php';
}

```
* Add the *Config Exclude* module settings in the *settings.local.php* file, for example the following lines.

```
$settings['config_exclude_modules'] = [
  'devel',
  'config_exclude',
  'config_filter',
  'stage_file_proxy',
];

```

The *settings.local.php* is not a requirement.
* Require the modules you need on the development environment with `composer require --dev` (for example, `composer require --dev drupal/devel`). To install the site without the development modules, you use `composer install --no-dev`. (On your staging and production environments, you should always use `--no-dev`.)
* Use `drush cex` as you would normally do. It will not not export any of the excluded modules settings.

###Note

I have noticed that the **core.extension** settings appear to have been modified after running the command above, but the corresponding .yml file is never written on the hard drive (even after confirming *will be deleted and replaced with the active config*), so there is nothing to be commited. I guess it depends on the internals of the *Config Exclude* module.
> 6 votes

# Answer
The Configuration Split module might be a viable solution for some.

> The Drupal 8 configuration management works best when importing and exporting the whole set of the sites configuration. However, sometimes developers like to opt out of the robustness of CM and have a super-set of configuration active on their development machine and deploy only a subset. The canonical example for this is to have the devel module enabled or having a few block placements or views in the development environment and then not export them into the set of configuration to be deployed, yet still being able to share the development configuration with colleagues.
> 4 votes

# Answer
There's an interesting issue for Drupal 8.3.x: Allow development modules to opt out of config-export. The general concensus is that Configuration Split is currently the best solution.

Comment by swentel:

> Just wanted to briefly document how config\_split works: The config split config entity defines what is blacklisted, allowing you to blacklist modules and/or config objects. The canonical example, being devel, already has an interesting use case: it comes with system.menu.devel which, in case you blacklist devel, the menu config file will not be removed since there's no dependency. While it's not a major problem, config split allows you individually select that as well so it's removed on the environment.

Comment by geerlingguy:

> I've tried a few different methods of managing environment-specific config, and config\_split seems to hit the right usability vs. extra overhead balance the best so far. It's simple and lightweight, but allows me to mark (and continue to use) certain configuration only in certain environments.
> 3 votes

# Answer
There is a neat way of doing this, where you end up with your dev modules committed in composer for convenience and those modules' config is not added to your config export (there are 2 parts):

**1. Composer require --dev** When enabling a module which is purely for development then use the --dev flag:

```
$ composer require --dev drupal/devel

```

This results in those dependencies being added into the composer.json file under require-dev:

```
...
    "require-dev": {
        "drupal/twig_xdebug": "^1.0",
        "drupal/devel": "^1.0@RC"
    }
}

```

So if you install the the site WITHOUT your dev modules you say:

```
$ composer install --no-dev

```

**NB:** On your staging and prod environments you should always do --no-dev

**2. Use the config\_split module**

Configuration split module allows you to create groupings of configuration export which can be enabled or disabled in an environment.

I actually have 3 splits:

1. Main site config (enabled everywhere; dev and staging and production)
2. Staging config (enabled in dev and staging) - includes reroute email module
3. Dev config - includes devel, kint... but not reroute email as that comes with having the staging config enabled in dev.
> 3 votes

# Answer
You can use a deployment override module for this. Read the following link for detailed description:

http://dcycleproject.org/blog/46/continuous-deployment-drupal-style

**However**, Best way to do this would be to disable your module on local and then export the configuration.

Drupal provides a way to override the configuration settings in `settings.php`, but they are not valid for disabling/enabling modules.

From `default.settings.php`:

```
/**
 * Configuration overrides.
 *  * To globally override specific configuration values for this site,
 * set them here.
 *
 *
 * blah..blah...blah
 *
 *
 * There are particular configuration values that are risky to override. For
 * example, overriding the list of installed modules in 'core.extension' is not
 * supported as module install or uninstall has not occurred. Other examples
 * include field storage configuration, because it has effects on database
 * structure, and 'core.menu.static_menu_link_overrides' since this is cached in
 * a way that is not config override aware. Also, note that changing
 * configuration values in settings.php will not fire any of the configuration
 * change events.
 */

```
> 2 votes

# Answer
I made a small script to do it all in one shot.

```
#!/bin/bash

drush pm-uninstall devel -y
drush pm-uninstall field_ui -y
drush pm-uninstall field_name_prefix_remove -y

drush config-export

drush en devel -y
drush en field_ui -y
drush en field_name_prefix_remove -y

```
> 2 votes

# Answer
You can also see Config Ignore module.

> This module is a tool to let you keep the configuration you want, in place.
>
> Lets say that you do would like the system.site configuration (which contains that sites name, slogan, email, etc) to remain untouched, on your live site, no matter what the configuration, in the export folder says.
>
> Or maybe you are getting tired of having the devel.settings changed every time you import configuration?
> 2 votes

# Answer
Introduced in Drupal 8.8 there is a setting for that: How does the new config\_exclude\_modules setting work exactly?

To have the devel module excluded you

1. Remove devel related configuration yaml files
2. Add `$settings['config_exclude_modules'] = ['devel'];` to your settings.php or, even better, your settings.local.php.
> 2 votes

---
Tags: 8, configuration
---


# Question
Title: How can I prevent composer from detaching a module's head?
How can I prevent composer from leaving a module's git status as a "detached head" when updating

Whenever I use composer to install or update one of my modules or themes, it downloads and overwrites the module's files into the expected directory but leaves the git status in a 'detached head' state and so subsequent development work is not staged to the expected commit until I reset the head ... which only takes a moment but ... I would prefer not to have to remember to do this each time.

Could it be the way I tag the commit of latest dev work? I `git push` the commit; `git tag` it; and `git push --tags` in the belief that git will not push tags and the commit simultaneously.

As an example:

A theme's complete `composer.json` *on GitHub*.

```
{
  "name": "iainhouston/pellucid_monoset",
  "description": "Drupal 8 Theme for pellucid_build",
  "type": "drupal-theme",
  "license": "GPL-2.0+",
  "keywords": ["pellucid", "php"],
  "homepage": "https://iainhouston.com",
  "minimum-stability": "dev",
  "authors": [
    {
      "name": "Iain Houston",
      "email": "iainhouston@mac.com"
    }
  ],
  "require": { }
}

```

The theme's entries extracted from the *project's* `composer.json`

```
"repositories": [{
    "type": "composer",
    "url": "https://packages.drupal.org/8"
    },
    ...
    {
    "type": "git",
    "url": "https://github.com/iainhouston/pellucid_monoset.git"
    },
    ...

```

# Answer
mradcliffe is correct:

> composer checks out the git commit hash rather than a branch if I recall correctly.

This is fairly easy to deal with though. For example, if your main branch is `8.x-1.x`, then you do some work on detached head, you can commit the work on the detached head, which will give you a hash. You then check out the `8.x-1.x` branch, and merge the hash. Since the detached head has the `8.x-1.x` branch upstream, it can be merged back into that branch after you make your changes.

Example:

```
$ git status
HEAD detached at aa284c1
$ git add file.php
$ git commit -m "Committed file.php"
[detached HEAD ef37212] Comitted file.php
$ git checkout 8.x-1.x
$ git merge ef37212

```

If you realize early enough, you can actually just run `git add` on all your changed filed, then check out the `8.x-1.x` branch. Then you can continue to work there, or make a commit on that branch. Or you can even create a new branch from `8.x-1.x` and continue your work in that branch.
> 2 votes

---
Tags: 8, composer
---


title: Multiple pagers in single page

text:
# Question
Title: Multiple pagers in single page
Hi I have a page in which I have added 2 blocks in both blocks I have paging,but when ever i click any page number of either a block both the page change simultaneously in Drupal7

$output .= theme('pager', array('tags' =\> array())); This is generating pager.

Pls help

# Answer
You can use the `element` parameter:

> An optional integer to distinguish between multiple pagers on one page.

e.g.

First call:

```
$output .= theme('pager', array('tags' => array(), 'element' => 0));

```

Second call:

```
$output .= theme('pager', array('tags' => array(), 'element' => 1));

```
> 3 votes

# Answer
I've implemented the multipage on a single page in **Drupal 8** Note:- The $element value is the key here. It should be same for both query extend and pager element.

**100% working solution.** Please find the exact solution for the same below:-

```
public function multiplePagers() {
    $build['pager_table_0'] = $this->buildTestTable(0);
    $build['pager_pager_0'] = $this->getPagerElement(0);

    $build['pager_table_1'] = $this->buildTestTable(1);
    $build['pager_pager_1'] = $this->getPagerElement(1);

    $build['pager_table_2'] = $this->buildTestTable(2);
    $build['pager_pager_2'] = $this->getPagerElement(2);

    $build['pager_table_3'] = $this->buildTestTable(3);
    $build['pager_pager_3'] = $this->getPagerElement(3);

    //render your table and pager respectively in you template
    return [
        '#theme' => 'your_theme_name',
        '#data' => $build
    ]
}

public static function getPagerElement($element){
    return [
        '#type' => 'container',
        '#attributes' => ['class' => ['test-pager-'.$element]],
        '#use-ajax' => TRUE,
        'pager' => [
            '#type' => 'pager',
            '#element' => $element,
        ],
    ];
}

protected function buildTestTable($element) {
    $header = [
        ['data' => 'wid'],
        ['data' => 'type'],
        ['data' => 'timestamp'],
    ];
    $query = Database::getConnection()->select('watchdog', 'd')->extend(PagerSelectExtender::class)->element($element);
    $result = $query
        ->fields('d', ['wid', 'type', 'timestamp'])
        ->limit(20)
        ->orderBy('d.wid')
        ->execute();
    $rows = [];
    foreach ($result as $row) {
        $rows[] = ['data' => (array) $row];
    }
    return [
        '#theme' => 'table',
        '#header' => $header,
        '#rows' => $rows,
        '#empty' => $this->t("There are no watchdog records found in the db"),
    ];
}

```

Feel free to thank me later :-)
> 2 votes

---
Tags: paging
---


# Question
Title: simplesamlphp_auth installation fails on Centos 8-server
I am trying to install simplesamlphp\_auth to Centos 8/Drupal 8 server according the instructions on:

https://www.drupal.org/docs/8/modules/apigee-developer-portal-kickstart/integrate-simplesamlphp- authentication

When I run the given command I get the following output:

```
composer require drupal/simplesamlphp_auth:3.x-dev drupal/simplesamlphp_custom_attributes --prefer-dist
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Using version ^1.0 for drupal/simplesamlphp_custom_attributes
./composer.json has been updated
> DrupalProject\composer\ScriptHandler::checkComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - don't install drupal/simplesamlphp_auth 3.x-dev|install drupal/simplesamlphp_auth dev-3.x
    - Installation request for drupal/simplesamlphp_auth 3.x-dev -> satisfiable by drupal/simplesamlphp_auth[3.x-dev].
    - Conclusion: remove simplesamlphp/simplesamlphp v1.17.7
    - Conclusion: don't install simplesamlphp/simplesamlphp v1.17.7
    - drupal/simplesamlphp_auth dev-3.x requires simplesamlphp/simplesamlphp ^1.18.2 -> satisfiable by simplesamlphp/simplesamlphp[v1.18.2, v1.18.3, v1.18.4].
    - Can only install one of: simplesamlphp/simplesamlphp[v1.18.2, v1.17.7].
    - Can only install one of: simplesamlphp/simplesamlphp[v1.18.3, v1.17.7].
    - Can only install one of: simplesamlphp/simplesamlphp[v1.18.4, v1.17.7].
    - Installation request for simplesamlphp/simplesamlphp (locked at v1.17.7) -> satisfiable by simplesamlphp/simplesamlphp[v1.17.7].

Installation failed, reverting ./composer.json to its original content.

```

So it seems, that for some reason the new enough simplesamlphp-package is not installable.

I have tried (in vain, though) to harvest the web about this problem, which should not be totally uncommon IMHO.

Any hints how to tackle the problem?

wbr

Hank

# Answer
Sorry for the trouble. The problem was caused because I had somewhere in the past installed those modules to this (test) site of my own and forgotten it totally. After removing the old simplesamlphp\_auth things seemed to go OK.
> 0 votes

---
Tags: 8, authentication-authorization
---


# Question
Title: How do I rewrite the way my view rows are displayed
I created a view and added three fields. A title, a link, and an image. When adding the image, I set the formatter as URL to image.

How do I rewrite my in my views so that each recipe can have the thumbnail as a background image instead?

In a way, each view row should be structured like this:

```
<article class="recipe" style="background-image: url({{ field_recipe_thumbnail }})">
  <h1>{{ title }}</h1>
  <p>{{ content }}</p>
</article>

```

Is there a way I can do this in my template? Note: The only question closed to mine that I found is here

# Answer
Did you override view ?? If your not override view Please follow below views view suggestion -

views-view-fields--(yourviewmachinename).html.twig views-view-unformatted--(yourviewmachinename).html.twig

Note - In views-view-fields--(yourviewmachinename).html.twig,file render your fields which are present in that view Eg. If will have field - title follow below render

{{ fields.title.content }}

Note - If your rendering page title then render {{ label }}

In these file - views-view-unformatted--(yourviewmachinename).html.twig - You will get loop here,don't change here any think.

Hope, this will help you.thanks!
> 0 votes

---
Tags: views
---


# Question
Title: How to unset node form select list element_validate?
I added a built-in select list field to a content type but left the allowed values field setting empty, since I'ld like to get the possible options to choose from dynamically.

To be precise I'ld like to offer the editors a list of files inside a certain directory to choose from. This list can grow and I don't like to touch the content type and adjust the allowed values field setting every time a new file gets added to that directory. (Editing it afterwards may even not be possible since after having values for that field in the database when nodes got added you are not allowed to change field settings anymore.)

So here I am, having the list of files added to the form widget's options array, but now I'm unable to save the selected value as it's not in the list of allowed values.

> The value you selected is not a valid choice.

OK I thought, let's simply uncheck the element validation: `unset($form['field_MYFIELD']['widget']['#element_validate'])`. As far as I can remember this worked in D7. Makes the problem even bigger.

> *TypeError:* Argument 1 passed to Drupal\Core\Field\WidgetBase::massageFormValues() must be of the type array, string given, called in /Users/Shared/www/Documents/MYREPO/web/core/lib/Drupal/Core/Field/WidgetBase.php on line 370 in *Drupal\Core\Field\WidgetBase-\>massageFormValues()* (line *505* of *core/lib/Drupal/Core/Field/WidgetBase.php*).

Is there a simple way to unset this element validation here? Or should I introduce another custom select list field and save the chosen value into a hidden textfield, simply?

# Answer
> 0 votes
The solution is here: https://chromatichq.com/blog/dynamic-default-and-allowed-values-list-fields-drupal-8

the discussion is here: https://tutel.me/c/drupal/questions/242006/how+do+i+programmatically+update+the+allowed+values+of+a+list+field

---
Tags: 8, forms
---


title: Basic page template

text:
# Question
Title: Basic page template
I am using Drupal 7 to create a page and a custom template for that page.

I created a page from *Content \>\> Add Content \>\> Page*.

In my theme /template folder I have created a file called page--my-test-page.tpl.php. In that template, I have a test echo which just displays *hello world*, which isn't displayed.

Where am I going wrong?

# Answer
> 1 votes
Theme suggestions like that do not work on node titles, out of the box. You *could* theoretically add your own suggestions based on node title, but it seems like a very bad idea to me because editors can change titles at will, which will immediately break the correspondance to the templates in your file system.

If you really want to target an individual node, `page--node--1.tpl.php` should work, where 1 is the node ID of your "My test page" content. But to be honest that is probably not a great idea either, because node IDs can also change very easily, especially between environments, whereas template filenames do not. For example you may create `page--node--57.tpl.php` because your custom page in question is node 57, but if the editor deletes it and then recreates it, even with the same name and same path, it will suddenly be node 109 and not match.

Ultimately, trying to target an arbitrary specific page with custom HTML is somewhat counter to the entire notion of a CMS. I'm not trying to sound preachy here, just explaining that you are inevitably going to be "swimming uphill" a bit here. The CMS "wants" you to do your templating based on categories and types - news stories vs events and so on - and not on the actual contents of the content, because editors can change all that on a whim.

So, you could for example solve this by writing a custom hook. See for example this example fragment which adds page.tpl suggestions based on content type. It's just PHP, so you're free to do whatever. So you can do:

```
if ($variables['node']->title == "My custom page")) {
   // the file name will be "page--customoverride.tpl.php".
   $variables['theme_hook_suggestions'][] = 'page__customoverride';
}

```

and you've got a dedicated page template for that item, but you still haven't really solved your problem, because if the editor changes title you're still back to square one.

You could of course add some extra field to your content types, like a "Use special styling" checkbox, and use that as the criteria to alter the theme suggestions. It's still possible for editors to change, but at least it's a dedicated, clearly labelled thing they won't change accidentally without realising that doing so has associated consequences to the templating.

So, hard to say what the best way to tackle this is. Depending on the scope of your site and how many staff you have, etc, it could be as simple as agreeing "Don't change the title of that page, guys!" Or you may feel obliged to create a bespoke content type purely for this one-off page, or a custom module to control this one-off page, or whatever other more complicated technical solution.

---
Tags: 7, theming
---


# Question
Title: Override templates for one view page or block
I am trying to figure out if there is a way to override the base templates for one view.
I created a page with a view called **'Promotions'**.
I need to override the `views-view-field.html.twig`, `views-view-fields.html.twig`, and `views-view-unformatted.html.twig` for just the one view/page.

I read about putting it into your custom theme's template folder in it's own folder that mimics the page name.
In my case, following the example it was `views-view-fields--promotions--page`.

The overrides work but they work for all the views (pages and blocks) that I created.
Can you narrow it down to just one view/page?

# Answer
> 2 votes
Yes.

The pattern will be something like `views-view-promotions--display_name.html.twig`

See https://api.drupal.org/api/drupal/core%21modules%21views%21views.theme.inc/group/views\_templates/8.2.x

Also, I recommend you activate Twig debugging (https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates) to see actual suggestions.

# Answer
> 1 votes
To override templates for one view page or block, i guess you should add another suggestions like **views-view-fields--VIEW\_NAME--DISPLAY\_NAME**, to do so you should implement `hook_theme_suggestions_HOOK_alter`.
here is an example for `views_view_fields` hook:

```
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MODULENAME_theme_suggestions_views_view_fields_alter(array &$suggestions, array $variables) {
  $view_id = \Drupal::routeMatch()->getParameter('view_id');
  $display_id = \Drupal::routeMatch()->getParameter('display_id');
  $suggestions[] = 'views_view_fields__' . $view_id . '__' .  $display_id;
}

```

Now if you have a view called **Promotions** and a display called **page** you will get the following suggestion:

```
views-view-fields--promotions--page

```

you can do the same to `views_view_unformatted` hook.

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


# Question
Title: How do you programatically determine who submitted a webform?
When I add a value element to a new webform draft and I attempt to prepopulate the element with a token listed as available, the element does not get populated.

# Answer
@beltouche: It should be noted that this YAML source creates a webform that internally stores the displayname property. As a result the identified user is stored wherever the webform submissions are stored. I now assume this is as designed. It seems to me that the prepopulation of a webform using something like `{{ user.displayname }}` is best accomplished by using a block/webform hybrid content type. Am I on the right track with this thinking?
> 0 votes

---
Tags: webforms
---


# Question
Title: How do I install Drupal Console to my project with Composer?
I am running my Drupal 8 project under Acquia Dev Desktop 2 and just got Composer installed. How can I add the Drupal Console to my project?

# Answer
> 9 votes
You should follow the docs on the official Drupal Console repo on how to install it with Composer. Note that the global launcher is not recommended, it is recommended to add it to your project through Composer.

https://github.com/hechoendrupal/drupal-console/blob/master/README.md

```
# Change directory to Drupal site
cd /path/to/drupal8.dev

# Download DrupalConsole
composer require drupal/console:~1.0 \
  --prefer-dist \
  --optimize-autoloader \
  --sort-packages

```

Note that the second command is all one command, not four. The `\` tells terminal the command is continuing to the next line.

# Answer
> 0 votes
In your drupal root folder just run `composer require drupal/console`, and after that add path\_to\_your\_drupal\_installtion\vendor\bin to your system PATH environment variables, and restart your cli. (Windows )...

# Answer
> 0 votes
you can install `drupal console` using `composer`

open the command line on windows then go to :

```
cd /path/to/drupal8.dev

```

now you can install `drupal console` :

```
composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader

```

after that you installed `drupal console` you can use it from drupal root directory where composer.json exist as follow:

```
vendor/bin/drupal <the_command>

```

you should replace `<the_command>` with one of the `drupal console` commands. you can see complete list of the commands here: drupal console commands

---
Tags: 8, composer, console
---


# Question
Title: How to populate an Entity Reference field from a modal AjaxResponse?
I have an entity ref autocomplete field (reference to bundle A) in one of my bundles (bundle B). I want to add a button below this field which will open a modal for a bundle A create form.

This code works great:

```
  $form['#attached']['library'][] = 'core/jquery.form';
  $form['#attached']['library'][] = 'core/drupal.ajax';
  $form['field_ref_to_bundle_a']['#suffix'] = '
    <div><a href="/node/add/bundle_a"
      class="use-ajax button"
      data-dialog-type="modal"
      data-dialog-options="{"width":800,"height":500}">' .
        t('Add New Bundle A') .
    '</a></div>';

```

When I hit Create in the modal, the new entity is created; but I need to assign this new entity to the field on the parent form (bundle B). I have added a #submit callback with a form alter on the modal form and in that callback I have:

```
  $response = new AjaxResponse();
  $response->addCommand(new CloseModalDialogCommand());
  $form_state->setResponse($response);

```

which closes the modal. In this call i know the NID of the newly created entity and I am guessing there must be some way to set the value on that field in the parent form.

Although i don't think it should be necessary, i have seen code suggesting i can use a $response-\>addCommand(new ReplaceCommand()) to swap out the entire original field with one that is populated with the default value; but i have had no luck in doing this. I have been able to use this $response call to swap out the entire autocomplete with a text string; so does seem like i am on the right path. All i really need to do is set the default value of the autocomplete field; but not sure how to do this through ajax.

Going with the idea that i need to replace the entire field (as opposed to just setting the default value); i found this code:

```
  $node = Node::load($nid);
  $elem = [
    '#type' => 'entity_autocomplete',
    '#target_type' => 'node',
    '#default_value' => $node,
    '#attributes' => [
      'id' => ['#edit-field-ref-to-bundle-a-0-target-id'],
    ],
  ];
  $renderer = \Drupal::service('renderer');
  $renderedField = $renderer->render($elem);

```

Although this does render something:

```
<div class="js-form-item form-item js-form-type-entity-autocomplete form-type-entity-autocomplete js-form-item- form-item- form-no-label">
<input id="#edit-field-ref-to-bundle-a-0-target-id" type="text" size="60" maxlength="128" class="form-text" />
</div>

```

It doesn't have a default value set. But perhaps I am close??

# Answer
Figured out it was the InvokeCommand i needed and to set "val" to the referenced entity title with id in ().

```
  $nid = $form_state->getValue('nid');
  $node = Node::load($nid);
  $value = $node->getTitle() . ' (' . $nid . ')';

  $response = new AjaxResponse();
  $response->addCommand(new CloseModalDialogCommand());
  $response->addCommand(new InvokeCommand('#edit-field-ref-to-bundle-a-0-target-id', 'val', [$value]));
  $form_state->setResponse($response);

```
> 3 votes

---
Tags: 8, forms, ajax, modal-dialogs
---


title: Programmatically add cache max-age

text:
# Question
Title: Programmatically add cache max-age
I tried setting the cache max-age to 0 in `hook_views_pre_view`, in `hook_views_pre_build` and in `hook_views_query_alter` but it just doesn't work.

Eg:

```
function my_module_views_pre_build(ViewExecutable $view) {
  $view->element['#cache']['max-age'] = 0;
}

```

The views caches the response until the caches are cleared.

I need to do this programatically because I need to force the views to not cache the results for more than 10 minutes based on some conditions.

**Later Edit**: The issue discussed in "How to use max-age" does not apply in my case. I know how to use cache tags, contexts and max-age for pages/rendered arrays and they work just fine. But for views I can't make them work.

# Answer
> 1 votes
Does it need to be done programmatically? Why not do it within the views UI, you can set the caching to "Time-based" and set a 5min limit.

This is in the "Advanced" section and the 3rd from bottom item

# Answer
> 0 votes
Views has a cache plugin for no caching which you can configure in UI. Better use this method, setting a cache max-age in a hook might not be enough to disable all caching in a view. Also you can't control traffic from anonymous users by this. If you have dynamic views you want to deliver to anonymous users uninstall the Internal Page Cache and set the Cache-Control headers in /admin/config/development/performance accordingly.

# Answer
> 0 votes
I had to use the cache\_control\_override module recently because the caching was not working for anonymous users when set from the views\_ui or even programmatically. This module just needs to be enabled and has no configuration and my views caching started working.

Sounds you might have the same problem. You can give this module a try.

The module solves this problem with bubbling the cachability data up to the page response level. Find out more info on the project's page.

---
Tags: views, 8
---


title: Alter form after submit

text:
# Question
Title: Alter form after submit
I'm creating module to use similiar words to get better search result. I have API which will returns top X similiar words for entered word. What I want to achieve is this workflow:

1. User enter some word into the search form and submit the form
2. My module call the API, gets the similiar words and change the search query

--- That is what I have done. But next part is problem ---

3. After sucesful search, alter the form to show user the similiar words I used to change the query.

At the start I expected, that I can save similiar words in `hook_search_api_solr_query_alter` and then in `hook_form_alter` change the form to show the words. But after some research I find out that is not possible, because hooks are called in different order.

Is there any way how I can alter form after submit (or validation)?

I also tried to set `form_state['rebuild']` in validation hook, but when the form is rebuild, the entered values are erased.

# Answer
`hook_form_alter` is probably a good approach for displaying the search words in the form.

Assuming you're not submitting the form via AJAX, you need a way of passing the search words to the *next* page load. One way might be to redirect to the same URL but adding your search words as URL query parameters. You could do that by setting $form\_state\['redirect'\] or calling drupal\_goto in your *submit* function.

Another way, maybe easier, would be to save your search words in the user's session and reading them back in the subsequent page.
> 0 votes

---
Tags: 7
---


# Question
Title: How to run a cron queue programmatically?
I have created a cron queue like given below.

```
function mymodule_cron_queue_info() {
  $queues['aggregator_feeds'] = array(
    'worker callback' => 'aggregator_refresh',
    'time' => 60,
  );
  return $queues;
}

```

My cron runs when calling drush cron. I need to run the queue 'aggregator\_feeds' individually without invoking any other cron queues. Drupal admin panel -\> config -\> cron : runs all queues as per schedule. drush cron command too runs all queue. How do I run a single queue programmatically?

Also I need to know how to run all the queues programmatically?

# Answer
For one of my project, this worked for me :-

```
$queue_machine_name = 'sync_product_list';
$queue = \Drupal::queue($queue_machine_name);
$queue_worker = \Drupal::service('plugin.manager.queue_worker')->createInstance($queue_machine_name);
$item_id = '123';
$queue_worker->processItem($item_id);

```
> 3 votes

---
Tags: hooks, cron, queue
---


# Question
Title: How to process more than one item from queue in each run?
I have set up a queue using this code.

```
function custom_logger_cron_queue_info() {
  $queues['custom_logger'] = array(
    'worker callback' => 'custom_logger_import',
    'time' => 60,
  );

  return $queues;
}

```

I add items using this code.

```
$item = array('uri' => $uri, 'uid' => $uid, 'fid' => $fid);
$queue = DrupalQueue::get('custom_logger');
$queue->createItem($item);

```

It works great, except that when cron runs every minute for this queue (I am using the *Ultimate Cron* module to set this) the `custom_logger_import()` is only processing one item per run.

```
function custom_logger_import($item) {
  $uri = $item['uri'];
  $uid = $item['uid'];
  $fid = $item['fid'];
  // …
}

```

Is there something I am missing on ensuring that more items are handled? They are only small jobs that complete in less than a couple seconds, but at the moment its taking 3-4 minutes to process just 3 items.

# Answer
> 3 votes
The queue system is designed to process items until the time is up. Maybe it's a bug in Ultime Cron? Try running the default core cron.php to verify that.

Are you sure that you're actually adding multiple items to be processed? Check your queue table.

# Answer
> 2 votes
If you want to do it programmatically instead of cron job, then this could be one of the option -

```
$queue_machine_name = 'custom_logger';
$queue = \Drupal::queue($queue_machine_name);
$queue_worker = \Drupal::service('plugin.manager.queue_worker')->createInstance($queue_machine_name);
$item_ids = ['1','2','3'];
foreach ($item_ids as $item){
  $queue_worker->processItem($item_id);
}

```

---
Tags: hooks, cron, queue
---


title: Using #states with field collection

text:
# Question
Title: Using #states with field collection
I'm trying to use #states in a unlimited field collection (using the field collection module).

I'm adding this functionality to a node add form so am altering form elements using hook\_form\_alter.

I can get it to work for the first item in the collection using the following code but it doesn't work for items added subsequently.

```
$form[$k]['field_employee_name']['#states'] = array(
    'visible' => array(
        ':input[name="field_witnesses[und][0][field_person_type][und]"]' => array('value' => 'Employee'),
    ),
);

```

# Answer
> 2 votes
To get this to work we need to add the #states functionality to every field collection after the ajax callback has taken place.

To do this add an #after\_build function to the field collection item in hook\_form\_alter:

```
$form['field_witnesses'][LANGUAGE_NONE]['#after_build'][] = 'field_witnesses_after_build';

```

And then in the after build function loop over the elements to add the #states behavior:

```
function field_witnesses_after_build($form, &$form_state) {
    foreach($form as $k => $v) {
        if(isset($v['#entity_type']) && $v['#entity_type']=='field_collection_item') {

            $form[$k]['field_employee_name']['#states'] = array(
                'visible' => array(
                    ':input[name="field_witnesses[und]['.$k.'][field_person_type][und]"]' => array('value' => 'Moto Employee'),
                ),
            );

        }
    }
    return $form;
}

```

# Answer
> 1 votes
Thank you for posting this, I was really going crazy trying to make #states work with hook\_form\_alter and your post saved the day! Just to clarify, I'm going to provide some greater detail about how I got this to work:

1. I created a new content type. It has some of its own fields. I then added a field collection to the content type with machine name "field\_volunteer\_jobs".
2. I edited the field collection and added fields for a boolean (checkbox) with machine name "field\_vol\_use\_event\_date" and a date with machine name "field\_vol\_date".
3. When a person is entering data on the content page, I want the date field to be hidden whenever the checkbox is checked.
4. I created a new module, named "states". In the module, I have the following hooks:

```
function states_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'school_event_node_form':
    $volunteer_jobs_lang = $form['field_volunteer_jobs']['#language'];
    $form['field_volunteer_jobs'][$volunteer_jobs_lang]['#after_build'] = array('states_after_build');
break;
}
}
function states_after_build($form, &$form_state) { //works!
  foreach($form as $k => $v) {
    if(is_numeric($k) && isset($v['#entity_type']) && $v['#entity_type']=='field_collection_item') {
      $form[$k]['field_vol_date']['#states'] = array(
        'invisible' => array(
        ':input[name="field_volunteer_jobs[und]['. $k.
        '][field_vol_use_event_date][und]"]' => array('checked' => TRUE))
      );
    }
  }
  return $form;
}

```

Note that in the states\_after\_build code above, I should really query the field #language and use that instead of \[und\]...

# Answer
> 0 votes
I fixed it for fieldset adding an `#id` attribute and set `#states` in `hook_field_group_build_pre_render_alter`.

```
/**
 * Implements hook_field_group_build_pre_render_alter().
 */
function MY_MODULE_field_group_build_pre_render_alter(&$element) {
  if ($element['#form_id'] === 'MY_FORM' && isset($element['MY_FIELDSET_NAME'])) {
    // Add form states to the field group.
    $element['MY_FIELDSET_NAME']['#id'] = 'MY_FIELDSET_NAME';
    $element['MY_FIELDSET_NAME']['#states'] = [
      'invisible' => [
        ':input[name="CONDITION_FIELD"]' => ['value' => 'CONDITION_VALUE'],
      ],
    ];
  }
}

```

---
Tags: javascript
---


# Question
Title: Entity Data not available in hook_entity_insert
I have written hook\_entity\_insert for pdf file generation. Want the pdf file to be generated immediately after the entity is created.

```
function general_inspection_checklist_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
    if($entity->getEntityTypeId() == "services_entity" && $entity->bundle() == "general_inspection_checklist"){
        $entity_id = $entity->get('id')->getValue(); // Get Entity Id
        $link = $GLOBALS['base_url']."/entityprint/pdf/services_entity/".$entity_id[0]['value']; // Pdf URL
        $timestamp = date("Y-m-d_H:i:s");
        $data =  file_get_contents($link);
        //$filename = 'Booking_'.$timestamp.'_'.$entity_id[0]['value'].'.pdf';
        $filename = 'Booking_'.$entity_id[0]['value'].'.pdf';
        $path = 'public://bookings'; // Create a path
        if (file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
            $fileuri = 'public://bookings/'.$filename;
            $file = file_put_contents($fileuri, $data);
            $file = File::create([
                'uid' => \Drupal::currentUser()->id(),
                'filename' => $filename,
                'uri' => $fileuri,
                'status' => 1,
            ]);
            $file->save();
        }
       $entity_name = $entity->get('name')->getValue(); // Get Entity Name
        // Load Service Entity based on ID
        $serviceentity = \Drupal::entityTypeManager()->getStorage('services_entity')->loadByProperties(['id' => $entity_name[0]['value']]);
        $serviceentity = reset($serviceentity);
        if(!empty($serviceentity)){
            //$field_booking_sheet = $serviceentity->get('field_booking_sheet')->getValue();
            // if(!empty($field_booking_sheet)){
            //     ksm($field_booking_sheet);
            // }
            // else{
                $serviceentity->set('field_booking_sheet', ['target_id' => $file->id()]);
                $serviceentity->save();
            //}
        }
    }
}

```

# Answer
You are trying to access a link which will be available only after the entity is saved in database. But the `hook_entity_insert` is called before the entity it is completely saved in the dataase. So, the PDF link won't be available.

```
$link = $GLOBALS['base_url']."/entityprint/pdf/services_entity/".$entity_id[0]['value']; // Pdf URL

```

You can use `drupal_register_shutdown_function` in such cases. You can put your PDF related code in another function and just register it here with `drupal_register_shutdown_function`. It's basically telling drupal that, after the `entity_insert()` function has run completely, execute this block of code.

```
function general_inspection_checklist_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
        if($entity->getEntityTypeId() == "services_entity" && $entity->bundle() == "general_inspection_checklist"){
            $entity_id = $entity->get('id')->getValue(); // Get Entity Id

            drupal_register_shutdown_function('YOUR_CUSTOM_FUNCTION', $entity_id);

        }
    }

function YOUR_CUSTOM_FUNCTION($entity_id){
    //Your STUFF
    $link = $GLOBALS['base_url']."/entityprint/pdf/services_entity/".$entity_id[0]['value']; // Pdf URL
    $timestamp = date("Y-m-d_H:i:s");
    $data =  file_get_contents($link);
    //$filename = 'Booking_'.$timestamp.'_'.$entity_id[0]['value'].'.pdf';
    $filename = 'Booking_'.$entity_id[0]['value'].'.pdf';
    $path = 'public://bookings'; // Create a path
    if (file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
        $fileuri = 'public://bookings/'.$filename;
        $file = file_put_contents($fileuri, $data);
        $file = File::create([
            'uid' => \Drupal::currentUser()->id(),
            'filename' => $filename,
            'uri' => $fileuri,
            'status' => 1,
        ]);
        $file->save();
    }

}

```
> 0 votes

---
Tags: hooks
---


# Question
Title: How to create a page to custom display of particular node type and add it to node context menu?
* I created custom node type, let's say "My Node".
* I created custom node display type (at /admin/structure/display-modes/view), let's say "Specialized Display".
* Configured the "Specialized Display" for "My Node" - configured some fields, their order, etc.
* How can I create a page on path "node/\*/specialized-display" for "My Node" nodes using "Specialized Display"? (I.e. reject "node/123/specialized-display" if "node/123" is not "My Node", but e.g. "story".)
* How can I make a tab appear in node context menu (the one which contains "View", "Edit", "Delete" tabs)?
* Bonus question: how can I make URL automatic alias(es) "\[alias of node/%\]/specialized-display"?

**What I tried**

Created view page, path "node/%/specialized-display", use contextual filter (to reject different node types, use argument for node selection and to alter page title).

Problems:

* Couldn't find out how to add it to the node context menu.
* It creates redundant node title on the page (one for whole page and one for item in view). Couldn't find out how to remove it, but it's not that big problem, I'll remove is using CSS (although accessibility is going to be damaged).

**My system**: Drupal version: 8.8.3

# Answer
**First question:** First you are going to want to set your views path to: `node/%node/specialized-display`. Then, in the contextual filter, under "WHEN THE FILTER VALUE IS AVAILABLE OR A DEFAULT IS PROVIDED" check off: Specify validation criteria. Finally, select "Content" from the dropdown and select your node type.

**Second Question:** This guide explains how to add contextual links, all you are going to need a basic custom module with a routing.yml file. You can set the route to the view. Hint, Drupal console's `drupal debug:router` is a great way to find the route to your view. https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-contextual-links#s-rendering-contextual-links

**Third question:** I've had my best luck with the sub-pathauto module to make the aliased routes. https://www.drupal.org/project/subpathauto

Thoughts... I am using this setup on two sites so far and this works pretty well. Sub-Pathauto seems to behave fairly well. I do have one tip though, when initially building my views, I disable it, so that I can ensure everything works before I add the extra layer.

Other thoughts... This could be done through traditional custom views processing. If you have a big site, it may be the way to go. I haven't tested Sub-Pathauto at large scale, this is currently something I am experimenting with.
> 0 votes

---
Tags: 8, nodes
---


title: Curl response into variable

text:
# Question
Title: Curl response into variable
Similar to Problem with cURL I have an api response which is returned at numerals only

If I break the code with a `print_r($rate);` which is where I point the curl response to an ajax error shows the correct response is being sent back as "ResponseText:0.09876787(command: . . . etc - but apparently it is not being put into the variable by

```
   $rate = curl_exec($ch);

```

my code runs fine at /devel/php and is returned into the variable and the code which uses `$rate` also runs to completion without any json decode and it is being sent as a html page if anything - as the number alone shows in a browser and page inspection shows html headers. The number `0.09876787` is what should be `$rate`.

I have fixed the http calls so no & is being changed to `&amp` as I have seen happen and the post above refers to also

So it runs correctly in the php devel window but not in the actual module

Is there something else different drupal 7 does to the response or needs to be done in code?

# Answer
> 0 votes
The website called to by curl needed to return a simple string integer - but it returns a single line html page which displays the string integer sought in the browser window with the sought after response integer in it. Thus what worked was to call website to get the response as a single mixed string and then strip everything but numbers and the decimal point with this code below

```
 $dom = str_get_html(curl_exec($ch));  // get html as dom
 $str = $dom->save();  //  save as string
 $rate = preg_replace("/[^.0-9]/", "", $str);  // strip text

```

Which works and absolutely produces a string integer variable - and after all that I discovered the real issue was elsewhere in the module code

---
Tags: 7
---


title: Show views only on one specific node

text:
# Question
Title: Show views only on one specific node
I think my question is very simple, but I was searching for long time for a good solution.

How do you integrate in Drupal 7 one views (e.g. page or block) inside or after one single node (e.g. node/10). What is the best solution?

Until now I used the drupal block system to attach one views-block after a single node. But I read, is not a good solution.

Thanks

# Answer
> 1 votes
That's the best use case for the Viewfield module. It works providing a custom field, so you can "attach" a view to nodes.

You can provide a default view if you want to display the same view on many nodes.

Or you can provide a custom argument to pass to the view.

# Answer
> 0 votes
In view block, select filter criteria, select title

---
Tags: views
---


# Question
Title: How to get rid of Deadlocks and Lock time out type issues?
I read multiple blogs, tried to google, it but didn't find any satisfaction from any solution. I have the following issues :

```
PDOException: SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction: DELETE FROM {cache_field} WHERE (cid LIKE :db_condition_placeholder_0 ESCAPE '\\') ; Array ( [:db_condition_placeholder_0] => field\_info:% ) in cache_clear_all() (line 163 of \includes\cache.inc).

PDOException: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction: SELECT 1 AS expression FROM {sessions} sessions WHERE ( (sid = :db_condition_placeholder_0) AND (ssid = :db_condition_placeholder_1) )

```

I tried to solve this by increasing `innodb_pool_buffer_size` and `wait_timeout` in my.ini but didn't worked.

I changed my cache table's engine from Innodb to MyIasm. The issue gone but it is not a perfect solution. The table engine will be changed after an upgrade of drupal. This issue doesn't affect anything on the site but I don't want this to occur.

Any solution guys?

# Answer
Read and follow this post; it assumes InnoDB.

In particular, see the part saying to add the following to the settings.php file.

```
$databases['default']['default']['init_commands'] = array('isolation' => "SET SESSION tx_isolation='READ-COMMITTED'");

```
> 21 votes

# Answer
The best way to get rid of deadlock errors once and for all is the Asynchronous Prefetch Database Query Cache module.

I can't recommend it enough. Brilliantly written and great performance gains.
> 5 votes

# Answer
I tried to apply patch https://www.drupal.org/project/drupal/issues/1650930.

Still I am facing issue on AWS
> 1 votes

---
Tags: 7, performance, database
---


# Question
Title: Create template suggestion for item-list.html.twig
I have to change the markup and I have to add CSS classes to `themes/classy/templates/dataset/item-list.html.twig`. But only for a specific `item-list.html.twig` in a specific block.

How do I create a preprocess function, which create a template suggestion for this `item-list.html.twig`? So I am able to use e.g. `item-list-facets.html.twig`?

# Answer
> 4 votes
I think it's better to use hook\__theme\_suggestions\_HOOK\_alter:

Something like this:

```
 /**
 * Implements hook__theme_suggestions_HOOK_alter().
 */
function MYTHEME_theme_suggestions_item_list_alter(&$suggestions, $variables) {
  $suggestions[] = 'item_list__' . str_replace('-','_',$variables["attributes"]["id"]);
}

```

Just make sure that in your suggestions name you use _ instead of -, otherwise you will get suggestions in the debug, but Drupal won't use it.

# Answer
> -1 votes
If its a class you might not need to have a separate twig file, but can simply add a class in your preprocess.

```
/**
 * Implements hook_preprocess_HOOK().
 */
function MYTHEME_preprocess_item_list($variables) {
  // conditional class
  $variables['custom-class'] = _some_function_to_return_class();
}

```

Copy the `item-list.html.twig` to your custom theme folder, and use the class.

---
Tags: 8, theming
---


title: Set Default Value for Node Title

text:
# Question
Title: Set Default Value for Node Title
I have a content type named `Account`, and it has a field named `account_number`. Since I import the data from a csv file using feeds. The Node title for each account is always empty.

Is there a way to set the node title default to its `account_number`?

Thanks

# Answer
I haven't used this personally, but the Automatic Nodetitles module is designed to handle tasks like this. If you have Token installed and enabled, you should be able to populate the autotitle using a field value.
> 4 votes

# Answer
On Drupal 8, you can use Automatic Entity Label module.
> 1 votes

---
Tags: nodes
---


title: How to uncache jsonapi?

text:
# Question
Title: How to uncache jsonapi?
As usual, I am debugging something and this time, it's jsonapi. I already have `$settings['cache']['bins']['render'] = 'cache.backend.null';` and `$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';` this works for HTML, how do you force JSONAPI to not cache?

# Answer
This is due to the internal page cache and Internal dynamic page cache, Drupal will heavily cache all GET requests, so what you are missing is

```
$settings['cache']['bins']['page'] = 'cache.backend.null';

```

as the 3rd bin to clear but this won't work due to dynamic cache, so can you either manually purge the entire Drupal cache or set a timestamp into your URL so you can bypass caching for development.

```
node/1?_format=json&time=123456789

```
> 3 votes

---
Tags: 8
---


# Question
Title: Use page.html.twig template variable in another twig template
How do I call a **page.html.twig** template variable from the **book-tree.html.twig** template.

Using **kint**, I have found the variable, **nid** as in the screenshot below:

The '**nid**' is highlighted, but it is the '**x-default** value that is required.

This variable will be used in a **set** statement, comparing it to the **item.original\_link.nid** to set an active class.

This page **nid** is not available within the **book-tree.html.twig** template.

As per Answer 1, I have created a `_preprocess` function in my subthemes .theme file as below:

```
function subtheme_bs_preprocess_book_tree(&$variables) {
 $variables['page_nid'] = 'Add code to get the node id variable';
}

```

The variable `page_nid` now shows up in the `book-tree.html.twig` array. The result is `'page_id' => string(36) "Add code to get the node id variable"` which is the static text I added.

I would like help on how to call the `nid` value from the `node.html.twig` template. I have tried several combinations:

`$variables['page_id'] = $variables['page']['content']['book_navigation']['#book_link']['nid']` But this and many other compinations I have tried all end with a:

`Notice: Undefined index: page in subtheme_bs_preprocess_book_tree()`

Maybe I need to call an `Available method` but have no clue as to how this is done.

Below is a screenshot of the `{{ kint() }}` output from the top of the `node.html.twig` file.

the value I need to target is the **115** in this line **'x-default' =\> value (3) 115**.

Many thanks in advance.

# Answer
The book-tree.twig is rendered in its own scope. It does not "know" any of the context it is being rendered in, so it can't tap into the variables from the page twig per se. It only gets the variables you give it. So you could implement a `THEME_preprocess_book_tree(&$variables)` hook to add it in. `$variables['page_nid'] = // your code here` will make it available in twig as `{{ page_nid }}`.

However at the risk of being "that annoying guy" who tells you not to do things instead of just answering your question

> This variable will be used in a set statement, comparing it to the item.original\_link.nid to set an active class.

Personally I would eschew this approach as it ends up placing logic inside the presentation layer. I would rather use the hook to compare item nids to page nid, and add the active class to that item's `attributes` as appropriate. That way the twig can be kept extremely "stupid", and simply dump out whatever attributes for all items, and those attributes will magically contain (or not contain) the appropriate classes.
> 0 votes

---
Tags: theming
---


title: Access Drupal globals in Twig

text:
# Question
Title: Access Drupal globals in Twig
As documented here, there are some global variables defined by Drupal. How can I access them in twig?

# Answer
> 6 votes
These variables are not available to template files, but you can easily add it to every template file by implementing hooks.

You need to prepare variable for twig files. To use the global variables in twig files you need to set it.

Prepares variables for the page template:

You will get details template\_preprocess\_page.

```
function template_preprocess_page(&$variables) {
  $variables['base_path'] = base_path();
}

```

# Answer
> 0 votes
You can use hook\_template\_preprocess\_default\_variables\_alter(): https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21theme.api.php/function/hook\_template\_preprocess\_default\_variables\_alter/8.2.x

This hook allows to add variables to all templates which are passed to twig.

# Answer
> -1 votes
Injecting variables to twig templates from a custom module, for example the 'module path' :

```
function custom_module_preprocess(&$variables, $hook) {

  $module_handler = Drupal::service('module_handler');
  $path = $module_handler->getModule('amu_http_status_code_display')->getPath();

  if($hook == 'page') {
    $variables['module_path'] = $path;

  }

}

```

---
Tags: theming, 8
---


title: Hide region when block menu is empty

text:
# Question
Title: Hide region when block menu is empty
I got the 2nd level main menu in a block in the sidebar, drupal 8 correctly hides the menu (and the block) when the user browses a page that is not in this menu, but the theme continues to show the empty region. The condition {% if page.region %} is true. is there any way to solve this problem?

# Answer
> 4 votes
It is better to use construction

```
{% if page.region|render|striptags|trim|length > 0 %} ... {% endif %}

```

So you can check if there is some content or not.

# Answer
> 2 votes
I you use menu\_block module, this patch will fix the problem of a region showing up even when there are no subitems for a menu. Only tested on menu block version 8.x-1.5.

# Answer
> 0 votes
You can use `{% if page.region|render|striptags %}` to make sure the regions actually has content. See also the discussion here: \[meta\] Themes improperly check renderable arrays when determining visibility.

# Answer
> 0 votes
I did it this way to reduce the number of renders.

```
{% set render_sidebar_first = page.sidebar_first|render %}
{% if render_sidebar_first and render_sidebar_first|striptags|trim|length > 0 %}
  {% block sidebar_first %}
    <aside class="{{ sidebar_class }}" role="complementary">
        {{ render_sidebar_first }}
    </aside>
  {% endblock %}
{% endif %}

```

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


title: Composer require got killed

text:
# Question
Title: Composer require got killed
I'm working on a live site and I'm trying to install a module using composer, but the proccess is killed. I found out that is due to server RAM. So, I am unable to work with composer, is there any solution?

# Answer
Composer is a notorious memory hog, and some web hosts will not allow you to run it on a production server. Even if it is allowed, it is not necessarily a good idea to deploy things this way.

The preferred method is to keep your project in version control (e.g., `git`) and then check out a feature branch in your local development environment.

Install the module using Composer in your feature branch, perform any code review, testing, or QA that you need to do, and then do one of the following:

* if you have some form of Continuous Integration / Continuous Delivery set up, you can merge the code into `dev` or `master` branch and use a git hook to automate build and deploy to the target hosting environment
* if you don't have any CI/CD tools, build your site in the local environment and use something like `rsync` (or SFTP) to deploy it to the remote server
> 2 votes

---
Tags: composer
---


# Question
Title: Upgraded to 8.8.3 and now all of my modules say "No available releases found"
I just recently updated to 8.8.3 and for some reason, all of my modules now say "No available releases found". Also the one module I had that did report "No available releases found" (Video Embed for google drive), is now saying that that module is up to date. It is like they switched somehow when I updated. I might roll back but the site is currently working just fine. Any ideas?

# Answer
> 1 votes
Clicking "Check manually" once on the Available Updates page will resolve this issue.

Please see https://www.drupal.org/project/drupal/issues/3120168 for more info.

# Answer
> 0 votes
It seems like the problem fixed itself. I am wondering if a cron job took care of it. I cleared cache and updated the DB, I just never thought to run cron.

---
Tags: 8, updating
---


# Question
Title: Why does this simple javascript execute multiple times?
Why does this javascript execute 2-4 times per page load:

```
// mei_library_turn.js
(function ($, Drupal) {
  Drupal.behaviors.mei_library_turn = {
    attach: function() {

      console.log('ready1');

      // There would be a lot more code in here, but I've stripped it all out to debug.

    }
  };

})(jQuery, Drupal, drupalSettings);

```

That is the entirety of the javascript file. What could possibly be causing this to fire multiple times? The script is not included in the head of the document multiple times.

Most often, when I load the page, it fires 3-4 times. Sometimes just two times.

I realize once() can be used to mask problems like these, but it adds complexity to scripts and I would like to understand what is causing the code to execute multiple times in the first place.

Here is the page where I attach the library:

```
public function book($marc_num) {

    $output = [];

    $output['something']['#attached']['library'][] = 'mei_library/librarybook';

    return $output;

  }

```

Here is my libraries file:

```
librarybook:
  version: 1.x
  js:
    js/mei_library_turn.js: {}

```

# Answer
> 11 votes
Behaviors will be executed on every request, including AJAX requests.

you can use the once function to make sure it is only triggered once.

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

       $('main', context).once('mei_library_turn').each(function () {
          console.log('ready1');
       };)

      // There would be a lot more code in here, but I've stripped it all out to debug.

    }
  };

})(jQuery, Drupal, drupalSettings);

```

---
Tags: javascript
---


# Question
Title: In node add, how to upload file using image from clipboard
How can I paste image from clipboard and save into image\_field ?

# Answer
You could try the FileField Sources module. It provides quite a few additional options to upload files.

> * Re-use files by an auto-complete textfield
> * Attach server-side files uploaded via FTP
> * Transfer files from a remote server (cURL required)
> * **Paste a file directly from the clipboard (Drupal 7 only)**
> * Select existing files through the IMCE file browser
> 0 votes

---
Tags: 7, nodes, javascript, blocks, files
---


# Question
Title: Why is libraries-override not removing assets?
My attempt to remove CSS and JS assets is not working. I have placed the following declarations in my module's \*.info.yml file. But after clearing the cache, I still see the assets in the head of the document. Is there anything wrong with my syntax:

```
libraries-override:
  global-styling:
    css:
      base:
        /themes/stack/css/lightbox.min.css: false
    js:
      /themes/stack/js/lightbox.min.js: false

```

Here is the relevant Drupal documentation: https://www.drupal.org/docs/8/theming/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-theme#override-extend

I also tried these for the key:

* stack/global-styling
* stack.global-styling

I also tried it without the full paths:

```
libraries-override:
  stack/global-styling:
    css:
      base:
        lightbox.min.css: false
    js:
      lightbox.min.js: false

```

Nothing is working so far.

# Answer
This doesn't answer the original question, but turns out to be a better solution in my case. You must clear your cache with each change to this function:

```
/**
 * Implements hook_library_info_alter().
 */
function example_library_info_alter(&$libraries, $extension) {

  // If you have 'stack' as your subtheme, you might have unwanted lightbox assets.
  if ('stack' === $extension) {

    if (isset($libraries['global-styling'])) {

      $current_path = \Drupal::service('path.current')->getPath();
      $path_args = explode('/', $current_path);

      // Your conditions may vary.
      if ('book' == $path_args[1] && isset($path_args[2]) && is_numeric($path_args[2])) {

        // Helper function below.
        if (example_array_key_exists_r('css/lightbox.min.css', $libraries)) {
            unset($libraries['global-styling']['css']['base']['css/lightbox.min.css']);
        }

        if (example_array_key_exists_r('js/lightbox.min.js', $libraries)) {
            unset($libraries['global-styling']['js']['js/lightbox.min.js']);
        }

      }
    }
  }

}

/**
 * Recursively search for an array key.
 *
 * @see https://stackoverflow.com/a/2948985/861826
 *
 */
function example_array_key_exists_r($needle, $haystack) {

  $result = array_key_exists($needle, $haystack);

  if ($result) return $result;

    foreach ($haystack as $v) {
      if (is_array($v)) {
        $result = example_array_key_exists_r($needle, $v);
      }
      if ($result) return $result;
    }

    return $result;
}

```
> 0 votes

---
Tags: theming, javascript
---


title: Can't log in to back end

text:
# Question
Title: Can't log in to back end
I have been trying to upgrade to 8.8.3 from 8.4.4 for some time. My 8.4.4 site was holding but after repairing a database malfulnction in which the watchdog file went mad with assert errors, now I can't login to the back end. After failing to login using the login module on the front page, the WSOD appears with this meesage.

'''The website encountered an unexpected error. Please try again later.Drupal\Core\Extension\InfoParserException: Missing required keys (core) in core/modules/path\_alias/path\_alias.info.yml in Drupal\Core\Extension\InfoParserDynamic-\>parse() (line 29 of core/lib/Drupal/Core/Extension/InfoParserDynamic.php).'''

I don't know where to start with this.

# Answer
This is due to the new `core_version_requirement` key taking the place of the `core` key in **module.info** files. Here's the change record: https://www.drupal.org/node/3070687.

A dirty hack to get around this would be to add the following to **path\_alias**'s .info file:

* `core: 8.x`

I would do this only for the purpose of getting your site back in order, and remove the key afterwards. You are likely to run into this error, or similar, for other modules as well. I think that disabling the **path\_alias** module, and any other troublesome modules, prior to upgrade might help.

This change record about **path\_alias** becoming its own core module might be relevant, as well: https://www.drupal.org/node/3092086.

It's also worth mentioning that, if you have drush installed, you can get a one-time login link by running `drush uli 1`. You'll get a link that looks something like this: http://default/user/reset/1/1584508997/mFfBCIO2zmwKOm3Bh7l5bBwGxwMO6MVqJ6-S-cvZ-pU/login. Take the part of the URL starting with "/user" and append it to your domain name.

Ex: http://my.site.dev/user/reset/1/1584508997/mFfBCIO2zmwKOm3Bh7l5bBwGxwMO6MVqJ6-S-cvZ-pU/login
> 0 votes

---
Tags: maintenance-mode
---


# Question
Title: Get all the paragraphs of the current node programmatically in form_views_exposed_form_alter
I have a content type with multiple field paragraph. I would like to get all the paragraphs from the current node in form\_views\_exposed\_form\_alter.

I tried

```
 $node = menu_get_object();
 $storage = Drupal::getContainer()->get('entity_type.manager')->getStorage('paragraph');
 $pids = $storage->getQuery();

```

which gets me all the paragraphs not only the ones of the current node. What am I missing?

# Answer
I'm assuming that the paragraphs are attached to your node via field. Let's assume the field is called `field_paragraphs`. Try the following:

```
$node = \Drupal::routeMatch()->getParameter('node');
$paragraphs = $node->get('field_paragraphs')->getValue();

```

This works because Drupal's routing system utilizes upcasting to promote the nid to a fully loaded node reference.
> 0 votes

---
Tags: views, 8, paragraphs
---


# Question
Title: Is there any way to get only the custom roles?
I would like a list of all custom roles. Currently I am loading all of them using

`$roles = $this->entityManager->getStorage('user_role')->loadMultiple();`

but am wondering if there is any function that only brings the custom ones besides manually creating a static filter for the Anonymous, Authenticated and Administrator.

# Answer
> 0 votes
As @stevekeiretsu said in a comment -\>

The Role entity doesn't really make any distinction. Looking at the roles in my own db (filter config table by name LIKE user.role%) the only potential contender I can see is that the three default ones have a dependency on \_core, so you could check that via getDependencies, but that feels arguably flakier than a static filter to me.

So for Drupal 8 there is no function defined.

---
Tags: 8, users
---


# Question
Title: how to create template of user register, login and forget password in drupal 8?
How to create template of user register, login and forget password in drupal 8 can we create template same as we created earlier in drupal7 ?

I want to open these forms in popup on clicking links

# Answer
> 7 votes
Yes it same as drupal 7.

For example:

We are using `page--user--register.tpl.php` for registration page template in D7. In D8 changed to twig extension `page--user--register.html.twig`.

You can enable debug mode in D8 so you can easily see the twig file need to use in your case. You can refer Drupal 8 custom page template to see how to enable debug mode.

Some links how to override the template files.

https://www.drupal.org/node/2521876

https://www.drupal.org/docs/8/theming/twig/working-with-twig-templates

https://www.drupal.org/node/2668886

# Answer
> 1 votes
for your case answer is `page--user--register.html.twig`, but generally, you can use below twig template naming suggestions:

```
page--user.html.twig
page--user--login.html.twig
page--user--password.html.twig
page--user--register.html.twig

```

I suggest you use `page--user.html.twig`, for all of these pages.

---
Tags: theming, 8
---


# Question
Title: Can you make a field unique in a content type?
I have an *Employee* content type with an *ID* field.

Can I make the field unique, so that Drupal would prevent me from entering the same *ID* more than once by mistake?

# Answer
> 5 votes
You can add a validation constraint to your field.
There is two ways to do that:

1. Setting a validation constraint to a field you haven't defined by implementing `hook_entity_bundle_field_info_alter`:

```
function YOURMODULE_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  if ($entity_type->id() === 'ENTITY_TYPE' && $bundle === 'BUNDLE_NAME') {
    if (isset($fields['FIELD_NAME'])) {
      $fields['FIELD_NAME']->addConstraint('UniqueField');
    }
  }
}

```
2. Setting a validation constraint to a field you have defined in baseFieldDefinitions

```
public static function baseFieldDefinitions(EntityTypeInterface $entityType) {
 $fields['FIELD_NAME'] = BaseFieldDefinition::create('string')
   ->setLabel(t('MY UNIQUE FIELD'))
   ->addConstraint('UniqueField');

 return $fields;
}

```

If you want to create your own validation constraint you can check here.

# Answer
> -2 votes
A core Drupal way to achieve your result:

1. Create Taxonomy "Employee ID".
2. Add Taxonomy reference field to "Employee" content type.
3. Ensure to check "Create referenced entities if they don't already exist" in field settings.

You will know if the ID exists if the term can be referenced. Plus this data becomes easily reusable.

---
Tags: 8
---


title: Troubles with external configuration

text:
# Question
Title: Troubles with external configuration
I'm working in the creation of a custom profile.

When the installation is already finished, on the configuration module /admin/config/development/configuration appears the following warning

> The staged configuration cannot be imported, because it originates from a different site than this site. You can only synchronize configuration between cloned instances of this site.

All my configuration based on new changes is exported to

> web/profiles/DISTRIBUTION\_NAME/config/install

using the following sh file

```
ddev exec drush cex
find ./web/profiles/DISTRIBUTION_NAME/config/install/ -type f -exec sed -i -e '/^uuid: /d' {} \;
find ./web/profiles/DISTRIBUTION_NAME/config/install/ -type f  -exec sed -i -e '/_core:/,+1d' {} \;

rm -f ./web/profiles/DISTRIBUTION_NAME/config/install/core.extension.yml ./web/profiles/DISTRIBUTION_NAME/config/install/update.settings.yml ./web/profiles/DISTRIBUTION_NAME/config/install/file.settings.yml

```

so, what i'm doing wrong or what else is missing?

# Answer
> 0 votes
The problem was about a relative path in the file:

> web/sites/default/settings.php

```
$config_directories['sync'] = 'web/profiles/DISTRIBUTION_NAME/config/install';

```

---
Tags: drush, configuration, installation-profiles
---


# Question
Title: How to execute custom code at Drupal startup
What's the correct way to execute code from an existing custom module at Drupal startup? The code checks certain private\_tempstore values and sets other values based on what it finds. It should be executed before page processing occurs so that pages can respond to the changed values.

I've read many posts, looked through the list of hooks, tried a few without success, looked at event subscribing, etc. All my searching and trying hasn't found an approach that works correctly for my situation.

Example custom code (not the real code):

```
$rsc = \Drupal::service('user.private_tempstore')->get('rsc');
$val = $rsc->get('temp_val');

if ($val == 100) {
  $rsc->set('temp_val', 200);
}

```

What I've tried:

```
hook_page_build() // in mymodule.module
hook_page_alter() // in mymodule.module
path: '/*' // in mymodule.routing.yml

```

No error messages, just no results via an error\_log() in the custom code to show that it was executed.

# Answer
> 2 votes
First of all, User module's user.private\_tempstore and user.shared\_tempstore services moved to core. So we want to use the `tempstore.private`.

The code below will get your started. you will want to read more about how `getSubscribedEvents()` works, as here is where you tweak the where and when of your event.

Don't forget an .info.yml file!

/mymodule/mymodule.services.yml

```
services:
  mymodule.mymodule_subscriber:
    class: Drupal\mymodule\MyModuleSubscriber
    arguments:
      - '@tempstore.private'
    tags:
      - { name: 'event_subscriber' }

```

/mymodule/src/MyModuleSubscriber.php

```
<?php

/**
 * @file
 * Contains \Drupal\mymodule\MyModuleSubscriber.
 */
namespace Drupal\mymodule;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Core\TempStore\PrivateTempStore;

/**
 * Provides a MyModuleSubscriber.
 */
class MyModuleSubscriber implements EventSubscriberInterface {

   /**
   * The PrivateTempStore Service
   *
   * @var PrivateTempStore
   */
   protected $privateTempStore;

   /**
   * MyModuleSubscriber constructor.
   *
   * @param PrivateTempStore $privateTempStore
   */
   public function __construct(PrivateTempStore $privateTempStore)
   {
     $this->privateTempStore = $privateTempStore;
   }

   /**
   * // only if KernelEvents::REQUEST !!!
   * @see Symfony\Component\HttpKernel\KernelEvents for details
   *
   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   *   The Event to process.
   */
  public function MyModuleLoad(GetResponseEvent $event) {
    // @todo remove this debug code
    drupal_set_message('MyModule: subscribed');
    // Interact with the tempstore
    $value = $this->privateTempStore->doSomething();
  }

/**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('MyModuleLoad', 20); // Like hook_init (Cached)
    // Priority greater than 200 alow to skip caching, like functionality of hook_boot.
    //$events[KernelEvents::REQUEST][] = array('MyModuleLoad', 300); // Like hook_boot (not Cached)
    return $events;
  }
}

```

---
Tags: 8, hooks
---