# Question
Title: Batch processing possible without redirects?
I'm using the Views Data Export module for exporting Views as .csv. Standard exports work in most cases, but with larger table only batch exports work. The problem with batch exports is that the redirects don't work well with systems using load balancing between servers and external caching services. I'd like to have something like the standard exporting, but processed the same way as batch processing so that PHP memory and execution time limits aren't reached. I've been reviewing the documentation as well as the Views Data Export module, but I haven't found a way to do this yet.

# Answer
> 2 votes
Redirects work just fine if your infrastructure is set up correctly. I will assume your issue is that you have a mount point for your public files directory - but not for your temp directory?

If you don't want to make two mount points (three, if you have a private folder), instead have one and just have three folders inside for tmp/ public/ private - then symlink tmp and public (e.g. tmp to /tmp/drupal).

The reason being is that file processes create temporary files which then can't be used by other instances if they're not shared. The external page cache isn't a factor here as it doesn't care so much about any of this, and I'm going to assume that this is for authenticated users too - so it's actually being bypassed (further assuming it's set up correctly). The load balancer cares even less, it just bounces you between instances unless you're using sticky sessions. Every instance should have access to the same database, files and cache - there won't be any problem.

---
Tags: 8, views, importing-exporting, batch-operations
---


# Question
Title: Migrating paragraph items to their host nodes from Drupal 7 to Drupal 9?
I am trying to do a Drupal 7 -\> Drupal 9 migration using the UI. It was able to convert field collection types to paragraph types. I was also able to create a few custom migrations using the d7\_paragraphs\_item plugin provided by Paragraphs to migrate all paragraph items from D7 into the database.

Now I need to attach them to the nodes.

My migration yaml:

```
id: field_content
migration_tags: {}
migration_dependencies: {}
migration_group: yale
label: Field Content Paragraphs
source:
  plugin: node_items
  key: migrate
destination:
  plugin: 'entity:node'
process:
  nid:
    - plugin: migration_lookup
      migration: d7_node_complete:page
      source: entity_id
      no_stub: true
    - plugin: extract
      index:
        - 0
  title: title
  items:
    plugin: migration_lookup
    migration:
      - accordion_items_paragraph
      - editor_items
      - highlight_files
    source: field_content_value
  field_content:
    plugin: sub_process
    source:
      - '@items'
    process:
      target_id: '0'
      target_revision_id: '1'

```

Except this is only doing maybe 20% of the total. It would appear that its not pulling back all possible paragraph items to stick into the field, or maybe I am just thinking of it wrong.

The source plugin is returning a set of data from Drupal 7 for a field that held Paragraph references:

```
class NodeItems extends SqlBase {

  /**
   * {@inheritdoc}
   */
  public function query() {
    $query = $this->select('field_data_field_content', 'fc');
    $query->join('node', 'n', 'n.nid = fc.entity_id');
    $query->join('paragraphs_item', 'pi', 'pi.item_id = fc.field_content_value');
    $query->fields('fc', [
        'entity_id',
        'bundle',
        'delta',
        'field_content_value'
      ]);
    $query->fields('n', [
      'title',
    ]);
    $query->condition('n.status', 1);
    $query->condition('fc.bundle', 'accordions', '!=');
    $query->orderBy('fc.entity_id');
    $query->orderBy('fc.delta');
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function fields() {
    return [
      'title' => $this->t('title'),
      'entity_id' => $this->t('entity_id'),
      'bundle' => $this->t('bundle'),
      'delta' => $this->t('delta'),
      'field_content_value' => $this->t('field_content_value'),
    ];
  }

```

"field\_content" in D9 is a Paragraphs field. It does seem to plug some values, I do see items on various nodes. But its failing because I think the lookup doesn't always return a value or maybe it doesn't know what to do with them? Also the nid: mapping needs to support multiple node types, I passed one migration. There are 12. Can I add all of them there or ?

Is this the way to attach them to host nodes? Is there a better way?

# Answer
I was thinking about this in the wrong way. The source plugin returns a list of results to migrate one at a time - the SQL query I was using would cause you to get for example, 5 rows for one node, each with a paragraph id. That is why only one paragraph was showing up on nodes at the end of a migration.

That isn't what you want - what you want instead is one row with the node id and 5 paragraph IDs.

I was able to do that by adjusting my source plugin query to the following:

```
  /**
   * {@inheritdoc}
   */
  public function query() {
    $query = $this->select('node', 'n');
    $query->join('D7_FIELD_NAME', 'fc', 'fc.entity_id = n.nid');
    $query->fields('n', [
      'nid',
      'title'
    ]);
    $query->condition('n.status', 1);
    $query->addExpression('GROUP_CONCAT(fc.D7_FIELD_NAME_VALUE)', 'paragraph_ids');
    $query->groupBy('n.nid');
    $query->groupBy('n.title');
    $query->orderBy('fc.delta');
    return $query;
  }

```

This produces a result set of

```
nid | paragraph_ids
-------------------
1     2, 4, 6, 8
2     13, 18, 12, 9
...........

```

Once you have that part, then you can fill in your Migration definition:

```
  D9_DESTINATION_FIELD_NAME:
    - plugin: explode
      delimiter: ','
      source: paragraph_ids
    - plugin: to_array
    - plugin: sub_process
      process:
        target_id:
          - plugin: migration_lookup
            migration:
              - accordion_items_paragraph
              - editor_items
              - highlight_files
            source: value
          - plugin: extract
            index:
              - 0
        target_revision_id:
          - plugin: migration_lookup
            migration:
              - accordion_items_paragraph
              - editor_items
              - highlight_files
            source: value
          - plugin: extract
            index:
              - 1

```

`explode` changes the comma delimited list into an array, and `to_array` is a small plugin I made to make it an array of arrays, each with an index of "value" and the id.

`sub_process` iterates over that and does a lookup against my other 3 paragraph migrations to drop the new destination id into target\_id and target\_revision\_id.

The `nid` mapping from the original question still works, and passing multiple node migrations provides the full lookup capability. So for any nodes the result set returns, they are updated accordingly.

Now all migrated Paragraphs show up on their respective nodes in the correct order. I was able to apply this pattern to 3 different entity\_reference\_revision fields in Drupal 9 that held Paragraphs.
> 1 votes

---
Tags: migrations, 9
---


# Question
Title: Render sub arrays with http client manger API calls response
I am trying to consume PokeAPI using Drupal. For making API calls I am using HTTP Client Manager module. I am able to set up initial configuration and get the data when the response field is a string. But I am not able to get data when the response field is array.Can any one please point out what I am doing wrong.

I am just trying to make a HttpGet request to the following URL

https://pokeapi.co/api/v2/pokemon?offset=300&limit=100

As the API has documentation of their resource Documentation I felt it would be good until I hit the wall of dealing with Array field. If anyone got suggestion for better approach I would like to try it out.

My code is as follows :

**pokeapi/pokeapi.http\_services\_api.yml**

```
pokeapi.base:
  title: "Drupal and PokeAPI Services API"
  api_path: "src/api/pokeapi_services.yml"
  config:
    base_uri: "https://pokeapi.co/"
    debug: "/tmp/pokeapi.log"

```

**pokeapi/src/api/pokeapi\_services.yml**

```
name: "Drupal and PokeAPI Services API"
apiVersion: "2.0"
description: "Drupal Client wrapper for the PokeAPI Services API."
imports:
  - "resources/posts.yml"
  # - "resources/models.yml"

```

**pokeapi/src/api/resources/posts.yml**

```
operations:
  GetPokemonsList:
    httpMethod: "GET"
    uri: "/api/v2/pokemon?limit={limit}&offset={offset}"
    summary: "Gets the available Pokemons List. It's possible to define a limit and offset."
    parameters:
      limit:
        location: "query"
        description: "The number of Pokemons data to be retrieved."
        type: "integer"
        required: true
        default: 100
      offset:
        location: "query"
        description: "The offset."
        type: "integer"
        required: true
        default: 200
    responseModel: "PokemonsList"

models:
  PokemonsList:
    type: "array"
    location: "json"
    items:
      "$ref": "NamedAPIResourceList"

  NamedAPIResourceList:
    type: "object"
    location: "json"
    properties:
      count:
        location: "json"
        type: "integer"
      next:
        location: "json"
        type: "string"
      previous:
        location: "json"
        type: "string"
      results:
        location: "json"
        type: "array"
        items:
          "$ref": "DetailedResourceList"

  DetailedResourceList:
    type: "array"
    location: "json"
    properties:
      name:
        location: "json"
        type: "string"
      url:
        location: "json"
        type: "string"

```

**pokeapi/src/Controller/PokeAPIController.php**

```
<?php

namespace Drupal\pokeapi\Controller;

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

/**
 * Returns responses for PokeAPI routes.
 */
class PokeAPIController extends ControllerBase {

  /**
   * PokeAPI Http Client.
   *
   * @var \Drupal\http_client_manager\HttpClientInterface
   */
  protected $httpClient;

  /**
   * {@inheritdoc}
   */
  public function __construct(HttpClientInterface $http_client) {
    $this->httpClient = $http_client;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('pokeapi.http_client')
    );
  }

  /**
   * Get Client.
   *
   * @return \Drupal\http_client_manager\HttpClientInterface
   *   The Http Client instance.
   */
  public function getClient() {
    return $this->httpClient;
  }

  /**
   * Builds the response.
   */
  public function build() {

    $client = $this->getClient();
    $command = 'GetPokemonsList';

    $response = $client->call($command)->toArray();
    dpm($response);

    $build['content'] = [
      '#type' => 'item',
      '#markup' => $this->t('It works!'),
    ];

    return $build;
  }

}

```

result of dpm($response);

```
Array
(
    [0] => 1118
    [1] => https://pokeapi.co/api/v2/pokemon?offset=300&limit=100
    [2] => https://pokeapi.co/api/v2/pokemon?offset=100&limit=100
    [3] => Array
        (
        )

)

```

here array value indexed 3 in response should contain result array of the data.

I believe there is some error in the following definition in the `posts.yml` If anyone can point out the correct way it will be helpful.

> ```
>       results:
>         location: "json"
>         type: "array"
>         items:
>           "$ref": "DetailedResourceList"
>
>   DetailedResourceList:
>
> ```

Similar Question : How can I access nested data?

# Answer
> 1 votes
There is a small mistake in models structure, use below one will solve your issue

```
models:
  PokemonsList:
    type: "object"
    location: "json"
    properties:
      count:
        location: "json"
        type: "integer"
      next:
        location: "json"
        type: "string"
      previous:
        location: "json"
        type: "string"
      results:
        type: "array"
        location: "json"
        items:
          "$ref": "DetailedResourceList"

  DetailedResourceList:
    type: "object"
    location: "json"
    properties:
      name:
        location: "json"
        type: "string"
      url:
        location: "json"
        type: "string"

```

---
Tags: 8, http-request
---


# Question
Title: Pass values to twig file from #theme options
I need to create a select field in a config form and pass values to it along with custom #theme options. Its easy to pass header & row values. But after selecting a value from select box, I need to load another dropdown, Below is my reference code:

addslider.php

```
 public function buildForm(array $form, FormStateInterface $form_state) {
 $vid = 'my_categories';
 $terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);

 foreach ($terms as $term) {
   $custom_categories[$term->tid] = str_repeat('-', $term->depth) . $term->name;
 }
  $form['block']['sliders'] = array(
  '#type' => 'fieldset',
  '#title' => $this->t('My Sliders'),
  '#collapsible' => TRUE,
  '#collapsed' => TRUE,
  '#theme'  => 'my_custom_slider_table',
);

foreach ($block['sliders'] as $key => $slider) {

$form['block']['sliders'][$key]['tid'] = array(
  '#type'          => 'select',
  '#title'         => t('Categories'),
  '#options'       => $custom_categories,
  '#required'      => TRUE,
  '#default_value' => !empty($slider['tid']) ? $slider['tid'] : NULL,
);
}

```

hook\_theme() in module file:

```
function mycustom_theme() {
  return [
    'my_custom_slider_table' => [
    //'variables' => [
    //'header' => $header,
    //'rows' => $example_rows,
    //'attributes' => array('id' => $table_id),
    //],
    'variables' => [
    'slider ' => [],
    ],
  ],
];

}

```

my-custom-slider-table.html.twig file:

```
<table>
  <thead>
    <tr>
      <th>{{ 'Taxonomy select' }}</th>
      <th>{{ 'Reference Node' }}</th>
      <th>{{ 'Options' }}</th>
    </tr>
  </thead>
  <tbody>
   <tr> <td>{{ slider }}</td><td>Test Sponsors</td><td>Edit/Delete</td></tr>
 </tbody>
</table>

```

I need to get the output of $custom\_categories variable in twig file, for the first td in {{ slider }} . Can you please help, new to Drupal8.

# Answer
You need to add it to your `$build` render object. Here's a piece of sample code, in this case from a Block plugin with a form on it, similar to yours:

```
...
in my BlockPlugin
..

public function build() {
    // getConfiguration returns the values from the form I have and save to a config object.
    $source = $this->getConfiguration()['source'];
    $access_token = $this->getConfiguration()['access_token'];

    $build = [
      '#theme' => 'my_fancy_search_widget',
      '#source_data' => $source,
      '#access_token' => $access_token,
    ];
    return $build;
  }

...
in my .module file:
...

/**
 * Implements hook_theme().
 */
function my_module_theme($existing, $type, $theme, $path) {
  return [
  'my_fancy_search_widget' => [
      'template' => 'main-search',
      'variables' => [
        'source_data' => NULL,
        'access_token' => NULL,
      ],
  ];
}

```

in my twig template I can print these vars with `{{ source_data }}` and `{{ access_token }}`
> 1 votes

---
Tags: 8, theming
---


title: How to make a theme depend on a module?

text:
# Question
Title: How to make a theme depend on a module?
My theme requires multiple modules to be install before it is fully functional. How can one set module dependency in a theme, so that when a user enables the theme, it will also enable the required modules? So far, I tried to specify the dependencies in the .info file of the theme, however, no success:

```
dependencies[] = some_module

```

Any help is much appreciated.

# Answer
> 7 votes
As far as I know, this functionality doesn't exist yet (up to Drupal 7).

A feature request is already created at https://drupal.org/node/474684 (for Drupal 8).

# Answer
> 2 votes
This was introduced in Drupal **8.9.0**.

Quoting the change record https://www.drupal.org/node/2937955

> To declare a dependency in your theme you need to add it to the .info.yml file:
>
> ```
> name: test theme depending on nonexisting module
> type: theme
> core_version_requirement: ^8 || ^9
> dependencies:
>   - drupal:test_module_non_existing
>
> ```

---
Tags: .info
---


# Question
Title: Display node content with frontend theme in admin route
I need to display content with the frontend theme in an admin page to get a preview. I get the content and built it with the `->getViewBuilder('node')` but the template used is coming from the admin theme and the created template in the frontend theme `node--newsletter.html.twig` is not taken into account.

Is there a way to see the node view mode with the frontend theme instead of the admin theme ?

Thank you.

# Answer
If this is a custom route (defined in a routing.yml file with a custom controller) you are able to do this by defining the route in the routing yaml with

```
options:
    _admin_route: FALSE

```

Which will cause the route to be treated as a "frontend" route. However it sounds like this is likely not the case here.

If you simply want to have previewing of standard content, the core preview function (the button next to "Save") is the standard mechanism to do this.
> 0 votes

---
Tags: 8, entities
---


title: Sub Menu items not showing

text:
# Question
Title: Sub Menu items not showing
I am trying to create a navigation with a sub-menu in Drupal 9. I added the top level nav item with and used # as the value for the link, and checked "Show as expanded"

Then I created a new item and chose the Top Level Item as the parent nav.

Top Level Item Sub Item

On my menu now the Top Level Item has an arrow, but the sub item is not there. And in dev tools under inspector I do not see the code for the sub item.

Is there a step I missed?

# Answer
Found a solution here - https://www.drupal.org/forum/support/module-development-and-code-questions/2019-08-03/menu-item-children-not-rendered-in

I needed to change "Number of levels to display" under the Navigation block to Unlimited
> 1 votes

---
Tags: navigation
---


# Question
Title: How can I programmatically create a block type?
I want to create a block type that has a couple of fields, a template and attached JavaScript.

I want that the user in my site will be able to create blocks of this type just like they create a custom block: through /block/add/myBlockType.

I would like ideally to have it all done programmatically but I dont mind manually creating my block type though "admin/structure/block/block-content/types" or with configuration files.

The thing is I have been scraping google for two days already and I don't manage to figure out how to programmatically create a block type

And this that the information is not easily found on Google makes me think that instead I need to create my type with configuration and then apply my plugin on creation of a new block but im still not sure how to do that and what my plugin needs to extend.

How can I do that?

# Answer
I had the same issue and I hope I have resolved it.

Your algorithm is next:

1. Create your own module
2. Create file \<your\_module\>.install
3. There must be at least one hook `hook_install` (I have used two: `hook_install` and `hook_uninstall`)
4. Inside install hook:
    * create a new block type
    * create fieldStorageConfig
    * create fieldConfig
    * set component for form and view display

My code:

```
<?php

use Drupal\block_content\Entity\BlockContentType;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;

function <your_module_name>_install() {
  $newBlockType = BlockContentType::create([
    'id' => <your_id>,
    'label' => 'Custom block type',
    'description' => "A custom block type",
  ]);
  $newBlockType->save();

  $blockId = $newBlockType->id();

  block_content_add_field($blockId, 'Icon', 'custom_block_icon', 'image', 'image', 'image_image');
  block_content_add_field($blockId, 'Count', 'custom_block_count', 'integer', 'number_integer', 'number');
  block_content_add_field($blockId, 'Description', 'custom_block_description', 'text', 'text_default', 'text_textfield');

}
function block_content_add_field(
  $blockTypeId,
  $label,
  $componentName,
  $fieldStorageType,
  $viewDisplayType = 'text_default',
  $formDisplayType = 'text_textarea_with_summary') {
    // Add or remove the body field, as needed.
    $field = FieldConfig::loadByName('block_content', $blockTypeId, $componentName);
    if (empty($field)) {
      $fieldStorage = FieldStorageConfig::loadByName('block_content', $componentName);
      if (empty($fieldStorage)) {
        $fieldStorage = FieldStorageConfig::create([
          'field_name' => $componentName,
          'entity_type' => 'block_content',
          'type' => $fieldStorageType,
        ]);
        $fieldStorage->save();
      }

      $field = FieldConfig::create([
        'field_storage' => $fieldStorage,
        'bundle' => $blockTypeId,
        'label' => $label,
        'settings' => ['display_summary' => FALSE],
      ]);

      $field->save();

      /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
      $display_repository = \Drupal::service('entity_display.repository');

      // Assign widget settings for the default form mode.
      $display_repository->getFormDisplay('block_content', $blockTypeId)
        ->setComponent($componentName, [
          'type' => $formDisplayType,
        ])
        ->save();

      // Assign display settings for default view mode.
      $display_repository->getViewDisplay('block_content', $blockTypeId)
        ->setComponent($componentName, [
          'label' => 'hidden',
          'type' => $viewDisplayType,
        ])
        ->save();
    }

    return $field;
}

```

Result: the new custom block type with 3 fields.
> 4 votes

# Answer
You can create content block type using configuration files:
In you module should have `config/install/block_content.type.YOUR_BLOCK_TYPE_MACHINE_NAME.yml` see the following example from core for ***Basic block*** `core/profiles/standard/config/install/block_content.type.basic.yml` .

Here is an example to create new type called ***My Block Type***

1. Go to *admin/structure/block/block-content/types* Create by clicking on **Add custom block type**
2. Create fields you want by **Manage Fields**
3. To export your configuration Go to *admin/config/development/configuration/single/export*  And Create a config file in your Module and put in it the result: *YOURMODULENAME/config/install/block\_content.type.my\_block\_type.yml*
4. And also you should export fields associated to your block type: the same way you did with block type config: Go to *admin/config/development/configuration/single/export* choose **Field** as configuration type and choose all **Configuration name** with name **block\_content.my\_block\_type.FIELD\_NAME** like the body field below  and then the **Field Storage** configuration.

Or you can export configuration using Drupal console like the following:

```
drupal config:export:entity block_content my_block_type --module="YOURMODULENAME" --optional-config --remove-uuid --remove-config-hash --include-module-dependencies

```
> 1 votes

# Answer
An easier way to do this would be to:

1. Add `block_content` module as a dependency to your custom module
2. Create the configuration you want and export it, pay attention to the config files created for step 3 below.
3. Add the exported config to your module under `your_module/config/install`. You can use config\_devel for that to make your life easier.
4. Enable your module.

This goes more towards the Drupal 7 Features, but it is quite easier to handle and to maintain.

The .info.yml file will have these lines in the end if you use config\_devel:

```
dependecies:
  - block_content

config_devel:
  - block_content.type.html_block
  - language.content_settings.block_content.html_block
  - field.field.block_content.html_block.body
  - core.entity_view_display.block_content.html_block.default
  - core.entity_form_display.block_content.html_block.default

```

I had to add 5 files in my case (one field, with translations enabled).
> 0 votes

---
Tags: 8, entities, blocks
---


# Question
Title: How do I alter a form submission handler?
I want to alter the form submission handler submit for the search block with a custom module.
Setting `$form['#attributes']['class']` works, but the submission handler doesn't seem to be triggered with any of the methods that I have alternatively found in many core and third-party modules.

```
/**
 * @file
 * Redirect search from search block to XXX.
 */

use Drupal\Core\Form\FormStateInterface;

/**
* Implements hook_form_FORM_ID_alter().
*/
function search_redirect_form_search_block_form_alter(&$form, FormStateInterface $form_state) {
    $form['#attributes']['class'][] = 'test-class'; //Working
    $form['#submit'][] = 'search_redirect_search_block_form_submit';
    $form['actions']['submit']['#submit'][] = '_second_submit';
}

function search_redirect_search_block_form_submit(&$form, FormStateInterface $form_state) {
  \Drupal::logger('search_redirect')->notice("the function is triggered"); // Not happening
  \Drupal::service('messenger')->addStatus("the function is triggered"); // Not happening
}

function _second_submit(&$form, FormStateInterface $form_state) {
  \Drupal::logger('search_redirect')->notice("second_submit"); // Not happening
  \Drupal::service('messenger')->addStatus("second_submit"); // Not happening
}

```

# Answer
> 2 votes
Stupid question but have you cleared cache to register the new hook?

Also, try inspecting the form in `hook_form_alter` to make sure you are attaching the handler to the correct action.

Lastly, I've found that I usually need to reorder the array to include my handler first in order for my actions to actually trigger on form submissions using Drupal core forms that have existing handlers.

As an example, I did like:

```
$form['actions']['submit']['#submit'] = array_reverse($form['actions']['submit']['#submit']);

```

which will reverse the array. I also sometimes use `array_unshift` to pop my handler at the start of the array if the other handlers need to retain their order.

---
Tags: 8, forms, search
---


# Question
Title: Create basic field data in template like node for custom entities {{ custom_entity.id }}
I see node preprocess does this

`$variables['node'] = $variables['elements']['#node'];`

and then in the template one can do this

`{{ node.id }}`

but when I create a custom entity and do the same, I never get past all the the errors like

```
Exception: Object of type Drupal\Core\Field\FieldItemList cannot be printed. in Drupal\Core\Template\TwigExtension->escapeFilter() (line 476 of core/lib/Drupal/Core/Template/TwigExtension.php).

```

What are they doing special for node?

# Answer
**Why does `{{ custom_entity.id }}` produce this error message?**

> Exception: Object of type Drupal\Core\Field\FieldItemList cannot be printed.

If your entity defines `id` for the entity ID then `{{ custom_entity.id }}` is ambiguous. It can mean the object property (the ID field) or the method EntityInterface::id().

So use parentheses to make it clear it is a method:

```
{{ custom_entity.id() }}

```

Or retrieve the field value when you have already a field as the error message shows:

```
{{ custom_entity.id.value }}

```

---

**What are they doing special for node?**

The node entity is using `nid` as ID field, so `id` and `nid` are unambigious.

Method `id()`:

```
{{ node.id }}

```

Field `nid`:

```
{{ node.nid.value }}

```
> 1 votes

---
Tags: nodes, 9
---


# Question
Title: Require v8 only contrib module with v9 patch
* Given I have Drupal 9 composer installation with `composer-patches` plugin
* and given a contrib module with a stable v8 release, but no v9 release (not even dev branch)
* and given that contrib module has a working v9 patch in the issue queue

is there any method to install that module + patch in composer? Even if I manually add both, the package and patch, to my `composer.json`, I still can't `require` or `update` this module with composer due conflicting versions. I really want to avoid duplicating `/contrib` code into my project's `/custom` codebase. My current workaround is:

* forking that module to my own, private git repo
* applying patch there
* creating a new `composer.json` in my private git, and changing the package vendor to my `custom_private_vendor`
* adding my private git as VCS repo in the D9 project's `composer.json`
* and then `composer require custom_private_vendor/contrib_module`

This fulfills my goal of not duplicating the contrib module in my project's custom codebase, but every time I do this I feel the urge to wash my dirty hands.

Is there something more elegant like `composer require drupal/contrib_module --apply-patch-first` or can I somehow target drupal.org's git with a specific patch included?

# Answer
> 18 votes
## Drupal 10

As reported by @rocketeerbkw, the official lenient endpoint in packagist currently doesn't support Drupal 10.

https://github.com/mglaman/composer-drupal-lenient does.

Instructions for use are in the repo.

---

## Drupal 9

The official advice is now to use a specially made lenient endpoint as described in Using Drupal's Lenient Composer Endpoint.

---

## Issue forks

Official advice found at: Use issue forks to make compatibility fixes work with Composer

Copied here for convenience:

It's impossible to install an incompatible module with composer and apply a compatibility patch afterwards. However, since issue forks are branches it's possible to install the module using that branch. In order to do this we need to do 3 things.

Under the repositories section where the composer source is listed we need to add an exclude key for our module that we're trying to install using the issue fork. In my example I'm trying to install a issue for the Homebox module.

```
{
    "type": "composer",
    "url": "https://packages.drupal.org/8",
    "exclude": [
        "drupal/homebox"
    ]
}

```

Next up we need to add the specific git URL to our repositories section. You can find this URL under the "show commands" section of the issue fork.

```
{
    "type": "git",
    "url": "git@git.drupal.org:issue/homebox-3146462.git"
}

```

Our complete repositories key looks something like this now:

```
"repositories": [
    {
        "type": "composer",
        "url": "https://packages.drupal.org/8",
        "exclude": [
            "drupal/homebox"
        ]
    },
    {
        "type": "git",
        "url": "git@git.drupal.org:issue/homebox-3146462.git"
    }
],

```

Now we can use the composer install command to require the module. Important here is that you need to specify the branch name prefixed with "dev-". So for the homebox example the command would look like this:

```
composer require 'drupal/homebox:dev-3146462-drupal-9-compatibility'

```

It's possible that for the first time when you execute this you're prompted to allow the ECDSA key fingerprint for git.drupal.org. Just type yes and composer will continue.

---

## Commit reference

You've got the right idea but you don't need to fork Drupal's repository. You can set up composer to read Drupal's git repo instead of using packagist for the naughty modules like this:

```
{
    "type": "package",
    "package": {
        "name": "drupal/cache_control_override",
        "type": "drupal-module",
        "version": "1.0.0",
        "source": {
            "type": "git",
            "url": "https://git.drupalcode.org/project/cache_control_override.git",
            "reference": "8db91684a427366d8f9c51f60cbac10c2d586d95"
        }
    },
    {
      "type": "composer",
      "url": "https://packages.drupal.org/8"
    }
},

```

Note the `reference` is a commit hash, though it looks like you can also use tags. Also note that the custom git `type: package` repo must be **before** Drupal's default `type: composer` repo in your composer file.

And then patch as normal using composer:

```
"drupal/cache_control_override": {
    "Drupal 9 Compatibility (3132036)": "https://www.drupal.org/files/issues/2020-04-29/Drupal-9-readiness-3132036-2.patch"
},

```

Thanks @miststudent2011 for pointing out that this doesn't automatically install dependencies which I can confirm. You will need to require those yourself!

(Shamelessly stolen from @acbramley on Drupal Slack because wider dissemination of this knowledge is worthwhile)

# Answer
> 7 votes
For a wider explanation of why Darvanen's answer is necessary, see https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer (disclaimer: I wrote this). But do note that using a different vendor namespace (like drupal\_git) shouldn't be necessary if the section is added to your composer.json file's 'repositories' *above* the one for packages.drupal.org .

Ultimately, composer processes the dependency & compatibility metadata for packages, and so decides to reject the package - **before composer gives the cweagans/composer-patches plugin chance to patch it**. This method overrides the metadata so the package isn't rejected before patching.

# Answer
> 3 votes
In case anyone comes across this question in the future, the official solution is to use the lenient endpoint as described in Using Drupal's Lenient Composer Endpoint.

---

Alternatively you can reach the same with Composer aliases. So you ask Composer to install Drupal 9 as if it were installing Drupal 8. This solution is probably not compatible with installing a Drupal 9-only module, but it worked for me when I about 10 modules away from having a Drupal 9 compliant system. The trick is very simple, and the only drawback is that you'll need to keep updating the now fixed version of core.

Replace all:

```
"drupal/core-composer-scaffold": "^9.1.5",
"drupal/core-recommended": "^9.1.5",

```

With:

```
"drupal/core-composer-scaffold": "9.1.5 as 8.9.99",
"drupal/core-recommended": "9.1.5 as 8.9.99",

```

And the same for `drupal/core-dev`, if that is used in the require-dev section. This way, a Drupal 8-only module won't block your installation of Drupal 9. You'll still need to apply the D9-readiness patch, as Drupal core will complain if the `core_version_requirement` is not set correctly.

---
Tags: composer, 9
---


# Question
Title: Correct views hook to alter contextual filter
I am trying to find the correct views hook to alter/add a contextual filter to a views block that's being rendered in a template. (Using drupal\_view and the twig tweaks module).

The view is setup to accept a contextual filter that is provided in the URL by default. It works great on that page, however it's been requested that the view also display on a sub-page of this main page, in where the URL does not contain the contextual filter. Therefore, I am trying to find a views hook that I can reliably attach the contextual filter to and have it work every page load.

I have tried using `hook_views_pre_view()`, however this appears to only work once between cache clears, as if I clear cache it works, then as soon as I refresh the page it stops working again until another cache clear.

Is there a way I can do this from a hook? The way the child-page is structured, I can't easily get it from the template to pass it into drupal\_view() as an argument.

The current code I am using is:

```
function item_types_views_pre_view(&$view, &$display_id, &$args) {
    if ($view->id() == 'existing_copies') {

        $parameters = \Drupal::routeMatch()->getParameters();
        $imcid = \Drupal::routeMatch()->getParameter('imcid');

        $entity = \Drupal::entityTypeManager()->getStorage('item_type')->load($imcid);

        if ($entity->bundle() == 'book_copy') {
            $main_record = $entity->field_book_main_record->getString();
        }
        elseif ($entity->bundle() == 'book_master_copy') {
            $main_record = $entity->field_master_copy_book_mr->getString();
        }

        $args = [$main_record];
    }
}

```

Which like I said, works great immediately after a cache clear, but no longer works after the page is refreshed.

# Answer
I was able to use achieved what I wanted by using `hook_views_pre_build()` as below

```
hook_views_pre_build(ViewExecutable $view) {
  $args[0] = '1234';

  $view->addArguments($args);
}

```
> 1 votes

---
Tags: 8, views
---


# Question
Title: What am I doing wrong in my theme that's breaking CAPTCHA?
I have a bug in my CAPTCHA implementation. When I click the "Get new captcha!" link, it does not refresh the image CAPTCHA.

After a ton of research in issue queues, testing and breaking my local, and finding everything that was NOT causing it I finally turned off my custom theme and lo, the "Get new captcha!" link works again.

My custom theme is built on USWDS Base theme.

* not using a CDN

I'm using:

* Drupal 9.0.11
* CAPTCHA and Image CAPTCHA 8.x-1.1
* **USWDS Base Theme** 8.x-2-4

No errors are produced in the log or in the console. I "feel" like it might be something related Ajax, but I can't figure out how to sniff it out or narrow it down.

Can anyone give me suggestions for settings I can test and change or specific places in code I might check to try to fix this? Thank you.

**Update**: I just tried using straight USWDS Base theme, no custom theme, and CAPTCHA bug is still there. *So not my custom theme, but my contrib base theme.*

# Answer
I found the conflicting template inside USWDS base theme. For anyone else having this problem, you must alter this template:

```
/themes/contrib/uswds_base/templates/form/details.html.twig

```

You can either wholesale replace with the same template from Bartik's classy template (or similar), or else custom rewrite it using the working template from Bartik and customizing it to what you need. I needed to rip out the `ul`/`li` based markup that USWDS imposed, but still keep the classes and accessibility markup.

In case it helps anyone else, here's what I ended up using:

```
<div{{ attributes.addClass('usa-accordion usa-accordion--bordered') }}>
  {%- if title -%}
    {%
      set summary_classes = [
        required ? 'js-form-required',
        required ? 'form-required',
      'usa-accordion__button',
      ]
    %}

    <button type="button" aria-expanded="true" aria-controls="{{ attributes.id }}-content"{{ summary_attributes.addClass(summary_classes) }}>{{ title }}</button>
  {%- endif -%}
  <div id="{{ attributes.id }}-content" class="usa-accordion__content usa-prose"
>
    {% if errors %}
      <div class="form-item--error-message">
        <strong>{{ errors }}</strong>
      </div>
    {% endif %}
    {%- if description -%}
      <div class="details-description">{{ description }}</div>
    {%- endif -%}
    {%- if children -%}
      {{ children }}
    {%- endif -%}
    {%- if value -%}
      {{ value }}
    {%- endif -%}
  </div>
</div>

```
> 0 votes

---
Tags: theming, captcha
---


# Question
Title: How do I interact with Mautic from a custom module?
I need to create a new contact in Mautic every time a new user joins my Drupal site.

Drupal.org has the following two modules:

I can't find documentation from any of these two modules on how to access the Mutic API from a custom Drupal module.

I believe, this could be done from inside a hook like this.

```
/**
 * Implements hook_ENTITY_TYPE_insert() for user entities.
 */
function custom_mautic_user_insert(Drupal\Core\Entity\EntityInterface $entity){

  // Some code here to access the Mautic API to create the new contact.

}

```

I have seen the code of https://www.drupal.org/project/commerce\_mautic, which uses an event subscriber to do its work, but this seems very complex for such a simple task.

# Answer
I think you're on the right track. Module https://www.drupal.org/project/mautic\_api provides a wrapper around Mautic API - see https://git.drupalcode.org/project/mautic\_api/-/blob/8.x-1.x/src/MauticApiService.php#L127

You can use it in you module code via `\Drupal::service('mautic_api')`. The hook you've mentioned looks correct to me.
> 0 votes

---
Tags: 8
---


# Question
Title: How to disable quickedit for specific block, but keep contextual links
I want to disable the quick edit feature for a specific block so that it does not show up in the contextual links anymore. However, I want to keep the other contextual links for this specific block (e.g. configure block). I do not want to entirely turn off quick edit, because I still need it on some elements.

Hope someone can help with this one?

# Answer
It looks like you can use module https://www.drupal.org/project/block\_content\_permissions for that. To cite the project page:

> Add the following permissions to allow access to edit blocks in-place (on-page):
>
> * Use contextual links (Contextual Links module)
> * Access in-place editing (optional, Quick Edit module)

However, it might not be feasible depending on the number of blocks on you site.
> 0 votes

---
Tags: 9
---


# Question
Title: How do I disable the "Continue to payment" button before the shipping method is selected?
How do I disable the *Continue to payment* button before the shipping method is selected? I use `#states` to disable the button, but it doesn't seem to work.

# Answer
I would've assumed form states would do the trick, but without seeing the code you've tried, it's hard to say what the issue might be. That said, we did *just* get the patch into Commerce Shipping that automatically calculates shipping upon full address entry and recalculates it on address change. I believe that may resolve the issue that led you to look into this in the first place. You can upgrade to Commerce Shipping 2.x-dev or apply this patch: https://www.drupal.org/project/commerce\_shipping/issues/2849756#comment-14030351
> 1 votes

---
Tags: commerce
---


title: Headers already sent

text:
# Question
Title: Headers already sent
I found this error repeated several times for two of the pages on my website.

```
    Warning: Cannot modify header information - headers already sent by (output started at
/home/customer/www/mydomain.com/public_html/includes/common.inc:2800) in user_cookie_save() (line 4041 of
/home/customer/www/mydomain.com/public_html/modules/user/user.module).

```

I checked a bit around and found other similar errors with "Headers already sent" but none of them on the user\_cookie\_save function.

How can I debug fix it?

I'm running on Drupal 7.78, PHP 7.3.2.7 and as modules that could influence the cookies, I'm running just the EU Cookie compliance module.

What I find strange, is that I do not recall having seen this error before. There is a small chance that the error was there ad I did not see it because the logs are filled with page not found, and access denied errors by nice persons from the internet :) I would say though that that is a small chance as I've checked many times the logs in the past and did not see this error.

I have no idea what changed, and also no idea of what is the impact of this error, it's a warning, but I can't reproduce it.

Many thanks

# Answer
HTML requests return headers, that tell what the response will be, and the body, that is the response. The headers are required by browsers to understand how to interpret the data that is in the body, therefore no output must be sent before the headers. This error is outputted when headers are sent after some body output has been sent. When working on a Drupal system, there are three common causes to this error that you can debug:

1. An echo statement in a module/theme (and not in a template). Sometimes developers will echo out a value for debugging purposes, and forget to remove that line.
2. Blank space before the opening `<?php` tag in a document on the system. This is usually in a custom module or theme, or can be in settings.php, or settings.local.php.
3. A closing \`?\>' tag, with whitespace after it. Drupal coding standards are to not use the closing php tag, so if you find this anywhere outside of a template, you can probably remove the closing tag. At the very least, you should ensure there is NO whitespace after the tag.
> 1 votes

---
Tags: 7, users
---


# Question
Title: How to properly check the menu for emptiness in twig?
I use Simplify Menu to display the necessary menu markup. How do I make sure that the menu is not empty (there are items there) and if there are menu items, they are enabled?

```
{% set items = simplify_menu('main') %}
  <ul>
    {% for menu_item in items.menu_tree %}
    <li class="{{ item_class }} navigation__item">
      <a href="{{ menu_item.url }}" class="{{ link_class }}">{{ menu_item.text }}</a>
    </li>
  </ul>
{% endfor %}

```

In my work, I use the Twig tweak module, but I can't do a check with it either:

```
{% if drupal_menu('main') is empty %}
{% endif %}

```

# Answer
> 1 votes
This is tricky as you would expect `{% if drupal_menu('main') is empty %}` to work for checking if the menu exists or not. In reality, you'll want to use the `render` filter for twig. So that would become:

```
{% if drupal_menu('main') | render %}

```

I tested this code in my theme's `page.html.twig` file and it works. e.g.

```
{% if drupal_menu('main') | render %}
  {{ 'Main menu is not empty'|t }}
{% else %}
  {{ 'Main menu is empty'|t }}
{% endif %}

```

There is a very long winded issue here with regard to this: \[meta\] Themes improperly check renderable arrays when determining visibility

There are also some related issues for this.

---
Tags: 8, theming, navigation
---


# Question
Title: Possibility to reinstal module without deleting old configuration for module permissions by term
I tried to upgrade my site from Drupal 8 to Drupal 9. In this process I upgrade the module Permissions by Term to Version 3.0. The upgrade failed due to problems with extension of CiviCRM that were not covered by update report. So I turned back to D8. Afterwards I got the messages that the module Permissions by Term 3.0 was not compatible to D8 and thus disabled. So I downgraded that module by Composer successfully to version 2.31. After trying to reinstall it I got the error message that it couldn't be installed because of existing configuration. In the web I found several ways to delete old configurations, but of course I would like to keep it since I'm afraid I would have to review every page to set permissions again. Thus my questions: Is there any way to reinstall the module without deleting my old configurations (or was my fear wrong)?

# Answer
Module configuration files are stored in the module's config/install directory. When you enable the module, Drupal tries to install those configurations. If Drupal complains that the configurations already exist, then you can take the following steps:

1. Identify which configuration files Drupal is complaining about.
2. Move those configuration files out the module's config/install directory. It doesn't really matter where you move them to, but you're going to want to restore the files after everything is fixed so I suggest just moving them up one level into the config directory.
3. Try to install the module. Drupal won't find the module's default configuration files that you moved so it shouldn't complain any more.
4. If Drupal still complains, that means you missed a configuration, so repeat the above steps.
5. Restore the original configuration files - move them back into config/install.

Note that this is a workaround - not a solution. The module should be examined to ensure it properly removes its own configuration (if appropriate) when uninstalled, and that it declares the proper dependencies in its configuration, and that configurations which are not removed are defined as optional. Please file a bug report in the issue queue for that module so that this can be fixed for other users.
> 0 votes

# Answer
For me I solved the problem by deleting the row permissions\_by\_term.settings in the table config (after I had realized that there were only a few settings I would be easily able to restore). Afterwards I could install the module. I did get an "unexpected error", but after refreshing the site, the module was marked as installed. But my site still missed the page for the module's settings. This changed after I had deinstalled the module and the reinstalled it again. In this process I lost the settings that had been stored in the tables permissions\_by\_term\_role and permissions\_by\_term\_user (that I could have saved, compare https://www.drupal.org/docs/contributed-modules/permissions-by-term), but since for me they were only few, it didn't matter. Thanks for your help.
> 0 votes

---
Tags: configuration
---


# Question
Title: Conditional form states in hook_form_alter()
I have a node with a field, whose widget uses select boxes and multiple choices are possible. The values are coming from a taxonomy entity reference field. There is another field, a text field, which needs to be hidden.

```
/**
 * Implements hook_form_alter().
 */
function mijn_condities_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if($form_id == 'node_bedrijf_form' || $form_id == 'node_bedrijf_edit_form'){
    $form['field_afstand']['#states'] = array(
      'visible' => array(
        ':input[name="field_openbaar_vervoer"]' => array('value' => '236'),
      )
      );

  }
}

```

A select box should be added according their choice. For example, when they choose bus or tram, there should be a field to enter the distance in meters. When they choose airport, the range must be in kilometers.

The field isn't hiding. I already tried to make the field invisible, but this doesn't work.

Does anyone know what is wrong?

# Answer
> 0 votes
This is a little bit tricky the **Form API #states** works with jQuery selectors if your filed ***field\_openbaar\_vervoer*** coming from a taxonomy entity reference.
So the input generated HTML will be something like (example from tags fields)

```
<input data-drupal-selector="edit-field-tags-3" aria-describedby="edit-field-tags--description" type="checkbox" id="edit-field-tags-3" name="field_tags[3]" value="3" class="form-checkbox">

```

So to target all those inputs you should use Starts With Selector in your code and it will work:

```
$form['field_afstand']['#states'] = [
  'visible' => [
    ':input[name^="field_openbaar_vervoer"]' => ['value' => '236'],
  ],
];

```

---
Tags: forms, 9
---


title: How to setup cookie domain?

text:
# Question
Title: How to setup cookie domain?
I am trying to set `$cookie_domain` in my settings.php within Drupal 8.

In Drupal 7, I add this in settings.php to set it up, but I am not sure how to do it in Drupal 8:

> $cookie\_domain = ".domain.com";

Thanks a lot

# Answer
This is a container parameter now.

Put this in services.yml or another service definition YAML file:

```
parameters:
  session.storage.options:
    cookie_domain: '.domain.com'

```

Since it is in a yaml file, it can't easily be dynamic, one option you have is having multiple yml files, and you dynamically add the one for the right environment, or you have a services.local.yml, just like settings.local.php that you have on each environment and not in git.
> 18 votes

# Answer
Another option for multiple environments rather than keeping multiple files is to use environment variables.

Create an environment variable the way you normally would, if you're using Docker that would usually be by loading an `.env` file with contents such as:

```
COOKIE_DOMAIN=.domain.com

```

Then use that environment variable in your services.yml file (or other YAML file) like this:

```
parameters:
  session.storage.options:
    cookie_domain: ${COOKIE_DOMAIN}

```
> 2 votes

---
Tags: 8, cookies
---


# Question
Title: How do I get group to which the node belongs and redirect anonymous users to the login page if they land on it?
I'm using the Drupal Group module and I've added content to a Drupal group I've created. I've also added users to this Group.

Works well: Drupal users have to login to see this content in that group.

Now I'm looking at User Experience (UX) improvements: If a non-logged in user visits a URL for a node that belongs to a group, then I'd like to redirect them to the login page and then redirect them back to that page.

I know how to do the 2 redirects ( How to redirect a user after login in Drupal the proper way \- I got this working for something else ). But I don't know how to get the group(s) that a node belongs to. Is there a standard call? on the Node object or via another object I can get hold of?

So far I found this: Find out to which group the entity belongs to by route. It's a code fragment for a class. I added in the constructor with params that correspond to the said services and member variables.

It runs, but doesn't work: calling `$group = \Drupal::service('mysite_custom_module.current_group')->getGroupFromRoute();` returns `$group` as `null`

My code I've written based on: Find out to which group the entity belongs to by route

**(Note - by me posting this code example here below *doesn't* mean I'm fixated on getting this particular approach to work. I would surely be very happy with *any* solution that answers my main question: "How to get the Drupal Group that the node belongs to / redirect anonymous to login page if they land on node belonging to group" )**

web/modules/custom/mysite\_custom\_module/mysite\_custom\_module.services.yml

```
services:
  mysite_custom_module.current_group:
    class: Drupal\mysite_custom_module\CurrentGroup
    arguments: ['@current_route_match', '@entity_type.manager']

```

web/modules/custom/mysite\_custom\_module/mysite\_custom\_module.module

```
/**
 * https://www.thesavvyfew.com/insights/how-redirect-user-after-login-drupal-proper-way
 *
 * Implements hook_form_FORM_ID_alter().
 */
function mysite_custom_module_module_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#submit'][] = 'mysite_custom_module_module_user_login_form_submit';
}
/**
 * Custom submit handler for the login form.
 */
function mysite_custom_module_module_user_login_form_submit($form, FormStateInterface $form_state) {
  $originalUrlAsString = \Drupal::request()->get('return');

  $urlAsObject = Url::fromUserInput($originalUrlAsString);
  $form_state->setRedirectUrl($urlAsObject);
}

    function mysite_custom_module_module_preprocess_page(&$variables) {
      $group = \Drupal::service('mysite_custom_module_module.current_group')->getGroupFromRoute();

      if ( $group ) {
        if (!( \Drupal::currentUser()->isAuthenticated() ) ) {
          $originalUrl = \Drupal::service('path.current')->getPath();
          $loginWithOriginalUrl = "/user/login?return=".$originalUrl;
          //$response = new RedirectResponse(Url::fromUserInput($loginWithOriginalUrl)->toString());
          $response = new RedirectResponse($loginWithOriginalUrl);
          $response->send();
        }
      }
    }

```

web/modules/custom/mysite\_custom\_modue/src/CurrentGroup.php:

```
<?php

namespace Drupal\mysite_module;

// https://www.drupal.org/docs/8/modules/group-media/find-out-to-which-group-the-entity-belongs-to-by-route

class CurrentGroup {

  private $routeMatch;
  private $entityTypeManager;

  // see mysite_module/mysite_module.services.yml
  public function __construct( $current_route_match, $entity_type_manager ) {
   $this->routeMatch = $current_route_match;
   $this->entityTypeManager = $entity_type_manager;
  }

/**
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *
   * @return bool|\Drupal\group\Entity\GroupInterface
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   */
  public function getGroupByEntity(EntityInterface $entity) {
    $group = FALSE;
    if ($entity instanceof GroupInterface) {
      return $entity;
    }
    $entity_type = $entity->getEntityTypeId();
    $group_content_type = 'membership_group_type-group_' . $entity_type . '-' . $entity->bundle();
    // Load all the group content for this entity.
    /** @var \Drupal\group\Entity\GroupContent $group_content */
    $group_content = $this->entityTypeManager->getStorage('group_content')
      ->loadByProperties([
        'type' => $group_content_type,
        'entity_id' => $entity->id(),
      ]);
    // Assuming that the content can be related only to 1 group.
    $group_content = reset($group_content);
    if (!empty($group_content)) {
      $group = $group_content->getGroup();
    }
    return $group;
  }

  /**
   * Get the group from the current route match.
   *
   * @return bool|\Drupal\group\Entity\GroupInterface
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   */
  public function getGroupFromRoute() {
    $entity = FALSE;
    $parameters = $this->routeMatch->getParameters()->all();
    if (!empty($parameters['group']) && is_numeric($parameters['group'])) {
      $group = Group::load($parameters['group']);
      return $group;
    }
    if (!empty($parameters)) {
      foreach ($parameters as $parameter) {
        if ($parameter instanceof EntityInterface) {
          $entity = $parameter;
          break;
        }
      }
    }
    if ($entity) {
      return $this->getGroupByEntity($entity);
    }
    return FALSE;
  }
}

```

# Answer
Answering my own question:

> How do I get group to which the node belongs

Install: Entity Group Field which is an add-on / companion module for use with the Drupal Group module.

Which provides an additional field (a 'computed' field) which automatically takes its value which is the Drupal Group that the content 'belongs' to. If the content doesn't belong to any group, then the field is not set.

The field is setable when editing or creating the content.

In terms of configuring the content type, the field only shows in the Manage Form Display section, so that you can position it for when editing the content.

Entity Group Field was discovered here: Group | Contributed Modules \- see this page for other modules that extend Group functionality.

> and redirect anonymous users to the login page if they land on it?

A simple 'blanket' approach to this is to change the access denied URL to `/user/login` in the settings in `admin/config/system/site-information`, see under 'Default 403 (access denied) page'. (Credit to my colleague Dylan for his thought that in most cases redirect to login ought to be OK, instead of Access Denied)

I've now implemented the above 2 steps and am finding them to work, from testing so far.

A further step I've not tried is to try to get the access denied redirect to work only for Group-only content, by programmatically getting the aforementioned above computed field value, if it is available from the Node object.
> 1 votes

# Answer
Service name mismatch: in your module file `mysite_custom_module.module` you are calling your service with `\Drupal::service('mysite_custom_module_module.current_group');` but in `mysite_custom_module.services.yml` you define it as `mysite_custom_module.current_group`

Also, are you sure your Route does define parameters? Can you show the route definition code?
> 0 votes

---
Tags: users, redirection, 9, group
---


# Question
Title: How can I create a table view of entities showing their related entities in the same row?
I have multiple content types, which are in some ways related to each other. Lets say, the first one is "Author". Other ones are "Novel", "Drama" and "Short Story", which each reference "Author" (using the same field for each content type, so I can create relationships easier later in the view). Now I want to create a view table like this:

| Author | Novels | Dramas | Short Stories |
| --- | --- | --- | --- |
| King, S. | It, Insomnia, ... | ... | Rush Call, ... |
| Martin, G. R. R. | ASOIF, ... | ... | ... |
| ... | ... | ... | ... |

For each author there should be one(!) row in the table and for each text type they wrote there should be a column in the table showing the titles of that text type comma separated.

How can I achieve this output using views? I tried different ways of grouping and aggregation, but none of them quite worked. For example, when I try to group by "Novel", the tables split and it looks awful. I would have no problem styling the final results in a custom template, but what can I do using core views to get to my desired outcome a little bit easier?

# Answer
> 0 votes
I don't see a way of creating with vanilla Views, that without changing the templates.

---

Starting from the Author Views is the worse path to take. You can use reverse Relationships to show nodes that reference a particular Author, but they will be in separate rows, reverse Relationship doesn't support Multivalue options that you get when directly displaying an ER field.

---

The best path seems to be to create Content Views that lists all "Novel", "Drama", and "Short Story" nodes. Add the Title Field, Author ER, and the CT (type).

(I don't know if there is some magical Agreggate trick that could work to your solution, the usual ones I've used aren't sufficient for something like this.)

Hide the Author field with `Exclude from display` and then under `Format` Settings select the Author field as the Grouping field.

This will still give you each book in its own row, but they will be grouped by their authors. With some template changes you can change the grouping to appear within the table so it appears more like you'd like, with the Author as a column that spreads multiple rows (their work) and all results can be displayed within one table where each author info is within separate `tbody` elements.

With some more templates adjusted I think you could get to construct exactly the table you want where work nodes of the same type are printed out in the same cell, and types come out as columns, but it wouldn't be trivial.

---

You might also try the Views Field View module. This is usually used to embed Views within Views (that are related through a field such as an ER field) but it can be very heavy on the performance!

I also haven't tried it under the reverse condition, assuming you start from the author and then get to the relating nodes through backwards Relationships. But OTTOMH it seems possible, you could list all work in the same table row as the Author, each work would still be in a separate row but you could group them by type though. The types wouldn't display horizontally like in your case, but vertically, still it would be close to what you want to achieve. And you could use templates to replace the output of the "embedded" Views (works) to match it closer to what you had in mind.

---
Tags: views
---


# Question
Title: Drupal config error "module.settings" depends on the module that will not be installed after import
I'm having this error on Travis Build. I can't go pass this error. I've been removing `dblog` from the list of config and also delete from my localhost database before I export `drush cex sync -y`

```
 The import failed due to the following reasons:
  Configuration <em class="placeholder">dblog.settings</em> depends on the <e
  m class="placeholder">Database Logging</em> module that will not be install
  ed after import.
  Configuration <em class="placeholder">views.view.watchdog</em> depends on t
  he <em class="placeholder">Database Logging</em> module that will not be in
  stalled after import. '

```

What else should I try to solve this problem?

# Answer
> 7 votes
This usually happens when the module isn't enabled in `core.extension.yml` but you are trying to import the config for that module.

It can usually be fixed by adding it to `core.extension.yml` E.g.

```
  dblog: 0

```

Note that the "zero" indicates the "weight" of the module, and does *not* indicate a 0/1 enabled/disabled boolean.

---
Tags: 8
---


# Question
Title: How can I programmatically bulk delete redirect entities based on their status code?
I have a list of 3089 301 redirects URLs and want to delete them programmatically from the database.

E.g *List of source URLs*

/about/test/2013/page\_61732.html /about/test/additional/branches/page\_38678.html
/about/test/additional/branches/page\_38678.html
/about/test/additional/branches/page\_38678.html ......

# Answer
> 2 votes
If I understand your question correctly, you want to delete all redirects with a status code of 301. That could be done like this:

```
$ids = \Drupal::entityQuery('redirect')
   ->condition('status_code', '301')
   ->execute();

$entities = Redirect::loadMultiple($ids);

\Drupal::entityTypeManager()->getStorage('redirect')->delete($entities);

```

If you only want to delete redirects that have a certain source URL, you should be able to add

```
->condition('redirect_source__path', $sources, 'IN')

```

to your query.

# Answer
> -1 votes
```
<?php
        use Drupal\redirect\Entity\Redirect;

        //list of all source urls
        $newInputs = [
            '/about/*****/2013/page_61732.html',
            '/about/*****/additional/branches/page_38678.html',
            '/about/*****/additional/branches/winners/page_38681.html',
            '/about/*****/additional/development/winners/page_38703.html',
             .....................
        ];

        foreach ($newInputs as $input) {
                 $sourceUrl = trim($input);

                 $query = \Drupal::entityTypeManager()->getStorage('redirect')->getQuery();
                 $redirects = $query->condition('redirect_source.path', substr($sourceUrl, 1))
                           ->execute();

                 $storageHandler = \Drupal::entityTypeManager()->getStorage('redirect');
                 $entities = $storageHandler->loadMultiple($redirects);

                 foreach ($entities as $entity) {

                         //get redirect source path
                          $sourceRedirectUrl = $entity->getSourceUrl();

                          if ($sourceRedirectUrl == $sourceUrl)
                             {
                               $entity->delete();

                              }
                           elseif (urldecode($sourceRedirectUrl) == urldecode($sourceUrl))
                              {
                                $entity->delete();
                               }
                           else
                               {
                                print 'Error !! Bad Url in the record';

                                Print "Source Url from list : ".urldecode($sourceUrl)." \n Source Redirect Url " .urldecode($sourceRedirectUrl). "\n";
                                }

                }
          }

      print 'There were ' . $done . ' redirects deleted.' . "\n";

```

---
Tags: 8, redirection
---


# Question
Title: How do I expose display routes from a specific view as REST API?
I have set up some displays in a *Categories* view, all with their own path. I want to expose all displays from that view with a REST API.

I've already set up a module with a path, but how do I get the paths to the individual displays?

`$view = Views::getView('categories');` gives me the view (probably with my desired displays), but I am quite stuck there.

Most of the answers I find online are pretty much outdated.

# Answer
I actually found a solution which is working for me myself.

```
$view = Views::getView('categories');

$displays = $view->storage->get('display');

$ret = array();

foreach( $displays as $display){
  array_push($ret, array(
    'title'   => $display['display_title'],
    'path'    => $display['display_options']['path']
  ));
}

return new JsonResponse( $ret );

```
> 0 votes

---
Tags: views, 9
---


# Question
Title: Using variable_get from DrupalWebTestCase
I would like to pull certain configuration items from settings.php from a DrupalWebTestCase in order to test my module (in this case, a SFTP module). I want to do it this way so that I don't hardcode my SFTP credentials.

For example, in my DrupalWebTestCase, I have:

```
  public function test_sftp()
  {
    $this->assertTrue(variable_get('mymodule_test_sftp'));
    // then I would try to connect, etc....
  }

```

In settings.php:

```
$conf['mymodule_test_sftp'] = array(
 'host' => 'example.com',
 // etc...
);

```

When I run the unit testing suite, this unit test fails, the value returned by variable\_get is NULL.

**Edit:**

Running the code below, returns the correct database settings, but I get "**Undefined index: mymodule\_test\_sftp**":

```
  public function test_sftp()
  {
    global $databases, $conf;
    $this->assertTrue($databases);
    $this->assertTrue($conf['mymodule_test_sftp']);
  }

```

# Answer
> 2 votes
Just faced a similar issue. What I have found out is that in your `DrupalWebTestCase` child class you still have access to all variables defined in `settings.php` before calling `parent::setUp()`. Which means you can do something like this:

```
class MymoduleWebTestCase extends DrupalWebTestCase {

  public function setUp() {
    $mymodule_test_sftp = variable_get('mymodule_test_sftp');

    parent::setUp();

    variable_set('mymodule_test_sftp', $mymodule_test_sftp);
  }

}

```

# Answer
> 0 votes
In the current Drupal 7, I found that the above is only true the first time the test case setUp() method is called. On subsequent calls, the values from settings.php will either be gone or replaced by what was in the database, which is not always the same. A local development instance of a site, for example, might have a definition for "site\_name" that is different from the "site\_name" value in the database copied from the live site.

You can catch that first value and use it thereafter:

```
class MymoduleWebTestCase extends DrupalWebTestCase {

  public function setUp() {
    static $mymodule_test_sftp = NULL;
    if ($mymodule_test_sftp === NULL) {
        // if it's not defined, don't keep checking
        $mymodule_test_sftp = variable_get('mymodule_test_sftp', FALSE);
    }

    parent::setUp();

    if ($mymodule_test_sftp) {
        variable_set('mymodule_test_sftp', $mymodule_test_sftp);
    }
  }

}

```

---
Tags: 7, testing, configuration
---


# Question
Title: How to force display of a specific page of paged data
I'm displaying a table of dated items ordered from old to new and am using the full pager. How can I force my page to initially display those items that are current ie. on initial load, display the page containing items that are most current (which might be ?page=17). The user can then page back/forwards to get older or newer items. Drupal 8.

# Answer
> 0 votes
I'm half way there!

In hook\_views\_pre\_build(\Drupal\views\ViewExecutable $view) I figured that the $cnt item was the most current; from there it was a simple matter to calculate which page that item would appear on and to set that as the current page.

```
$pager = $view->getPager();
$defaultPageNum = round($cnt/$pager->getItemsPerPage());
$pager->setCurrentPage($defaultPageNum);

```

This works like a charm; however, the pager links at the bottom of the page do not auto-magically update and still indicate that I'm on page 1 (instead of page 62).

Anyone know how I get these links to update?

---
Tags: page-controller
---


title: How can I get numbered classes on rows?

text:
# Question
Title: How can I get numbered classes on rows?
I worked briefly with Drupal 7 and I thought it was possible there but in Drupal 8 is it possible to have a view output an increasing numbered CSS classes for Views rows?

This is what I want.

```
<div class="view">
  <div class="view-row-1"></div>
  <div class="view-row-2"></div>
  <div class="view-row-3"></div>
  <div class="view-row-4"></div>
</div>

```

I know I can add a CSS class to every row and give every row the same class.

# Answer
> 11 votes
In Drupal 7 and 8 the add view row classes is check-marked by default.

**The problem is that in Drupal 8, it does not work. (looks like this is a bug)**

As you can see in the above picture, the number is missing on the div class.

# Luckily, there is a workaround solution.

In FIELDS, add Global: View result counter and hide it from display

In FORMAT, click on Settings (the 1st one)

For row class, put for example: `hello-{{ counter }}` and uncheck-mark "add view row class", as you don't need it.

## Result

# Answer
> 5 votes
I liked the solution provided by **@No Sssweat**

As the above solution still an issue in https://www.drupal.org/node/2669394.

Other way is **Rewrite results** where you can add the classes like you need.

**Add Global: View result counter and hide it from display**

```
<div class="views-row-{{ counter }}">
</div>

```

# Answer
> 2 votes
Or you can use the module Semantic Views to number row classes, first/last and every nth row, custom markup and more.

> This Views plugin makes unformatted styles, field row styles and other output more readily configurable without needing to override template files. Instead of overriding row style templates for views where you want to specify different HTML elements (tags) and class attributes, you can specify these inside the Views UI and avoid overriding templates for each view.

# Answer
> 2 votes
You can also do this in your views-view--\[view name\].html.twig template by replacing

```
{{ rows }}

```

with

```
{% set totalrows = rows[0]['#rows']|length %}
{% for row in rows[0]['#rows'] %}
     {% set rownum = ( rownum | default(0) ) + 1 %}
     <p>This is row: {{ rownum }} of {{ totalrows }}</p>
     {{ row }}
{% endfor %}

```

# Answer
> 2 votes
This can be done by simply changing one line in the default views template.

Add a copy of `views-view-unformatted.html.twig` to your theme and change this:

```
set row_classes = [
  default_row_class ? 'views-row',
]

```

to this:

```
set row_classes = [
  default_row_class ? 'views-row views-row--' ~ loop.index,
]

```

As long as "Add views row classes" is checked in the Views UI, the div classes will show as follows:

```
<div class="views-row views-row--1"></div>
<div class="views-row views-row--2"></div>
<div class="views-row views-row--3"></div>

```

# Answer
> 1 votes
For me the easiest way to print numbered CSS classes in Views rows was per the following Twig snippet.

```
{% for key, row in rows %}
  <div class="view-row-{{ key+1 }}">
    {{ row }}
  </div>
{% endfor %}

```

This will output the following markup.

```
<div class="view-row-1"></div>
<div class="view-row-2"></div>
<div class="view-row-3"></div>
<div class="view-row-4"></div>

```

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


# Question
Title: How can I display a taxonomy term's ancestral tree on a content page?
I am using Drupal 8. I have a hierarchical taxonomy vocabulary like this (simplified):

Animals
-Vertebrates
--Fishes
---Butterflyfishes
----Chevron Butterflyfish

On a taxonomy term's page, I automatically get the ancestral tree as breadcrumbs. For example, on drupal/Butterflyfishes I see this:

Animals \>\> Vertebrates \>\> Fishes

If I add Butterflyfishes as a Taxonomy term entity reference on a content page (i.e. not the taxonomy term's page itself), how can I also display such an ancestral tree on that content page?

# Answer
2 possible solutions: a) programmatically via an own custom module providing a custom formatter or via a custom theme function. Or b) via contrib modules providing a field formatter to view the whole term path instead of only the end point (default).

In your case I assume you ask for the second. The module Hierarchical select used to provide this view widget (field formatter) in D7 and maybe alternative modules like SHS or CSHS in D8 will provide it? If not, you can try to work with the Custom formatter module, which enables you to build own formatters in admin UI without creating own modules for this purpose. It comes with examples showing how it works, and it can be used even if the user has no advanced module development knowledge.
> 1 votes

# Answer
https://www.drupal.org/project/hierarchical\_term\_formatter, https://www.drupal.org/project/shs and https://www.drupal.org/project/cshs all provide this functionality.
> 1 votes

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


# Question
Title: Why are spaces in the file path rendered with %2520 instead of %20?
I have a custom content entity (service) with a 'file' field defined by:

```
$fields['file'] = BaseFieldDefinition::create('file')
  ->setLabel(t('File'))
  ->setSettings([
    'file_extensions' => 'pdf',
    'file_directory' => 'sel',
    'description_field' => TRUE,
  ])
  ->setDisplayOptions('view', [
    'type' => 'file',
  ])
  ->setDisplayOptions('form', [
    'type' => 'file',
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE);

```

A classic CRUD form allows me to create a service:  Lets say I upload a file with spaces in its name. As you can see if I hover the file name in the form, the link appears to be `http://jdp8:8888/sites/default/files/sel/name%20with%20spaces.pdf`with `space` replaced by `%20` and the link works:
So far, so good...

I have a View to display this content entity:  The 'file' field is rendered as a '•' with a link to the file that allows to open the content of the file (a .pdf file) in another window.
When the file name contains spaces, it is rendered as `http://jdp8:8888/sites/default/files/sel/name%2520with%2520spaces.pdf` with `%2520`instead of `%20`.
And of course the links leads to a `The requested page was not found` error.

I have recently updated Drupal to 8.9.13.
Before I was running Drupal 8.9.1 and I am pretty sure that it was working.

Any idea on what is going wrong? Is it Drupal? Is it Views?

As I suspect Views (everywhere else, it works), here is the way the file field is handled in the view:

# Answer
> 2 votes
I found a kind of workaround: I wrote `{{ file__target_id|replace({'%20': " "}) }}` in the definition of 'file' field in the view.

---
Tags: 8, views
---


# Question
Title: How to make get for drupal behaviors to run only once?
```
Drupal.behaviors.js_mod = {
attach: function (context, settings) {
     //$('body', context).append(chart);
    // $( '#drupal-myradar', context ).once
     $.get( "/web/js/mod", function( data ) {
        console.log(data);
      });
}

    }
})(jQuery, Drupal, drupalSettings);

```

Essentially this code is running multiple times while grabbing information from my controller code. I only want this to print out once to the console when the page is loaded.

# Answer
This works as designed. Behaviors attach runs multiple times, but the scope provided in context changes. So check if the element is in context and apply once() to get the element only one time:

```
 Drupal.behaviors.js_mod = {
    attach: function attach(context, settings) {
      var $myradar = $(context).find('#drupal-myradar').once('js_mod');
      if ($myradar.length) {
        ...

```
> 4 votes

# Answer
If your script is high-level, which is most likely, then only run it when the context is equal to the document. I found this trick in the autologout module and use it almost everywhere now:

```
Drupal.behaviors.dosomething = {
  attach: function attach(context, settings) {
    if (context !== document) {
        return;
    }
    // Do stuff here but still use .once when attaching behaviors.
  ...

```
> 10 votes

# Answer
That would do :

```
(function($, Drupal, drupalSettings) {
    let onlyOnce;
    Drupal.behaviors.js_mod = {
      attach: function (context, settings) {
          if (!onlyOnce) {
            onlyOnce = true;
            //$('body', context).append(chart);
            // $( '#drupal-myradar', context ).once
            $.get( "/web/js/mod", function( data ) {
              console.log(data);
            });
          }
       }
     }
})(jQuery, Drupal, drupalSettings);

```
> -4 votes

---
Tags: 8, javascript
---


# Question
Title: Is there a way to see all the available variables inside content?
I am using Drupal 9 with twig files

I have a page where in one section I need to show thumbnails of the latest posts. So I created a new view as a block, and placed this block under Content in admin/structure/block/list/

When I inspect with debug on I get these file suggestions -

```
 FILE NAME SUGGESTIONS:
   * block--views-block--latest-news-block-1.html.twig
   * block--views-block--latest-news-block-1.html.twig
   * block--views-block.html.twig
   * block--views.html.twig
   x block.html.twig

```

So I created a file name block--views-block--latest-news-block-1.html.twig with the code from block.html.twig.

Inside that file I have -

```
    {% block content %}
      {{ content }}
    {% endblock %}

```

Which shows all the content in the block. I need to customize the content in the block though, some things need to be removed, I need to truncate the article text, need to add buttons.

I think I'd be able to do what I want if I could target specific parts of the content. I want to do something like this -

```
<div class="card">
     <h2>{{ content.title }}</h2>
     <p>{{ content.body }}</p>
</div>

Is there a way to target specific parts of the content like that?

```

# Answer
Normally it works that way but Views templates may be different.

1. Enable Twig debugging.
2. Add Devel and Kint: `composer require drupal/devel kint-php/kint`
3. Enable Devel: `drush -y en devel`
4. Inside the template put `{{ kint(content) }}`, flush caches, visit the page and you should see what else can be found inside `content`.
> 2 votes

---
Tags: views, theming, blocks
---


title: How do I turn off maintenance mode?

text:
# Question
Title: How do I turn off maintenance mode?
Does anyone know how to turn off maintenance mode? I tried accessing http://www.example.com/?q=user/login, but that gives me a blank page. I tried executing this SQL query, but it didn't affect any record.

```
UPDATE `variable` SET `value`='0' WHERE 'name' = 'maintenance_mode';

```

I tried to find a `$conf['maintenance_mode']` variable in the project, but it doesn't exist. Adding `$conf['maintenance_mode'] = false;` in the *setting.php* file didn't do anything either.

How do I turn off maintenance mode?

# Answer
> 27 votes
Using Drush, you can run `drush vset maintenance_mode 0` to disable the maintenance mode on a Drupal 7 site.

# Answer
> 15 votes
The answer by schnippy is correct; however, some details are wrong, at least in Drupal 7.28.

The query to change maintenance\_mode should be:

```
UPDATE variable SET value = 'i:0;' WHERE name= 'maintenance_mode';

```

The value is an integer, even if a string might work as well. It's just not what Drupal itself uses.

More importantly, in order to reset the cache for maintenance\_mode, the table to use is cache\_bootstrap.

```
DELETE FROM cache_bootstrap WHERE cid = 'variables';

```

There is no cache with ID equal to *variables*, inside the *cache* table.

This is tested and works with Drupal 7.28.

# Answer
> 7 votes
You're on the right track with the database approach but your query is wrong since the variables are serialized. The actual syntax is:

```
UPDATE variable SET value = 's:1:"0";' WHERE name= 'maintenance_mode';

```

Also - its a good idea to follow this by flushing the variables cache:

```
DELETE FROM cache WHERE cid = 'variables';

```

# Answer
> 5 votes
Maintenance mode is triggered by the variable "maintenance\_mode", which is set to 1 when activated.

This is the code present in the System module (system.admin.inc, line 2194).

```
/**
 * Form builder; Configure the site's maintenance status.
 *
 * @ingroup forms
 * @see system_settings_form()
 */
function system_site_maintenance_mode() {
  $form['maintenance_mode'] = array(
    '#type' => 'checkbox',
    '#title' => t('Put site into maintenance mode'),
    '#default_value' => variable_get('maintenance_mode', 0),
    '#description' => t('When enabled, only users with the "Use the site in maintenance mode" <a href="@permissions-url">permission</a> are able to access your site to perform maintenance; all other visitors see the maintenance mode message configured below. Authorized users can log in directly via the <a href="@user-login">user login</a> page.', array('@permissions-url' => url('admin/people/permissions'), '@user-login' => url('user'))),
  );
  $form['maintenance_mode_message'] = array(
    '#type' => 'textarea',
    '#title' => t('Maintenance mode message'),
    '#default_value' => variable_get('maintenance_mode_message', t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))),
    '#description' => t('Message to show visitors when the site is in maintenance mode.')
  );

  return system_settings_form($form);
}

```

You can use drush to disable maintenance mode.

```
drush vset maintenance_mode 0;
drush cc all;

```

You can also use `variable_set('maintenance_mode', 0)` and clear cache afterwards (with a call to `cache_clear_all()`).

# Answer
> 2 votes
With the latest version of Drush/Drupal the command has changed:

```
drush state:set system.maintenance_mode 0 --input-format=integer
drush cache:rebuild

```

Drupal documentation

# Answer
> 0 votes
If you remember your username and password, login from http://www.example.com/?q=user. Then go to *Configuration \>\> Maintenance mode*; uncheck *Put site into maintenance mode*, and save.

# Answer
> -3 votes
In my case, Drush was not working and I could bring back the site by doing this:

Add the below line in docroot\core\lib\Drupal\Core\EventSubscriber\MaintenanceModeSubscriber.php

\Drupal::state()-\>set('system.maintenance\_mode', FALSE);

Run the site again for 2-3 times (clearing the cache) and it is up again.

Remember to take out this line once your site is up

---
Tags: maintenance-mode
---


# Question
Title: Exclude first node with specific value from a view?
We have an Article content type. The content type has a boolean field called "Featured".

We have two views setup:

1. The featured article view. This is limited to the most recent article with the "Featured" boolean checked (limit 1, sort by date).
2. The recent articles view. This shows all the recent articles on the site.

The problem is we don't want the most recent "Featured" article to display in the recent articles view. But we also want other "Featured" articles to display if they aren't the most recent.

I can't find an easy way to achieve this as we are only allowed to filter out ALL featured articles or none, and not just the first one.

# Answer
> 1 votes
The easiest and fastest way I can think of is to use an offset in your pager.

If the most recent featured article is to be skipped, ensure that the list does not start with the first, but with the second result. You can do this for any pager, or even with a fixed amount of items to display.

Alternatively, but that is easier with a node and a view, you might be able to use a contextual filter to suppress a Content ID from a views listing. I have used to populate a sidebar view with all recent articles except the viewed one.

In your situation it might be an issue getting the Content ID from one view to another though

---
Tags: 8, views
---


# Question
Title: Is it possible to alter html_head using hook_page_attachments_alter() per node?
Is it possible to alter html\_head using `hook_page_attachments_alter()` per node? I need to attach different `<script>` tags to a list of nodes. I am able to add it to each node, but all gets overridden with the last alteration.

```
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'faq_page', 'status' => 1]);

foreach($nodes as $node) {
  $description = [
    [
      '#tag' => 'script',
    ],
    // …
  $page['#attached']['html_head'][] = [$description, 'description];
}

```

# Answer
> 2 votes
Yes, when you get the current node.

```
/**
 * Implements hook_page_attachments_alter().
 */
function MYMODULE_page_attachments_alter(array &$attachments) {

  $node = \Drupal::routeMatch()->getParameter('node');

  if ($node instanceof \Drupal\node\NodeInterface) {

    $attachments['#attached']['html_head'][] = [
      [
        '#tag' => 'script',
        '#value' => 'alert("' . $node->getTitle() . '")',
      ],
      'MYMODULE_foobar',
    ];
  }
}

```

---

If this really should be in a `foreach`, you need to ensure to give each tag an unique key.

```
foreach ($nodes as $node) {
  $description = [
    [
      '#tag' => 'script',
    ],
    ...
  ];
  $page['#attached']['html_head'][] = [$description, 'description_' . $node->id()];
}

```

---
Tags: nodes
---


# Question
Title: How to load a node given a menu link id?
I have this id via `$link->getParent()`:

```
menu_link_content:6cf83fce-228f-42da-bc39-bea06c767510

```

How do I get the node id of that menu link?

# Answer
Something like:

```
if ('entity.node.canonical' == $link->getRouteName()) {
  $params = $link->getRouteParameters();
  $nid = $params['node'];
}

```
> 5 votes

# Answer
See EntityRepository::loadEntityByUuid() for a non-deprecated way of loading by UUID.
> 1 votes

# Answer
You can load the node from the (already depreciated) entityManager using the UUID:

```
$node = \Drupal::entityManager()->loadEntityByUuid('6cf83fce-228f-42da-bc39-bea06c767510');

```
> 0 votes

# Answer
Elaborating on simesy's answer.

```
$menu_id = $link->getParent();
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
$menu_item = $menu_link_manager->createInstance($menu_id);
if ('entity.node.canonical' == $menu_item->getRouteName()) {
  $params = $menu_item->getRouteParameters();
  $nid = $params['node'];
}

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: Twig adds an unwanted 'row' class that doesn't appear in class array
My site theme includes customised templates for 4 regions in the footer, all containing identical code:

```
  set classes = [
    'region',
    'region-' ~ region|clean_class,
    'col-sm-12',
    'col-md-6',
    'col-lg-3',
  ]
%}
{% if content %}
  <section{{ attributes.addClass(classes) }}>
    {{ content }}
  </section>
{% endif %}

```

However, the HTML it produces varies.

In the first two regions, the class `row` is being inserted - despite it not appearing in the `classes` array:

```
<!-- BEGIN OUTPUT from 'themes/custom/my_theme/templates/layout/region--footer-first.html.twig' -->
  <section class="row region region-footer-first col-sm-12 col-md-6 col-lg-3">

```

In the last 2 regions, the `row` class is missing - which is the correct code I want:

```
<!-- BEGIN OUTPUT from 'themes/custom/my_theme/templates/layout/region--footer-third.html.twig' -->
  <section class="region region-footer-first col-sm-12 col-md-6 col-lg-3">

```

I can't figure out where it's coming from, so my workaround is to include an additional step that removes the class, in the first two region templates only:

```
<section{{ attributes.addClass(classes).removeClass('row') }}>

```

This gives the result I want, but I'm still not sure where the `row` class comes from and why it was being applied inconsistently??

# Answer
Those 5 classes are being added using `.addClass()` to a pre-existing `{{ attributes }}` Twig object. The 'row' class must already be in the `attributes` object when Drupal passes it to the Twig template.

Typically, the place where something like that would happen is in your .theme file (or the parent theme's .theme file if yours is a subtheme). Look for a function like **THEMENAME\_preprocess\_region()** and see if you can find a hard-coded "row" string being thrown in there.

Alternatively, some fancier theme systems might expose configuration options in the Drupal interface that could be setting that class. You'd find those under Admin \> Appearance, then in "Settings" for your active theme.
> 2 votes

---
Tags: 8, theming
---


# Question
Title: Uncaught PHP Exception: MissingValueContextException
After upgrading to version 8.8.5, I can't access the main web page, but I can log in to the admin panel. When I turn on the verbose logging funcionality I receive the following error message:

```
Drupal\Component\Plugin\Exception\MissingValueContextException: Required contexts without a value: view_mode in Drupal\Core\Plugin\Context\ContextHandler->applyContextMapping() (line 155 of core/lib/Drupal/Core/Plugin/Context/ContextHandler.php).

Drupal\panels\Plugin\DisplayBuilder\StandardDisplayBuilder->buildRegions() (Line: 183)
Drupal\panels\Plugin\DisplayBuilder\StandardDisplayBuilder->build() (Line: 338)
Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant->build() (Line: 29)
Drupal\page_manager\Entity\PageVariantViewBuilder->view() (Line: 105)
Drupal\Core\Entity\Controller\EntityViewController->view() call_user_func_array() (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 124) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 57)
Drupal\Core\StackMiddleware\Session->handle() (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch() (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup() (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 23)
Stack\StackedHttpKernel->handle() (Line: 708)
Drupal\Core\DrupalKernel->handle() (Line: 19)

```

I don't know if this is a core or a module error, any help appreciated.

Actual system: Drupal 8.8.5, PHP 7.4.5, 5.5.5-10.1.44-MariaDB-0+deb9u1

Thanks.

# Answer
It seems to be related to a new constraint added on releases, as seen on https://www.drupal.org/project/drupal/issues/3113474

As "view mode" is asked, with no default context, some modules like Panels IPE, Panels, MiniLayout may generate problems if you ask to display a single entity field as FieldBlock.

Just apply patch on https://www.drupal.org/files/issues/2020-02-13/3001313--63\_0.patch ; for the record :

```
--- a/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php
+++ b/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php
@@ -124,7 +124,14 @@ public function getDerivativeDefinitions($base_plugin_definition) {
           $context_definition->addConstraint('Bundle', [$bundle]);
           $derivative['context_definitions'] = [
             'entity' => $context_definition,
-            'view_mode' => new ContextDefinition('string'),
+            'view_mode' =>  new ContextDefinition(
+              'string',
+              $this->t('View Mode'),
+              FALSE,
+              FALSE,
+              NULL,
+              'default'
+            ),
           ];

```
> 0 votes

---
Tags: 8, panels
---


# Question
Title: Database log messages (auto cleaning) with keeping exceptions
I can see that the Drupal has a settings about logs to keep, but when some amount is configured, so after X logs, the oldest are deleted.

Is there any option to make some logs not to be deleted?

# Answer
> 0 votes
Under **Database log messages to keep**, there is an **All** option to keep all logs. However, there is no option to selectively delete logs automatically in core.

There are two things you could try instead:

First, the **Recent log messages** screen is a view. So, if you have the Views UI module enabled, you can edit the log messages view to create a new view mode (for example, a separate page) and then customize the configuration on that page to only list the types of log messages you want to automatically delete. You can then trigger this manually at whatever interval you want.

Another option would be to use the Logging and Alerts module to store the logs you want to keep forever by copying them to email, SMS, or some other server.

---
Tags: log-messages
---


# Question
Title: How to get the "label" of "Allowed Values" for a text list programmatically?
I created a text list field on the user entity. I entered the following for **Allowed values list:**

```
apple|A delicious apple
pear|A very delicious pear
orange|A not so delicious orange

```

I can access the key for the field like this:

```
$current_user->get('field_list_fruits')->value,

```

which returns `apple`. But how do I get the text `A delicious apple` programmatically?

# Answer
> 2 votes
Load the field config and look for the key/value pair from the allowed value list?

Much easier though is using the field formatter for this field type OptionsDefaultFormatter:

```
$build = $user->field_foo->view(['type' => 'list_default']);

```

What you do with $build depends on the use case. Put it in a render array to be rendered later or

```
$output = \Drupal::service('renderer')->renderPlain($build);

```

if you need it now and can't wait until the page is rendered, for example if you want to send an email.

---
Tags: 8, entities
---


# Question
Title: Create link to node in specific language
So I need to create links to specific translations of a node but am having issues.

This is my code:

```
foreach($entities as $entity) {
$urls[] = Url::fromRoute('entity.node.canonical', [
        'node' => $entity->id(),
        'language' => $entity->language()->getId(),
      ]);
}

```

`$entity` in this context is `EntityInterface`.

But this gives me `/node/1185?language=es` instead of `/es/node/1185`.

# Answer
> 1 votes
$entity-\>toUrl('canonical', \['language' =\> $entity-\>language()\]);

Taken from this question thread

---
Tags: nodes, i18n-l10n
---