# Question
Title: How to change labels on node add/edit form inside Authoring information box?
I have a Drupal 8 site with the Bartik theme. How can I change label text on node add/edit form inside 'Authoring information' box. This box contains:

```
-Menu settings
-URL path settings
-Authoring information
-Promotion options

```

I want to rename some labels and add a new input text field. The main thing I want to change is the Authoring information box and the information inside of it. Is this done with hook form alter?

:

# Answer
Those are the uid and created base fields, so yes hook\_form\_alter() or using interface translation are your options.

To add a new element in there, you need to set the right group, from NodeForm:

```
<?php
if (isset($form['uid'])) {
  $form['uid']['#group'] = 'author';
}

```
> 1 votes

# Answer
I encountered a similar problem, and I solved it by implementing hook\_form\_alter().

```
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'node_article_edit_form' || $form_id == 'node_article_form') {
    $form['author']['#title'] = t('Ownership information');
    $form['uid']['widget'][0]['target_id']['#title'] = t('Created by');
    $form['created']['widget'][0]['value']['#title'] = t('Created on');
  }
}

```
> 1 votes

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


# Question
Title: How to disable the page title output of main content?
I want to output the page title in the 'title' block and **not** with the main content output. I'm using the Bootstrap theme for Drupal 8.

I've enabled the title block and placed it in its own region but now I've got two page titles being displayed.

I've spent two days and have tried everything to disable the title that is output with {{ page.content }} in the page.html.twig template.

I do not want to hide it via CSS.

Can the page.content title be disabled?

# Answer
> 1 votes
The title is probably listed in the content type's manage display list.

Edit the content type and hide the title field.

---
Tags: 8
---


# Question
Title: Test a settings form that displays a queue
I'm trying to write a test on a settings form. The module uses a queue, and the settings form displays the items in the queue like so:

When I extend the test class from `WebTestBase` I get:

```
Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'mskcc_local_d8.test73723996queue' doesn't exist: SELECT COUNT(*) AS expression FROM (SELECT 1 AS expression FROM {queue} q WHERE name = :db_condition_placeholder_0) subquery; Array ( [:db_condition_placeholder_0] => google_analytics_counter_worker ) in Drupal\google_analytics_counter\GoogleAnalyticsCounterManager->getCount() (line 635 of modules/contrib/google_analytics_counter/src/GoogleAnalyticsCounterManager.php).
Drupal\Core\Database\Statement->execute(Array, Array) (Line: 625)
Drupal\Core\Database\Connection->query('SELECT COUNT(*) AS expression
FROM
(SELECT 1 AS expression
FROM
{queue} q
WHERE name = :db_condition_placeholder_0) subquery', Array, Array) (Line: 87)
Drupal\Core\Database\Driver\mysql\Connection->query('SELECT COUNT(*) AS expression
FROM
(SELECT 1 AS expression
FROM
{queue} q
WHERE name = :db_condition_placeholder_0) subquery', Array, Array) (Line: 510)
Drupal\Core\Database\Query\Select->execute() (Line: 635)
Drupal\google_analytics_counter\GoogleAnalyticsCounterManager->getCount('queue') (Line: 134)
Drupal\google_analytics_counter\Form\GoogleAnalyticsCounterSettingsForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 514)
Drupal\Core\Form\FormBuilder->retrieveForm('google_analytics_counter_admin_settings', Object) (Line: 271)
Drupal\Core\Form\FormBuilder->buildForm('google_analytics_counter_admin_settings', Object) (Line: 74)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 664)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

which tells me that the `queue` table is missing from the automated test environment.

But when I extend the test class from `KernelTestBase` and add

```
// These additional tables are necessary because $this->cron->run() calls
// system_cron().
$this->installSchema('system', ['key_value_expire']);

$this->connection = Database::getConnection();
$this->cron = \Drupal::service('cron');

```

to setup(), I assume my automated testing environment will contain a queue table (still to be determined). But the methods I regularly use to test a form, like `$this->drupalGet` and `$this->assertResponse` will now be not found.

How can I test a settings form that displays the contents of the queue table?

Thanks

# Answer
> 1 votes
A functional test satisfies both requirements.

```
<?php

namespace Drupal\Tests\google_analytics_counter\Functional;

use Drupal\Component\Utility\SafeMarkup;
use Drupal\Tests\BrowserTestBase;

/**
 * Tests the google analytics counter settings form.
 *
 * @group statistics
 */
class GoogleAnalyticsCounterSettingsTest extends BrowserTestBase {
  const ADMIN_SETTINGS_PATH = 'admin/config/system/google-analytics-counter';

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['google_analytics_counter'];

  /**
   * A test user with administrative privileges.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $adminUser;

  /**
   * Verifies that the google analytics counter settings page works.
   *
   * @see MediaSourceTest for good example code.
   */
  public function testForm() {
    $admin_user = $this->drupalCreateUser(array(
      'administer site configuration',
      'administer google analytics counter',
    ));
    $this->drupalLogin($admin_user);

    // Create item(s) in the queue.
    $queue_name = 'google_analytics_counter_worker';
    $queue = \Drupal::queue($queue_name);

    for ($i = 1; $i <= 5; $i++) {
      $queue->createItem(['type' => 'fetch', 'index' => 'boogie' . $i]);
    }

    $this->drupalGet(self::ADMIN_SETTINGS_PATH);
    $this->assertResponse(200, 'Access granted to settings page.');

    // Assert Fields.
    $settings_fields = $this->getAdminUserSettingsFields();
    foreach ($settings_fields as $field_name) {
      $this->assertField($field_name, SafeMarkup::format('@field_name field exists.', ['@field_name' => $field_name]));
    }

    // Cron Settings.
    $edit = [
      'cron_interval' => 0,
      'chunk_to_fetch' => 5000,
      'api_dayquota' => 10000,
      'cache_length' => 24,
    ];

    // Enable counter on content view.
    $this->drupalPostForm(self::ADMIN_SETTINGS_PATH, $edit, t('Save configuration'));
    $this->assertRaw('The configuration options have been saved.');
  }

  /**
   * Returns a list containing the admin settings fields.
   */
  protected function getAdminUserSettingsFields() {
    return [
      'cron_interval',
      'chunk_to_fetch',
      'api_dayquota',
      'cache_length',
      'queue_time',
      'start_date',
      'advanced_date_checkbox',
      'fixed_start_date',
      'fixed_end_date',
    ];
  }

}

```

---
Tags: 8, testing, queue
---


title: Making a radios form element required

text:
# Question
Title: Making a radios form element required
How can I make *which\_option* required so that users are forced to select an option?

```
$options = array(
  'Design1' => t('Design 1'),
  'Design2' => t('Design 2'),
);

$form['which_option'] = array(
  '#name' => 'which_option',
  '#id' => 'which_option',
  '#type' => 'radios',
  '#required' => TRUE,
  '#options' => $options,
  '#default_value' => isset($which_option) ? $which_option : NULL,
  '#prefix' => '<br><hr><br><p>If you're a lucky winner, tell us which bag you would like</p><br><div class="label-wrap">',
  '#suffix' => '</div>',
);

```

# Answer
> 1 votes
Looking at the code used from Drupal core, I found that book.admin.inc uses the following code, to define a require radios element.

```
$types = node_type_get_names();

$form['book_child_type'] = array(
  '#type' => 'radios',
  '#title' => t('Content type for child pages'),
  '#default_value' => variable_get('book_child_type', 'book'),
  '#options' => $types,
  '#required' => TRUE,
);

```

The code you shown doesn't work because *#default\_value* is set to `NULL`.

```
'#default_value' => isset($which_option) ? $which_option : NULL,

```

You don't show how `$which_option` is initialized; either that variable is never initialized, or it is not initialized when you tested the code. In both the cases, `isset($which_option)` returns `FALSE` and *#default\_value* is set to `NULL`.

Instead of that, the code should avoid setting *#default\_value*, which is what form\_test.module (a module for testing form elements) does. (See the first form element in the following code; the other form elements are shown to make a comparison.)

```
$form['radios'] = array(
  '#type' => 'radios',
  '#title' => 'Radios',
  '#options' => $options,
  '#required' => TRUE,
);
$form['radios_optional'] = array(
  '#type' => 'radios',
  '#title' => 'Radios (optional)',
  '#options' => $options,
);
$form['radios_optional_default_value_false'] = array(
  '#type' => 'radios',
  '#title' => 'Radios (optional, with a default value of FALSE)',
  '#options' => $options,
  '#default_value' => FALSE,
);

```

Notice the first radios element, which is required, doesn't have any *#default\_value* property set.

---
Tags: forms
---


title: Reload js behaviors after click

text:
# Question
Title: Reload js behaviors after click
I'm using boostrap 3 with modals. I've a button that opens a modal, in the modal there are some facet blocks. The view has ajax enabled, so when I click on a facet the page is not reload but are reloaded the content of the view AND facets blocks.

I've to execute some js functions when I click on facets links, I've added this js to my theme:

```
Drupal.behaviors.my_theme = {
    attach: function (context, settings) {
        jQuery('#facets a', context).click(function () {
            alert('enter');
        });
    }
};

```

The problem is that the alert is executed only on the first click. On second, third etc alert does not appear.

What's wrong?

# Answer
Check to see if the ID has changed. If the content containing #facets is getting ajaxed in then the ID may have changed

Or you could try:

```
jQuery('body').on('click', '#facets a', function () {
        alert('enter');
    });

```
> 1 votes

---
Tags: views, javascript, ajax, search, bootstrap-theme
---


title: Suitable way to hide a paragraph entity

text:
# Question
Title: Suitable way to hide a paragraph entity
I have read Hide an entity with hook\_entity\_view\_alter(), and by all rights this code should hide every paragraph on a page:

```
/**
 * Implements hook_ENTITY_TYPE_view_alter().
 */
function mymodule_paragraph_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
  $build['#access'] = false;
}

```

There are no errors, I know the function is being called because the debugger stops there on a breakpoint, I've cleared cache with every test.

I've tried `hook_entity_view`, `hook_entity_view_alter`, `hook_ENTITY_TYPE_view` and `hook_ENTITY_TYPE_view_alter`.

None of them have any effect whether I'm logged in or not.

`['#access']` is not showing up in the build array in any of these hooks which makes me think the advice might be out of date since 8.4 dropped? If it does work - why should it work?

Are there any other ways, better ways of hiding paragraph entities (or any entity really)?

Obviously there will be some logic involved later which is why I want to do it in one of these hooks (or similar).

---

Edit 1: It has been suggested that there should be a $build\['content'\] array or similar. There is only the entity object in whichever hook I try of the four I have listed:

# Answer
> 1 votes
Try this:

```
$build['#printed'] = TRUE

```

# Answer
> 1 votes
`$build['#printed'] = TRUE` works but is heavily cached..you can set your cache though or still try `$build['body']['0']['#access'] = FALSE;` OR

`$build['filter_this_view']['actions']['submit']['#access'] = FALSE;`

depending on your $build array structure. The fields will not be cached

# Answer
> 1 votes
I know it didn't work for you, but I am using `mymodule_comment_view_alter()` (i.e. hooking into hook\_ENTITY\_TYPE\_view\_alter) to selectively hide **individual comments**.

Although $build didn't have an '#access' key, eventually I tried

```
$build['#access'] = false;

```

and that *does* work, for comments anyway.

Also I don't need to clear the cache at all whilst editing the hook (I do have Twig debugging on it local.services.yml, but with twig.config.cache still enabled.)

(Drupal 8.5.5)

---
Tags: 8, entities
---


# Question
Title: Allow users to use embedded HTML tags in custom blocks
I'm using CKEditor in Drupal 8 and the client wants to write HTML that contains embedded tags like so

```
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
  <div class="menu-toggle-icon"></div>
</button>

```

Unfortunately, Drupal ends up mangling the code to something like this

```
<button aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-target="#navbarSupportedContent" data-toggle="collapse" type="button"></button>

<div class="menu-toggle-icon"> </div>
<button aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-target="#navbarSupportedContent" data-toggle="collapse" type="button"></button>

```

I think this is in an attempt to prevent XSS but I'm not totally sure.

Should I be able to allow the user to embed tags? If so, how could I go about doing this?

# Answer
The W3C specs (https://www.w3.org/TR/2011/WD-html5-20110525/the-button-element.html#the-button-element) show that a button allows phrasing content (https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#phrasing-content), e.g. a `<span>` to be placed inside a `<button>`, but not a `<div>`, so your WYSIWYG editor is correctly rearranging the elements.

Perhaps you could rework your code to allow for a `<span>` to be used inside the `<button>` and style that instead.
> 1 votes

# Answer
Answering my own question here. CKEditor will not allow for incorrect HTML as per this GitHub pull request found in this forum.

I.e.

```
<button>
  <div></div>
</button>

```

Will always be reformatted.
> 0 votes

---
Tags: 8, blocks, wysiwyg
---


# Question
Title: Custom Content Type with Custom Fields creation
I followed the examples given at: https://www.drupal.org/node/2629550 to create a new content type. No problems there, the content type exists after I install the module. However, when I uninstall, and re-install with the custom field yml files it says to have, I get errors saying that the field storage doesn't exists. So I dug into `core/modules/node/config/install`and copied the field.storage.body and modified it for the field I wanted (username). The field created, however, when I install the module now... It says:

`Drupal\Core\Field\FieldException: Attempt to create a configurable field for a non-configurable field storage. in Drupal\field\Entity\FieldConfig->__construct() (line 94 of C:\xampp\htdocs\drupal-8.4.4\drupal-8.4.4\core\modules\field\src\Entity\FieldConfig.php).`

Here is the yml for the custom content type:

```
#node.type.faculty_bio.yml
langcode: en
status: true
name: "Faculty Bio"
type: faculty_bio
description: "Faculty Bio"
help: ''
display_submitted: true

```

and the code for the custom field:

```
#field.field.node.faculty_bio.username.yml
langcode: en
status: true
dependencies:
  config:
    - field.storage.node.body
    - node.type.faculty_bio
  module:
    - text
    - node
id: node.faculty_bio.username
field_name: field.storage.node.username
field_storage: username
entity_type: node
bundle: faculty_bio
label: Username
description: 'The username'
required: true
translatable: true
default_value: {}
default_value_callback: ''
settings:
  display_summary: true
field_type: text

```

# Answer
I created the content type in a test environment, and populated all of the fields I wanted using the UI. Then I went to the site configuration and did an export on the entire site. I pulled all of the yml files I needed for the fields and node types, and it works beautifully.
> 0 votes

---
Tags: 8
---


title: Base tpl file for "add content" page?

text:
# Question
Title: Base tpl file for "add content" page?
I'm building my first drupal site, and I'm aware there's a huge amount about theming that I don't understand. Right now I'm learning to create custom layouts for specific pages by copying and modifying the template file for that page type (e.g., `node.tpl.php` -\> `node-—my-content-type.tpl.php`). Now I'm trying to modify the "add content" page for a specific content type. Is there a template file that I can copy and modify, and if so, where can I find it? Or does this page type need to be handled differently?

This is in Drupal 7.

*What I've tried:*

* Modifying `node.tpl.php` doesn't affect the add content page, nor does creating and modifying `node--add.tpl.php` nor `node--add--my-content-type.tpl.php`.
* Modifying `page.tpl.php` does affect the add content page (and all other pages). However...
* Copying it to `page--node--add--my-content-type.tpl.php` (as suggested in this question) causes the add content page for my-content-type to not display at all, so apparently there is some other template info that's needed.

# Answer
> 2 votes
Try

```
theme_node_add_list

```

Parameters

$variables: An associative array containing:

content: An array of content types.

```
function theme_node_add_list($variables) {
  $content = $variables['content'];
  $output = '';

  if ($content) {
    $output = '<dl class="node-type-list">';
    foreach ($content as $item) {
      $output .= '<dt>' . l($item['title'], $item['href'], $item['localized_options']) . '</dt>';
      $output .= '<dd>' . filter_xss_admin($item['description']) . '</dd>';
    }
    $output .= '</dl>';
  }
  else {
    $output = '<p>' . t('You have not created any content types yet. Go to the <a href="@create-content">content type creation page</a> to add a new content type.', array('@create-content' => url('admin/structure/types/add'))) . '</p>';
  }
  return $output;
}

```

See here

# Answer
> 0 votes
If you just need to modify or theme the node form page of all the node types then you can use:

page--node--add.tpl.php = Add New Node
page--node--edit.tpl.php = Edit Existing Node
page--node--delete.tpl.php = Delete Node

Further reading here Template (theme hook)

If you need it to be specific like:

page--my-article-type--add.tpl.php then use theme suggestion function like something below:

```
function MYTHEME_preprocess_page(&$variables) {
 global $theme_key;
 $theme_name = $theme_key;
 if (!empty($variables['node']) && !empty($variables['node']->type)) {
  $variables['theme_hook_suggestions'][] = 'page__' . $variables['node']->type;
 }
}

```

---
Tags: theming
---


# Question
Title: How to force the allowed number of values of a custom field to 1
I'm creating a custom field for a Drupal 8 site. How do I force the field cardinality to be just 1? All the answers I find are for Drupal 7.

# Answer
> 0 votes
I've found it:

```
    /**
     * Plugin implementation of the 'comment' field type.
     *
     * @FieldType(
     *   id = "comment",
     *   label = @Translation("Comments"),
     *   description = @Translation("This field manages configuration and presentation of comments on an entity."),
     *   list_class = "\Drupal\comment\CommentFieldItemList",
     *   default_widget = "comment_default",
     *   default_formatter = "comment_default",
     *   cardinality = 1,
     * )
     */

```

It's here: https://www.drupal.org/project/drupal/issues/2403703#comment-12248397

---
Tags: 8, entities
---


# Question
Title: Want to delete some custom user data while delete any user in Drupal8
Is there any Hook available for user delete in Drupal8. I have some custom data in a custom table and I want to delete those data while I delete any user in Drupal8. Can anybody help me out of this?

# Answer
Use `hook_entity_delete().`

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

```
function mymodule_entity_delete(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityType() == 'user') {
     ...
  }
}

```
> 4 votes

---
Tags: hooks
---


# Question
Title: How to get attachments out of a twig file
How do I get the attachments out a twig file and add them to a build array?

If there is a twig file with

```
{{ attach_library('mytheme/pullquote') }}

```

And because it's in an ajax response, I need to get the attachments out without rendering the page, how do I get a new build array with that library attached?

In my controller:

```
   $build['pullquote'] = [
      '#theme' => 'pullquote',
      '#quote_text' => $quote_text,
      '#attribution_name' => $attribution_name,
      '#attribution_title' => $attribution_title,
      '#size' => $size,
    ];

    $response = new AjaxResponse();
    $response->addCommand(new EmbedInsertCommand($build));
    return $response;

```

Because the library is added in twig and not in the build array, it's not coming through in the response.

The EmbedInsertCommand is from the embed module, which entity\_embed inherits from, at embed/src/Ajax/EmbedInsertCommand.php

which uses the CommandWithAttachedAssetsTrait, with this function:

```
 /**
   * Processes the content for output.
   *
   * If content is a render array, it may contain attached assets to be
   * processed.
   *
   * @return string|\Drupal\Component\Render\MarkupInterface
   *   HTML rendered content.
   */
  protected function getRenderedContent() {
    $this->attachedAssets = new AttachedAssets();
    if (is_array($this->content)) {
      $html = \Drupal::service('renderer')->renderRoot($this->content);
      $this->attachedAssets = AttachedAssets::createFromRenderArray($this->content);
      return $html;
    }
    else {
      return $this->content;
    }
  }

```

Unfortunately, AttachedAssets::createFromRenderArray misses libraries added within twig.

# Answer
Usually ajax commands which add html are able to catch attachments bubbling up when they render the content. Don't know EmbedInsertCommand(). The name clearly says it is an command inserting html, so it should be able to do it.

For commands not able to handle attachments you can render the content already in the controller and add the attachments to the response here:

```
  $response = new AjaxResponse();
  $html = \Drupal::service('renderer')->renderRoot($build);
  $response->addCommand(new EmbedInsertCommand($html));
  $response->setAttachments($build['#attached']);
  return $response;

```

This is only a workaround, not the recommend way, because Ajax does some more processing of the attachments before adding them to the response, but for a single command this should be OK.
> 0 votes

---
Tags: 8
---


title: Pathauto conditions

text:
# Question
Title: Pathauto conditions
Is it possible for Pathauto to have one pattern for a content type, and a different pattern for the same content type based on the value of a field in that content type? I have a checkbox field and if its checked I want to use a different pathauto setting. Right now the only condition Pathauto has is based on content type. Is there a hook that can do this.

# Answer
> 4 votes
Yes. There exists `hook_pathauto_pattern_alter()` for this purpose. Per the docs:

> Alter the pattern to be used before an alias is generated by Pathauto.
>
> This hook will only be called if a default pattern is configured (on admin/config/search/path/patterns).

A hook invocation takes arguments in which you can inspect the type and alter `&$pattern` accordingly.

---
Tags: 8, path-aliases
---


# Question
Title: Show/hide menu link based on changing custom $tempStore value
I'd like to show/hide a main-menu link based on a `$tempStore` variable the user can set and modify during their session, i.e.

* user sets `$tempStore['vlaue'] = 0;` --\> menu link is hidden
* user sets `$tempStore['value'] = 1;` --\> menu link is shown.

The menu link is provided by a view (page). What I started to do is to implement my own custom `RouteSubscriber` which adds a custom access check (which is defined as a service in `mymodule.service.yml`) to the view. The custom access check in `myCustomAccessCheck.php` basically does the following

```
   ...
   $value = $tempstore->get('value');
   return AccessResultAllowed::allowedIf($value == 1);
   ...

```

Apparently Drupal by default hides all menu links that the user does not have access to, so this approach should work (which it actually does!). However, caching is a problem, i.e. when the user changes the value, the link is shown/hidden only after a `cache-rebuild`.

Now my question:

* Is there a better/more elegant approach to do this? (I could not find any)
* If not, can I use some hook to add my custom cache tag to the menu-link? (the view itself already has this cache tag, but the provided menu link does not respond to it)
* Is it "better" to make a view-block instead of view-page, using a hook to add the custom cache tag to the block and add the block to the menu via \*.links.menu.yml to have more control over the behavior?

# Answer
> 1 votes
You can try to add the custom cache tag to the access result:

```
return AccessResult::allowed()->addCacheTags(['custom_cache_tag']);
return AccessResult::forbidden()->addCacheTags(['custom_cache_tag']);

```

---
Tags: 8, routes, navigation, caching
---


title: Hook or event before a page gets cached

text:
# Question
Title: Hook or event before a page gets cached
Is there a hook or event I can tie into before a page gets cached. I need a hook/event that I can call so that I can run some logic on the page that is about to be cached to tell Drupal if I want a particular page to actually get cached. This is a very specific use case to the website I'm working on.

# Answer
If you need to decide whenever a page should be cached from Drupal, you need to create a service that implements the `\Drupal\Core\PageCache\ResponsePolicyInterface` interface and it's tagged *page\_cache\_response\_policy*, as described in Flexible page cache policy.

That page shows code that can be used as example. You can also use code that Drupal core actually implements, as example, like the code for the node.page\_cache\_response\_policy.deny\_node\_preview service.

The code implementing the service is quite simple. It becomes more complex basing on the logic you need to apply to decide when a page should be cached.

```
class DenyNodePreview implements ResponsePolicyInterface {

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

  /**
   * Constructs a deny node preview page cache policy.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The current route match.
   */
  public function __construct(RouteMatchInterface $route_match) {
    $this->routeMatch = $route_match;
  }

  /**
   * {@inheritdoc}
   */
  public function check(Response $response, Request $request) {
    if ($this->routeMatch
      ->getRouteName() === 'entity.node.preview') {
      return static::DENY;
    }
  }

}

```
> 2 votes

---
Tags: hooks, caching, event-subscribers
---


# Question
Title: How to "disable" certain paragraph types?
I am not sure if this is possible or not (which is why I have come to you fine folks), but I have searched for this and still haven't found an answer...

Is it possible to just "disable" paragraph types in a D8 site instead of deleting them? I know you can "disable" content types in D8 and D7, but I just want to disable some of the paragraph types that we have on our customer's sites without completely deleting them in case the need for them happens to come up from individual customers.

When I go to the full list of paragraph types, the only options that I'm given are:

* Manage Fields
* Manage Form
* Manage Form Display
* Manage Display
* Edit
* Delete

So, any help with this would be greatly appreciated, even if it's just to say, 'nope. not possible.' :)

Thank You! Nicole

# Answer
Sure this is. Per field. So let's say you have a "Paragraphs" field (field\_paragraphs in the screenshot below) in the "Article" content type. Then you edit this field and there you have to select which paragraph types you want to include or exclude.
> 3 votes

---
Tags: paragraphs
---


# Question
Title: select list in webform containing the list of node titles
how can we create a select list in webform containing the list of node titles of specific content type.

I have a product content type through which I have added several product nodes. Now I want to create an inquiry form which should allow the visitors to select the \*products from the select list about which they want to send inquiry.

\*the products in the select list will be the product node titles.

# Answer
Check out https://groups.drupal.org/node/71588 for providing dynamic select options to the webform module. You'll have to specify the content type, but here's a query that can be used to populate it (replace product with the machine name of the content type):

```
SELECT nid, title FROM {node} WHERE type = 'product' AND status = 1 ORDER BY title ASC

```
> 5 votes

# Answer
Webform Views Select is designed for this.

> This module will let you populate a webform select component with data from a view.
> 0 votes

# Answer
Webform References is another option for this.

> Provides a webform component that can reference a node/term/user in webform. It provides "Select List", "Autocomplete", "Checkbox" and "Radio" as widget.

A view with entityreference display can also be used to get the list as options.
> 0 votes

---
Tags: webforms, entities
---


# Question
Title: How on node forms do I set multiple vertical tabs to be always open?
How can I make sure that the `Menu Settings` part when editing a node is always open just like the published section. See the image below.

# Answer
You can do this with the `hook_form_node_form_alter`. Add the following to a custom module.

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function YourCustomModuleNAme_form_node_form_alter(&$form, FormStateInterface $form_state){
  //- MENU SETTINGS
  $form["menu"]['#open']                 = TRUE;
  //- COMMENT SETTINGS
  $form["comment"]["widget"][0]['#open'] = TRUE;
}

```

Change the value of #open to true to show the menu as openend.

In some cases it is necessary to move this hook implementation to the end of the list. Because the menu group added by menu\_ui Module can overwrite your settings to #open false again. For this you can use the following:

```
/**
 * Implements hook_module_implements_alter().
 */
function YourCustomModuleNAme_module_implements_alter(&$implementations, $hook){
  switch ($hook) {
    // Move our hook_form_FORM_ID_alter() implementation to the end of the list.
    case 'form_alter':
      $group = $implementations['YourCustomModuleNAme'];
      unset($implementations['YourCustomModuleNAme']);
      $implementations['YourCustomModuleNAme'] = $group;
      break;
  }
}

```
> 1 votes

---
Tags: 8, forms
---


title: How to append an HTML tag to a field?

text:
# Question
Title: How to append an HTML tag to a field?
On the basic page content type, we have a paragraph field that is set to `Plain Text with Link field` and below are the paragraph type's fields.

How to append a `<a>` to the field so that it is displayed right at the end of the field?

**Fields:**

1. Description `(type = text (formatted, long))`
2. Link `(type = link)`

**Current**

Twig template:

```
{{ content.field_description }}
{{ content.field_link }}

```

Sample output:

```
<p>Dramatically create 24/7 paradigms via ubiquitous information. </p>
<a href="some/path/">Read More</a>

```

**Goal**

Twig Template:

```
{{ content.field_description }}

```

Desired Output:

```
<p>Dramatically create 24/7 paradigms via ubiquitous information. <a href="some/path/">Read More</a></p>

```

What we tried and got stuck. When we tried to print the `$pr_description` field using `ksm()`, we could not find a method or array where we could append the link to:

**mytheme.theme**

```
function mytheme_preprocess_paragraph__plain_text(&$variables) {
  $pr_plain = $variables['elements']['#paragraph'];
  if(!$pr_plain->get('field_link')->isEmpty()) {
    $pr_link_field = $pr_plain->get('field_link')->first();
    $pr_link_uri = $pr_link_field->uri;
    $pr_link_title = $pr_link_field->title;

    $pr_description = $pr_plain->get('field_description');
    ksm($pr_description); // this did not provide method or array such as `#suffix`
  }
}

```

# Answer
You are using "Text formatted" for your description field, so the `<p>` tag is most likely part of the field value (an editor also could enter `<table><tr><td>Dramatically create 24/7 paradigms via ubiquitous information. </td></tr></table>` in that field). It will be much easier to achieve your desired output if you change the description field to plaintext or unformatted long.
> 1 votes

---
Tags: 8, theming, hooks, paragraphs
---


# Question
Title: Issue with "Content: Has taxonomy terms (with depth)" with a content type with a repeated taxonomy
I have and issue with the view filter "Content: Has taxonomy terms (with depth)". In my view I'm filtering a content type who as two fields represented by the same taxonomy, and that view filter (Content: Has taxonomy terms (with depth)), do the filter of the union of all the values in the two fields of the same taxonomy. For example:

---

Taxonomy "Subjects":

deparment1

* subject11
* subject12
* ...
* subject1n

deparment2

* subject21
* subject22
* ...
* subject2n

deparment3

* subject31
* subject32
* ...
* subject3n

---

Custom type: **Annual enrollment**

Fields:

...

Subjects enrolled on first period (reference to term Subjects and multivalue)

Subjects enrolled on second period (reference to term Subjects and multivalue)

...

---

View: Filter for enrollments

...

Content: Has taxonomy terms (with depth)(exposed)

...

---

For example, in this case, that filter (associated with a Taxonomy and not a content type field) will filter the results for the departments in both subjects enrolled on first and second period, and what I want is that the filter only affects one field (in my real case, I need two of these filters, one for each field).

# Answer
> 1 votes
My problem was that the view filter *Content: Has taxonomy terms (with depth)* search in the `taxonomy_index` table instead of a field of the content type, so I ended duplicating the *Simple hierarchical select module* (SHS) who's behavior is equal to the *Content: Has taxonomy terms (with depth)*, and editing the query it does.

# Answer
> 0 votes
I have the same problem: a "person" content type with two taxonomy term fields (place of birth and place of residence) related to the same vocabulary (provinces and towns), rendered through Simple Hierarchical Select.

I don't understand how you solved it, how you set the view to filter "Content: Has taxonomy terms (with depth)" just with one taxonomy field.

Thank you

---
Tags: 7, taxonomy-terms
---


title: How do I stop the node from caching

text:
# Question
Title: How do I stop the node from caching
Sometimes when I run below code in the `hook_preprocess_menu()` of a node, I am getting a previously loaded node instead of my current node.

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

```

What should I do to stop this?

# Answer
If you add node data in a preprocess hook, then you need to add the cache tag of the node:

```
$variables['node_title'] = [
  '#markup' => $node->getTitle(),
  '#cache' => [
    'tags' => $node->getCacheTags(),
  ],
];

```

If this node is from a route match, then you need to add a cache context for the route as well:

```
$node = \Drupal::routeMatch()->getParameter('node');
$variables['node_title'] = [
  '#markup' => $node->getTitle(),
  '#cache' => [
    'tags' => $node->getCacheTags(),
    'contexts' => ['route'],
  ],
];

```
> 1 votes

---
Tags: 8, nodes
---


# Question
Title: Keep getting "Bad request" messages in browser after adding JS
I have added this script in my Drupal 7 site to make the site remember the last clicked Quicktab and then open that tab on page reload:

```
// JavaScript Document
(function($) {

    Drupal.behaviors.quicktabsTabMemory = {
      attach: function(context, settings) {
        // The .each() is in case there is more than one quicktab on a page.
        $('.quicktabs-wrapper', context).each(function () {

          var $this = $(this);
          var wrapperID = $this.attr('id');

                var nid = settings.nordtec_klister['currentNid']; // getting the nid on the client side

          var $activeTabLink = $('.quicktabs-tabs li.active a', context);
          var activeTabLinkID = $activeTabLink.attr('id');

          // Use a unique cookie namespace for each set of Quicktabs, which
          // should allow for more than one set on a page.
          var cookieName = 'Drupal-quicktabs-active-tab-id-' + wrapperID + 'nid='+ nid;
          // Default cookie options.
          var cookieOptions = {path: '/'};

          // Click the tab ID if a cookie exists otherwise set a cookie for
          // the default active tab.
          var $cookieValue = $.cookie(cookieName);
          if ($cookieValue) {
            $('#' + $cookieValue).click();
          }
          else {
            $.cookie(cookieName, activeTabLinkID, cookieOptions);
          }

          // Set the click handler for all tabs, this updates the cookie on every
          // tab click.
          $this.find('ul.quicktabs-tabs a').click(function quicktabsCookieClickHandler() {
            $activeTabLink = $this.find('.quicktabs-tabs li.active a', context);
            activeTabLinkID = $activeTabLink.attr('id');
            $.cookie(cookieName, activeTabLinkID, cookieOptions);
          });
        });
      }
    };

})(jQuery);

```

This works as a charm, BUT ever since I added this I keep getting this message in the browser (Chrome)...

**Bad Request** Your browser sent a request that this server could not understand. Size of a request header field exceeds server limit.

...after maybe 1 or 2 working days of browsing the site, adding and editing content (many tabs open with different pages etc). I can only assume that it's not a coincidence that those error messages began to show soon after I added this script.

So my question is: What should I do in order to avoid those messages? Clear out all cookies after a certain time? I have tried to limit the cookie life time to 28800 seconds and also the garbage collector life time to that same value in settings.php:

```
ini_set('session.gc_maxlifetime', 28800);
ini_set('session.cookie_lifetime', 28800);

```

This helped some, the messages does not occur as often after this, but they do still happen once a week or so.

# Answer
> 1 votes
Finally found the solution to my problem, in case anyone else makes the same mistake.

The problem with my cookie is this line from the code above:

```
var cookieName = 'Drupal-quicktabs-active-tab-id-' + wrapperID + 'nid='+ nid;

```

Cookie names cannot contain equal characters (or spaces, commas, semi-colons etc). That will create errors. So i simply changed "=" to "-" in my code line above, and the errors went away.

---
Tags: 7, javascript, cookies
---


# Question
Title: How can I remove allowed values of a list field?
I set up a *List (Text)* select list field in a paragraph bundle. I set some values to test. I want to remove them (so I can populate them programmatically) and I deleted the content using the fields, but I still get this message.

> Allowed values list: some values are being removed while currently in use

These values are not used. I did use them to test, but I deleted them after testing.

How can I remove those values?

# Answer
> 1 votes
Have you got revisioning on for your content types? If so then those revisions will still be using the paragraph. You'll need to delete the revisions too before you can make the change

---
Tags: 7, paragraphs
---


# Question
Title: Weird redirect on taxonomy term edit page
When I try to edit taxonomy terms, or delete them, and I click on edit/delete, it redirects me to that term page instead.

I also have Devel module installed, and when I choose that option in the drop-down menu, it works.

I have tried almost everything.

* URLs are OK; if I inspect the edit/delete buttons, the URL is the expected one. When it redirects me, that URL remains in the browser.
* I thought it was a Drupal core issue. At the time I was using Drupal 8.5.3, but I am still having the problem after updating to Drupal 8.5.5.
* I have removed all my custom modules/theme files (to check if it were my fault).
* I changed the administrative theme from the Seven theme to the Bartik theme.
* I cleared the cache and ran update.php several times.

The problem still remains, and I'm still not sure if it's an issue I have somehow caused, or it's a Drupal core issue.

Did anyone have a similar problem, or know what would be the problem?

# Answer
> 1 votes
Did you try to edit Taxonomy Term view `/admin/structure/views/view/taxonomy_term` I'm having issues with editing / deleting / translating taxonomy terms because I've edited `taxonomy_term` view. Disable `taxonomy_term` view and edit/delete should work.

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


title: Add result to view with webservice

text:
# Question
Title: Add result to view with webservice
In my drupal 8 Commerce, I have a view with product and filter criteria.

And I want to know, if it's possible to add result to this view with a result of webservice.

I try to inspect `$view->result in hook_views_pre_render`

and the result is `view\ResultRow` with `entity Product`

Is it possible to add results without creating an entity and from an webservice just read information like this schema:

**/myviewurl**

* Product 1 (from drupal db)
* Product 2 (from drupal db)
* Product 3 (from drupal db)
* Product 4 (from webservice not in db)
* Product 5 (from webservice not in db)
* Product 6 (from webservice not in db)

# Answer
Try **hook\_views\_pre\_render** hook to alter view result if only you need to display result. You just need to prepare the webservice result as per **hook\_views\_pre\_render** result data.
> 0 votes

---
Tags: views, 8, commerce
---


# Question
Title: How to render a form with 2 fields for each line?
I'm looking for a way to render a form with 2 text-fields in to the same (for each) line. I would like to do this using hook functions, so I tried with this:

```
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'form_page_1') {
    $form['#type'] = 'table';
  }
}

```

But obviously it doesn't work. Do you have any idea?

# Answer
Can you just add wrapper to each field with bootstrap classes to both form elements?

```
    $form['field_1_wrapper'] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('col-sm-6')),
    );

     $form['field_1_wrapper']['field_1'] = array(
      '#type' => 'textfield',
      '#title' => t('Field 1'),
    );

    $form['field_2_wrapper'] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('col-sm-6')),
    );

    $form['field_2_wrapper']['field_2'] = array(
        '#type' => 'textfield',
        '#title' => t('Field 2'),
    );

```
> 0 votes

---
Tags: theming, forms
---


# Question
Title: Run callback after Views exposed filter AJAX
I feel like I'm doing something really wrong here. I have a View block which has an exposed filter. Since it is in a block I have to use Ajax. I'm trying to run some JS on the views result but can't get anything to happen when the ajax call completes.

To try and keep this as simple as possible I have created a test.js file with only the following code:

```
(function ($) {
  $(document).ajaxComplete(function (e, xhr, settings) {
    console.log('test');
  });
})(jQuery);

```

I add this with my theme's template.php file but when I filter my view and the results update with ajax, this code does not seem to run. I can't work out why not.

EDIT: I managed to get this to work by moving the code inside my\_view.tpl.php but I'd be keen to know why it doesn't work in an external file.

# Answer
JS events need to be bound when the document is ready. Drupal handles this for you if you use behaviors:

```
(function ($) {
  Drupal.behaviors.myModule = {
    attach: function(context, settings) {
      $(document).once('mymodule-ajax').ajaxComplete(function (e, xhr, settings) {
      // ...
      });
    }
  }
})(jQuery);

```
> 4 votes

# Answer
I was trying to execute javascript after Ajax Views load content. Using Drupal 8.5 and Better Exposed Filter contrib module I did :

```
(function($, Drupal, drupalSettings) {

  Drupal.behaviors.myModuleScript = {

    attach: function(context, settings) {
      // Attach action to Drupal Ajax Views event
      $(document).once('weberAjaxViews').ajaxSuccess(function (event, data) {
        if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {

          var ajaxViews = drupalSettings.views.ajaxViews;
          Object.keys(ajaxViews || {}).forEach(function (i) {
            if (ajaxViews[i]['view_name'] == 'your_view_name' &&  ajaxViews[i]['view_display_id'] == 'your_view_display_name') {
              // Do some JS here
            }
          });

        }
      });
    }

  };

})(jQuery, Drupal, drupalSettings);

```

I have been using ajaxSuccess instead of ajaxComplete so my code does not get executed when the Ajax call throws an Error.
> 3 votes

# Answer
Have a look at my answer on another question that uses the betterExposedFilter module.
> 0 votes

---
Tags: ajax, views
---


title: Get the form ID from a Webform entity

text:
# Question
Title: Get the form ID from a Webform entity
I need to output the form id of a webform entity. I load a chunk of enabled webforms directly from the database by using

```
\Drupal::entityTypeManager()->getStorage('webform')->loadMultiple();

```

Afterwards I have to output the form\_id's of the webform entities.

How to achieve this? I cannot see any "form\_id" stored in the returned entity object.

UPDATE:

I can use the following script to receive a static version of the form id:

```
$target_form_id = str_replace('email_confirm_redirect_2_', '', $entity->getSubmissionForm()['#form_id']);

```

Still not really professional

# Answer
> 6 votes
Rather than storing the form ID, you could just store the webform ID and check that in a form alter. Webform provides its own form alter hook that only fires for webforms and lets you put the hook in a dedicated include file.

See `honeypot_webform_submission_form_alter()` in `third_party_settings/webform.honeypot.inc` for an example of getting the webform from the hook:

```
/**
 * Implements hook_webform_submission_form_alter().
 */
function honeypot_webform_submission_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // <snip>

  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
  $webform_submission = $form_state->getFormObject()->getEntity();
  $webform = $webform_submission->getWebform();

```

From there you can use `$webform->id()` to get the webform ID.

---
Tags: 8, webforms
---


# Question
Title: How to create conditional checkboxes that hide each other?
I have 2 check-boxes.

* Checkbox 1: Attend event for 1 day
* Checkbox 2: Attend event for 2 days

If a checkbox is selected, I want to hide the other one. I don't want the user to be able to select both. If I create 2 rules, I get a *circular reference* error which breaks the form.

How do I achieve what I described?

# Answer
> 3 votes
Simple solution: Don't use 2 fields with checkboxes, use one field with radio buttons.

# Answer
> 0 votes
If you really need 2 checkboxes instead of a radio button, do the following: example with 2 checkboxes (Day1 and Day2).

For checkbox Day1 chose the following under Edit-Conditions

For checkbox Day2 do the same just vice versa.

---
Tags: webforms
---


# Question
Title: Inline entity form shows a content type select list
I am using Inline entity form for a non-commerce project. The settings are:Widget:multiple values,Node:Allow users to add existing content. Mode:Views:Filter by Entity reference view.So I have created an Entity reference view to show only nodes that have been created by the user. The issue is:When looking at the Inline entity form to create or add existing content,there is a dropdown with all the content types of the site.This only appeared when I change the mode to Views:Filter by Entity reference view How can I remove that? thanks See image attached

# Answer
> 0 votes
Try editing the inline entity field and only setting one entity (ie Company content type in your example) that can be referenced.

# Answer
> 0 votes
I managed to solve this by making changes to inline\_entity\_form.module specifically the inline\_entity\_form\_settings function. This fix requires you to have already selected the target bundle in the ief tables module and limits to only one content type (I'm sure someone can easily adapt this logic to include multiple by adding a separate settings option).

After the line

```
 // Allow other modules to alter the settings.
drupal_alter('inline_entity_form_settings', $settings, $field, $instance);

```

add in the following code:

```
if (empty($settings['bundles']) && isset($instance['widget']['settings']['type_settings']['ief_table_view_mode']['bundles'])) {
    if (array_search('1', $instance['widget']['settings']['type_settings']['ief_table_view_mode']['bundles']) != false) {
        $settings['bundles'][] = array_search('1', $instance['widget']['settings']['type_settings']['ief_table_view_mode']['bundles']);
    }
}

```

---
Tags: entities
---


# Question
Title: Unable to change the author of content using views/action
I want to change the author of multiple nodes. I have set up a new action by going to /admin/config/system/actions and then selecting "CREATE AN ADVANCED ACTION" and then "Change the author of content..."

In my view of the content type I have added the "Node operations bulk form" field.

My problem is that when I try to update any content using this method I get the error "No access to execute Change the author on the Content \[TITLE\]'. The user has a role giving permission to edit the content.

I have looked at the code that generates this error - it is in core/modules/system/src/Plugin/views/field/BulkForm.php

```
        // Skip execution if the user did not have access.
    if (!$action->getPlugin()->access($entity, $this->view->getUser())) {
      $this->drupalSetMessage($this->t('No access to execute %action on the @entity_type_label %entity_label.', [
        '%action' => $action->label(),
        '@entity_type_label' => $entity->getEntityType()->getLabel(),
        '%entity_label' => $entity->label()
      ]), 'error');
      continue;
    }

```

Anyone any idea what I can do to get this to work? I need to change the author of thousands of nodes, so I need to work this out.

# Answer
I just created a module for this, which allows you to change the Author as a batch operation on /admin/content, with a custom selection step to pick the new author.

Module: change\_author\_action
> 1 votes

---
Tags: views, 8, actions
---


# Question
Title: Why would my /admin/reports/dblog get "stuck" on only showing "page not found" errors?
Edit #2: Ok, I finally logged out of my admin account, restarted the browser, then logged back in. Presto! Works. Now that I've thoroughly embarrassed myself, I'll just bow out and go hide underneath a rock.

Edit: Ok, looks like my question wasn't specific enough - sorry! Let's see if I can word this better. Thanks for your patience and to the people who've already taken a swipe at answering this.

I'm having a problem where, no matter what type I select, /admin/reports/dblog refuses to show any results other than for "page not found" entries. As soon as I hit the "Filter" button, it reverts back to the "page not found" results list.

I've tried clearing caches, rebooting Apache, running update.php ... nothing makes a difference. If I try "Clear Log Messages," I get an error screen saying "The website encountered an unexpected error. Please try again later," which is a remarkably unhelpful message. Any thoughts? Thanks!

I haven't added any new modules recently and the dblog results were working fine up until yesterday afternoon. I had made no changes to the site near that time.

I'm not receiving an Error 500 as far as I can tell, as was suggested; it's a generic error message that appears to be one of Drupal's canned messages. If that's not the case, my bad!

# Answer
> 1 votes
Try having a look in your server error\_log file that will probably tell you what's causing the problem. My guess is an unsupported character or something has been recorded in a log message.

You could just try clearing the actual log table in the database. Looks like you're on drupal 7 so you'd want to truncate the watchdog table to remove all logged errors

---
Tags: log-messages
---


title: What is the "default revision"?

text:
# Question
Title: What is the "default revision"?
I'm using the Workflow module in Drupal 8 and I saw this checkbox on the "add a state" screen (/admin/config/workflow/workflows/manage/help/add\_state):

> **Default revision** When content reaches this state it should be made the default revision; this is implied for published states.

What exactly is meant here by "default revision"? Why is it implied for published states?

# Answer
So that means it will become the active revision shown to users. So if a revision is published its got to become the default revision as it will be shown as the page content for normal users

When you select "Archived" for a piece of content you'd want that to become the default revision too so that when users look at the page they'd see access denied. But you wouldn't have the published option ticked for "Archived"

And draft you wouldnt want to become the default revision because it's not supposed to be shown to users in that state
> 6 votes

---
Tags: 8, workflows
---


title: Views random 1 image after refresh

text:
# Question
Title: Views random 1 image after refresh
I'm trying to use Views to randomly display an image(or node) from a content type. So everytime(or every 10secs) a user refresh their browser a new random image should display.

Here is my setting in Views. I added "Global: Random(asc)" in Sort Criteria, 1 item on Pager, and "Never Cache" Query results "10"seconds Rendered output on Caching setting.
**However, the page does not render a new image after 10sec browser refresh for Anonymous user, but any login user.**

### **====== Update June 22, 2015 at 12:26pm ======**

**optional solution:**
* exclude cache on specific page by using CacheExclude module
* still looking for solution to exclude cache on specific views(and view block) for anonymous users. **Update:** Found a solution for Views by using Views Random. This module allow user to enables cached views results randomly.

# Answer
> 2 votes
Pages are cached for anonymous users. Views obtains random image every time it has it's chance to work, but for anonymous your cache time is probably significantly longer.

All you have to do is to disable cache on the page you have this view on. How depends on the cache system you are using.

# Answer
> 1 votes
In the view, expand advance, locate **Caching**, set it to none

---
Tags: 7, views
---


# Question
Title: Hide columns depending on checkbox state with Javascript
I have a form with a fieldset where I created a simple checkbox:

```
$form['my_fieldset']['my_checkbox'] = array(
    '#type' => 'checkbox',
    '#title' => t('my title'),
    '#default_value' => 1,
    '#disabled' => FALSE,
);

```

Then, in other fieldset, I have a tableselect with these columns:

* slot1
* slot2
* slot3

The data for these columns is as below:

```
'slot1' => array(
    'data'=> array(
        '#type' => 'select',
        '#title' => 'Slot1',
        '#title_display'=> 'invisible',
        '#default_value'=> '',
        '#value' => 'slot1',
        '#options' => $my_options,
        '#name' => 'slot1',
        '#attributes' => array('class' => array('update-slot1')),
    ),
),
'slot2' => array(
    'data'=> array(
        '#type' => 'select',
        '#title' => 'Slot2',
        '#title_display'=> 'invisible',
        '#default_value'=> '',
        '#value' => $emulator_data['slot2'],
        '#options' => $cards_available,
        '#name' => 'slot2[' . $emulator_data['container'] . ']',
        '#attributes' => array('class' => array('update-slot2')),
    ),
),
'config' => array(
    'data'=> array(
        '#type' => 'select',
        '#title' => 'config title',
        '#title_display'=> 'invisible',
        '#default_value'=> '',
        '#value' => 'config',
        '#options' => $my_options,
        '#name' => 'config',
        '#attributes' => array('class' => array('update-config')),
    ),
),

```

What I need is to hide 'slot1' and 'slot2' columns if the checkbox is checked and hide the 'config' column if it's unchecked, using javascript.

# Answer
`#states` is a good JavaScript only approach to hiding simple markup, but sometimes we need to modify the render array itself

To add/remove form elements or complex render arrays based on feedback, you can do so by checking the value of `$form_state['values']['my_fieldset']['my_checkbox']` in a condition around your table column logic. Also wrap the other\_fieldset with a div defined in #prefix and #suffix that has that wrapper id.

```
if (isset($form_state['values']) && $form_state['values']['my_fieldset']['my_checkbox']) {
  // Add slot1/slot2 columns here.
}

```

Then add an AJAX/AHAH to the checkbox element:

```
$form['my_fieldset']['my_checkbox'] = array(
    '#type' => 'checkbox',
    '#title' => t('my title'),
    '#default_value' => 1,
    '#disabled' => FALSE,
    '#ajax' => array(
      'callback' => 'my_module_form_ajax_callback',
      'wrapper' => 'other-fieldset-id-wrapper',
      'method' => 'replace',
      'effect' => 'slide',
    ),
);

```

Then implement a function to return the form element you want to replace. Note that you do *not* modify the form/form\_state here and modifying the form will have no effect. However the value of the checkbox will be stored in form\_state values when the form is re-rendered.

```
  function my_module_form_ajax_callback($form, $form_state) {
    return $form['other_fieldset'];
  }

```
> 1 votes

---
Tags: javascript
---


# Question
Title: Converting JavaScript from Drupal 7 to Drupal 8 standards
I have a Drupal 7 module that contains a JavaScript file whose only contents are

```
Drupal.behaviors.InitializeMapplic = {
  attach: function (context, settings) {
    jQuery("#mapplic").mapplic(Drupal.settings.mapplic);
  }
};

```

I'm aware that Drupal 8 introduced a new JavaScript API and that this code needs to be updated. However, I'm confused as to what the Drupal 8 equivalent is. I have read and tried to dissect the change records at https://www.drupal.org/node/1793334 and I have reviewed the API documentation at https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview.

So my question is, exactly what needs to change here in order for this to play ball with Drupal 8? Will it just become

```
jQuery("#mapplic").mapplic(drupalSettings.mapplic);

```

all by itself or what? Any light that can be shed on this for me would be appreciated.

# Answer
> 0 votes
As you already linked from the docs https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview I just repeat the most important parts here:

**MYMODULE.libraries.yml**

```
foobar:
  js:
    js/foobar.js: {}
  dependencies:
    - core/jquery
    - core/jquery.once
    - core/drupal
    - core/drupalSettings

```

**js/foobar.js**

```
(function ($, Drupal) {
  Drupal.behaviors.myModuleBehavior = {
    attach: function (context, settings) {
      $('.MYSELECTOR', context).once('myCustomBehavior').each(function () {
        // Apply the myCustomBehaviour effect to the elements only once.

        // I guess you have to pass something to `settings` first.
        // $("#mapplic").mapplic(settings.mapplic);

        console.log('Hello world!');
      });
    }
  };
})(jQuery, Drupal);

```

**MYMODULE.module**

```
function MYMODULE_page_attachments_alter(array &$attachments) {
  $attachments['#attached']['library'][] =  'MYMODULE/foobar';
}

```

---

Update: removed some flaws.

---
Tags: 8, javascript, migrations
---


# Question
Title: CKEditor configured MediaEmbed button doesn't appear in toolbar
I have updated my CKEditor profiles to display the MediaEmbed button. The profile is saved, but when editing content, the button doesn't appear in my toolbar.
I'm using CKEditor 4.4, oEmbed plugin 1.17, jQuery 1.10 and the latest version of the CKEditor module.

Here's a screenshot of the config:

And another screenshot of the actual toolbar:

Any idea why?

# Answer
I managed to resolve my problem but didn't have time to post it in here. It was simply misconfiguration...

First you need to install Widget, Lineutils and oEmbed plugins in CKEditor's plugin folder.
Then you need to specify the path to the plugins folder in CKEditor's module configuration.
Finally, in each of CKEditor's profile, you need to enable the plugins and move the oEmbed icon to the profile's toolbar.
Clear Drupal and browser cache and it should be working.

That's it!
> 1 votes

# Answer
All you have to do is: go to Configuration-\>Content Authoring-\>Ckeditor-\>click on ***Edit*** in *Advanced* or *Full* mode tick the check box of Plugin for embedding HTML snippets and that's it
> 0 votes

---
Tags: 7, wysiwyg
---


# Question
Title: How do I change priority of two different implementations of hook_node_access()?
I am using the *Node View Permissions* module, which implements `hook_node_access()`. I am also using a custom module (mymodule.module) which is implementing the same hook. `node_view_permissions_node_access()` is always invoked after `mymodule_node_access()`.

How can I change the hook invocation order? `mymodule_node_access()` should be executed after `node_view_permissions_node_access()`.

# Answer
> 5 votes
Use `hook_module_implements_alter()`:

> This hook is invoked during module\_implements(). A module may implement this hook in order to reorder the implementing modules, which are otherwise ordered by the module's system weight.

Example:

```
function MYMODULE_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'node_access') {
    // Move your module's implementation to the end of the list
    $group = $implementations['MYMODULE'];
    unset($implementations['MYMODULE']);
    $implementations['MYMODULE'] = $group;
  }
}

```

In the possible event that another module also implements `hook_module_implements_alter` to move its own implementation of `hook_node_access` to the end of the list, you can get cunning and make sure your implementation of the alter hook runs last too:

```
  if ($hook == 'node_access' || $hook == 'module_implements_alter') {
    // Move your module's implementation to the end of the list
    $group = $implementations['MYMODULE'];
    unset($implementations['MYMODULE']);
    $implementations['MYMODULE'] = $group;
  }

```

---
Tags: hooks
---


# Question
Title: How to load JS as the first item in head tag?
We have a custom module that has a JS library that we want to load in the `<head>` tag as the very first item even before all the normal Drupal JS files. All other libraries are loaded through `mytheme.libraries.yml`.

How can I load the library (`mymodule/myscript`) so that it loads as the first `<script>` tag in the `<head>`?

What we tried:

### mymodule.module

```
function  mymodule_page_attachments(array &$page) {
  $attachments['#attached']['library'][] = 'mymodule/myscript';
}

```

### mymodule.libraries.yml

```
myscript:
  version: 1.x
  header: true
  js:
    /path/to/file: { external: true, weight: -200 }

```

Current problem:

```
<head>
  <script>script1</script>
  <script>script2</script>
  <script>myscript is loaded here</script>
</head>

```

Goal:

```
<head>
  <script>myscript is loaded here</script>
  <script>script1</script>
  <script>script2</script>
</head>

```

# Answer
Using @Manav's link, i was able to get to this solution that worked.

```
function mymodule_page_attachments(&$attachments) {
  $custom_script = [
    '#type' => 'html_tag',
    '#tag' => 'script',
    '#attributes' => [
      'src' => 'path/to/file.js',
    ],
    '#weight' => -200, // this allowed me to do what i needed
  ];

  $attachments['#attached']['html_head'][] = [$custom_script, 'custom_script_key'];
}

```
> 4 votes

---
Tags: 8, theming, javascript
---


# Question
Title: query to retrieve all translations and nodes of a language that has been removed from the system?
I am experiencing an issue after a language has been removed from the system. Every time I go on the admin/content page on a drupal 8 site I get:

```
Error: Call to a member function getId() on null in Drupal\Core\Entity\Entity\EntityViewDisplay->buildMultiple() (line 254 of core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php).

```

This is a known issue on drupal.org but it has not been addressed yet. I am afraid this may be a recurring issue and I am trying to build something to clean up content causing the issue (i.e. the content language was removed from the system).

I am looking for a Drupal query that would return all the nodes(entities)/translations which has a language that has been deleted from the system. I can load all content and loop through them to check `$entity->language() == FALSE` or `$entity->language() == NULL` but that does not seem to be performant even with using the batch API. Ideally, db query that returns the IDs of the offending content would be much better. Then I could update them to language neutral or delete the content.

I am wrote something that does something similar to the way node update translations after a language is deleted:

```
  /**
   * {@inheritdoc}
   */
  public function clearRevisionsLanguage(LanguageInterface $language) {
    return $this->database->update('node_revision')
      ->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED])
      ->condition('langcode', $language->getId())
      ->execute();
  }

```

I repurposed the above to:

```
function some_helper_to_update_node_lang($lang_code) {
  \Drupal::database()->update('node_revision')
    ->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED])
    ->condition('langcode', $lang_code)
    ->execute();
}

```

But the above function requires the language code, which is reasonable but I am not sure how to make this a more flexible in as much to return all content that has a removed language.

# Answer
> 2 votes
I ended executing this function to clean up the content:

```
function delete_non_existing_language_content() {
  // 1. Get enabled languages
  $languages = \Drupal::languageManager()->getLanguages();
  $lang_codes = array();
  foreach ($languages as $language) {
    $lang_codes[] = $language->getId();
  }
  // 2. Get all the nodes that have langcode not in the language list.
  $result = \Drupal::database()->select('node_field_data')
    ->fields('node_field_data')
    ->condition('langcode', $lang_codes, 'NOT IN')
    ->execute();

  // @todo think I can use fetchAllKeyed instead?
  $nids = array_keys($result->fetchAllAssoc('nid'));

  // 3.Delete all of them:
  // @todo Or possibly update them to language neutral code if possible:
  $storage_handler = \Drupal::entityTypeManager()->getStorage('node');
  $entities = $storage_handler->loadMultiple($nids);
  $storage_handler->delete($entities);

}

```

This worked for my use case, but I don't think it will be performant for large databases.

---
Tags: database, i18n-l10n
---


# Question
Title: Is a session alone enough for non logged-in users to see some information?
In my project I have a content type called *Person* that is only viewable or editable by logged-in user. In this content type, I added some fields.

I want to give a person the ability to visit his profile. So I made a module called `anonymous_profile` with the following code.

```
function anonymous_profile_menu() {
    $items = array();
    $items['anonymous-profile-login'] = array(
        'title' => t('Login'),
        'page callback' => 'drupal_get_form',
        'page arguments' => array('anonymous_profile_login_form'),
        'access arguments' => array('access anonymous person login'),
        'type' => MENU_NORMAL_ITEM,
    );

    $items['anonymous-profile'] = array(
        'title' => t('Anonymous Visit'),
        'page callback' => 'anonymous_visit_page',
        'access arguments' => array('access anonymous person login'),
    );

    $items['anonymous-profile-logout'] = array(
        'title' => t(''),
        'page callback' => 'anonymous_logout',
        'access arguments' => array('access anonymous person login'),
    );
    return $items;
}

```

*anonymous-profile-login* creates a form where users insert information in order to log in on the *anonymous-profile* page. *anonymous-profile-logout* is the logout page.

```
function anonymous_profile_permission() {
    return array(
        'access anonymous person login' => array(
            'title' => t('access anonymous person login'),
            'description' => t('Anonymous person login form to view profile page.'),
        ),
    );
}

```

This is the form object that is returned to *anonymous-profile-login*.

```
function anonymous_profile_login_form() {
    $form['field_national_id'] = array(
        '#type' => 'textfield',
        '#title' => t('National ID'),
        '#size' => 10,
        '#maxlength' => 20,
        '#required' => TRUE,
        '#description' => t('Please insert your national id'),
    );

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

    return $form;
}

```

This is the form submission handler.

```
function anonymous_profile_login_form_submit($form, &$form_state) {
    $national_id = $form_state['values']['field_national_id'];

    $login_result = false;
    if ($national_id == '123456') { //this is for test.in real , inserted national id must be searched in database...

        $login_result = true;
    }

    if ($login_result) {
        drupal_set_message('Login is ok');
        $_SESSION['anonymous_logged_user'] = $national_id ;
        drupal_goto("anonymous-profile");
    } else {
        drupal_set_message('Invalid login information', 'error');
    }
}

```

This is the logout page.

```
function anonymous_logout() {
    if (isset($_SESSION['anonymous_logged_user']))
        unset($_SESSION['anonymous_logged_user']);
    drupal_goto('anonymous-profile-login');
}

```

In `anonymous_visit_page()`, first I check the session *anonymous\_logged\_user*; if it is OK, I show the information to the user.

```
function anonymous_visit_page() {
    if (isset($_SESSION['anonymous_logged_user'])) {
        if ($_SESSION['anonymous_logged_user'] > 0) {

            $national_id = $_SESSION['anonymous_logged_user'];
            // load information from database bases on $national_id and print rendered html output.

        }
    }
    //--------------------------
    //visitor is not logged via form
    drupal_set_message('You must loggin in order to see your profile', 'error');
    drupal_goto('anonymous-profile-login');

}

```

Is this solution safe?
Is a session alone enough for this method, or must I increase the code safety?
Is there any possibility the session is stolen, and users access information without log in via form?

I am using Drupal 7.

# Answer
To answer a couple of questions asked:

* *Extra features to increase safety?* You're tying identification/authorization together here; if I know an ID number then I'm authorized to view details associated with it. A malicious actor can just throw guesses at that field to start pulling data they shouldn't have access to. You should increase your authorization criteria (e.g. ask additional details to prove the user is who they say they are) and make the form more robust against brute-forcing (e.g. limit requests, use other bot-defeating tools, etc.).
* *Can a session be stolen?* Yes. A PHP session is vulernable to session hijacking if you're using unsecure transport. You should enforce an encrypted session so you can rule that out.
> 1 votes

---
Tags: sessions
---


title: 8 - Form Validate Entity Reference

text:
# Question
Title: 8 - Form Validate Entity Reference
I would like to add a form validation to an entity edit form. The entity has an `entity_reference` field on which I would like to perform a manual validation. I have successfully implemented a hook function to access the data entered into the widget, perform the required checks, and raise an error if necessary. The problem is that I do not want to make my function dependent on the widget that is used to alter the `entity_reference` field.

An entity\_reference field with cardinality bigger than 1 (i.e. the ability to store a list of entries) can be edited using, e.g., an Autocomplete, an Autocomplete (Tag Style) or a Select List. The problem is that the data accessible in the validation function will differ depending on what widget is used.

The function `$form_state->getValue('field_name')` returns either

```
Array ( [0] => Array ( [target_id] => 2 ) [1] => Array ( [target_id] => 3 ) )

```

or

```
Array ( [target_id] => Array ( [0] => Array ( [target_id] => 2 ) [1] => Array ( [target_id] => 3 ) ) )

```

For a select\_list or an autocomplete\_tag, respectively.

I could obviously check what the structure of the array is to determine how to handle it, but I'm sure there must be a better way to obtain the data from this array.

My custom validation involves a check to be performed on a relation between the referenced entities and the user, so I do not need to perform any checks on the entered raw data. Basically, I just want to obtain a list of `target_id`'s that I can interact with.

# Answer
The solution was to implement entity-level constraints. This allows Drupal to manage the data that gets typed into the widgets, and no additional (widget-dependent) validation is necessary.

Apparently, the idea in Drupal 8 is that most entity-related validations are not done via the form validations. Instead, so-called constraints can be added, either on the field level to affect only one field, or on the entity level to affect multiple fields.

This GitHub repo contains example files for creating entity-level constraints, which were very helpful. You will need to create files for the Constraint and for its Validator. Furthermore, you will need to attach the Constraint to the Entity, which can be done either using hooks (as demonstrated in the `.module` file, see link above) or by adding this to the annotations of your entity:

```
 *   constraints = {
 *     "ExampleConstraint" = {}
 *   }

```
> 1 votes

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


# Question
Title: Extending an existing Plugin class results in Class not Found PHP Fatal Error
I am trying to create my own Plugin that extends an existing Plugin class. I can extend the base class and everything is fine. However, if I extend a existing Plugin class, I get a `Class not Found` error.

e.g.

```
<?php

namespace Drupal\my_module\Plugin;

use Drupal\contrib_module\Plugin\ClassA;

class MyClass extends ClassA {
  public function implement() {}
}

```

The error I am getting would be
`Class 'Drupal\contrib_module\Plugin\ClassA' not found in /var/www/project/web/modules/custom/my_module/src/Plugin/MyClass.php on line 7`

Any Thoughts guys?

# Answer
There is no D8 commerce\_usps module yet. I found a development version on github, I pressume you're using this one.

The use statement uses the following structure `use [namespace]\[classname]`

So your use statement needs to be

```
use Drupal\commerce_usps\Plugin\Commerce\ShippingMethod\USPS

class ForExample extends USPS { ...

```
> 0 votes

---
Tags: plugins
---


# Question
Title: How can i remove duplicate encoding meta tag
I have repeated `charset` meta tag in all my drupal pages. I have been using my metatag module.

To optimize SEO results, this error is reported as primary to fix.

I have used jquery(ready & load event) to remove from client side, removes in dom element but the page source shows 2 charsets.

No configuration in meta tag refers to charset.

# Answer
If the `<meta charset="utf-8">` tag is appearing twice in the rendered HTML, chances are one of the instances is hard-coded in your theme's html.tpl.php template, while the other is inserted by the metatag module.

I'd recommend checking your theme templates. In some cases, freelancers with little Drupal knowledge may create several page level templates duplicating the head, header, and footer markup too.

As Alfred noted in his comment, removing this tag should be done server side and not via javascript. While it does add a few bytes to download of the page, it does not critically effect search engines from detecting the page's content for indexing.
> 1 votes

---
Tags: 7, meta-tags
---


# Question
Title: Trying to use Replace to change the output of value on a view using custom text
I'm trying to figure out how I can replace `underscores` and a specific text using `Replace` on a Drupal 8 view custom text. In a template, I could use the following code to replace specific text.

```
<span class="tag">{{ items.entity.getType|replace({'_': " ", "2": ""}) }}</span>

```

what can I use on a view on custom text? I tried using `{{ type|replace({'_': " ", "2": ""}) }}` but it seems to show the text as plain text, not HTML markup.

>

# Answer
> 1 votes
have you try to use *Rewrite results* in views field settings? In *Rewrite results* there is an option *Override the output of this field with custom text* if you click on it it will let you change the output of this field to whatever you want. plus there will be a *Replacement patterns* option which will show you a list of replacement tokens. also you can add some HTML if you want/need to.

---
Tags: views
---


# Question
Title: How to set root of programmatically rendered menu
I'm currently attempting to create a plugin where the user can choose what level of a menu to render regardless of what page they're on. I'm generating the form where the user can select the menu level here

```
public function blockForm($form, FormStateInterface $form_state) {
    $menu_name = 'main';

    $menu_tree = \Drupal::service('toolbar.menu_tree');

    $parameters = new \Drupal\Core\Menu\MenuTreeParameters();
    $tree       = $menu_tree->load($menu_name, $parameters);

    $manipulators = array(
        array('callable' => 'menu.default_tree_manipulators:checkAccess'),
        array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
        array('callable' => 'toolbar_menu_navigation_links'),
    );

    $tree = $menu_tree->transform($tree, $manipulators);
    $list = ['none' => $this->t('None')];
    foreach ($tree as $item) {
        $list += [$item->link->getPluginId()=> $item->link->getTitle()];
        if ($item->hasChildren) {
            foreach ($item->subtree as $subitem) {
                foreach ($subitem->subtree as $subitem_child) {
                    $list += [$subitem->link->getPluginId() => '-'.$subitem->link->getTitle()];
                    foreach ($subitem->subtree as $sub_subitem) {
                        $list += [$sub_subitem->link->getPluginId()=> '--'.$sub_subitem->link->getTitle()];
                    }
                }
            }
        }
    }

    $form        = [
        'menu'            => [
            '#type'          => 'select',
            '#title'         => $this->t('Top level of menu'),
            '#default_value' => $this->configuration['menu'],
            '#options'       => [
                $list,
            ],
        ],
    ];

    return $form;
}

```

This works, and the user can select the level of the menu they want, but I'm not sure what to use in order to render the menu at that level. I did see that I could get a plugin

```
    $menu_name  = 'main';
    $menu       = $this->configuration['menu'];
    $menu_tree  = \Drupal::service('toolbar.menu_tree');

    $parameters = new \Drupal\Core\Menu\MenuTreeParameters();
    $tree = $menu_tree->load($menu_name, $parameters);

    $manipulators = array(
        array('callable' => 'menu.default_tree_manipulators:checkAccess'),
        array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
        array('callable' => 'toolbar_menu_navigation_links'),
    );

    $tree = $menu_tree->transform($tree, $manipulators);
    foreach ($tree as $item) {
        var_dump($item->hasChildren);
        if ($item->hasChildren) {
            var_dump($item->link->getTitle().' - '.$item->link->getPluginId());
            foreach ($item->subtree as $subitem) {
                var_dump($subitem->link->getTitle().' - '.$subitem->link->getPluginId());
                foreach ($subitem->subtree as $subitem_child) {
                    var_dump($subitem_child->link->getTitle().' - '.$subitem_child->link->getPluginId());
                    var_dump($subitem_child->link->getTitle().' - '.$subitem_child->link);
                }
            }
        }
    }

```

I have the pluginID of the selected in the form, but I'm not sure how to make any use of that. I tried using $parameters-\>setRoot('818bf040-f12a-4915-835f-b9339eb7c828');

Where 818bf040-f12a-4915-835f-b9339eb7c828 in this case was the pluginid of the selected menu item, but that caused the menu to not return anything.

Is there a way to render a menu and set the root to a specified location inside that menu programmatically?

# Answer
My solution was to loop through each menu item and see if its plugin id is the same as the supplied one, and return the menu item as soon as it finds one. (Hopefully plugin ids are not prone to changes after they've already been set)

```
    foreach ($tree as $item) {
        if ($menu_link_id == $item->link->getPluginId()) {
            $top_level_menu = $item;
            return $item;
        }
    }

```
> 0 votes

# Answer
Try the following:

```
$parameters->setRoot('menu_link_content:818bf040-f12a-4915-835f-b9339eb7c828');

```
> 2 votes

---
Tags: 8, navigation
---


title: Change the input format for 3000+ nodes

text:
# Question
Title: Change the input format for 3000+ nodes
I have a lot of nodes that need to get their input format changed - I could do that by hand, but then I won't be done before Christmas 2014.

Where is Drupal storing that information? How can I change the input format in a split second, with an SQL query?

# Answer
Doing this en-masse could present a potential security risk, especially if you are changing the format to a more lenient set of filters. Text formats modify field output during display, not during save. For example, any previously-escaped HTML or PHP submitted to a field will straight up render/run if you accidentally or intentionally set the filter to Full HTML or PHP code.

For this reason, Drupal doesn't automatically update all existing nodes when you change a text format. The behavior of text formats in similar scenarios is still an open issue. (See Text formats should throw an error and refuse to process if a plugin goes missing, which is still open on May 31, 2021).

With that said, each field stores the text *field\_machine\_name\_format*, where *field\_machine\_name* is the field machine name. That column should be updated *field\_revision\_field\_machine\_name* and *field\_data\_field\_machine\_name* tables.

The value for the column is a machine name defined as the *format* column in the *filter\_format* table. Updating all the fields would be a matter of running a query like the following, for each field that needs changing.

```
UPDATE field_revision_foo SET field_foo_format = 'new_format';
UPDATE field_data_foo SET field_foo_format = 'new_format';

```

You can determine the value of *new\_format* value from /admin/config/content/formats, from the *Configure* link.
> 19 votes

# Answer
Try this way, by making a loop for all nodes of certain type:

```
$node = node_load(nid);
$node->body[$node->language][0]['format'] = 'full_html'; // plain_text
node_save($node);

```
> 4 votes

# Answer
Just ran into the same situation as Morten did here, with a D6 =\> D7 upgrade that apparently didn't finish the input formats.

Took a cruder approach than the answers already here, and wrote a module which ran through the DB schema and updated all the columns which contain the string 'format', replacing the D6 format values (1, 2, 3) with D7 machine names (`filtered_html`, `full_html`, `plain_text`).

https://gist.github.com/xurizaemon/9824872

Hardcoded to support the mapping of

```
1 => filtered_html,
2 => full_html,
3 => plain_text,

```

Also might try to rewrite fields which are named 'format' (eg "date\_format", but if you have a date format with value '2', that's your problem).
> 1 votes

# Answer
For me, the following worked:

```
update `field_revision_body` set `body_format` = 'new_body_forma' WHERE `bundle` = 'node_type'
update `field_data_body` set `body_format` = 'new_body_forma' WHERE `bundle` = 'node_type'

```

Of course you must change the new\_body\_forma and the node\_type
> 1 votes

# Answer
Presumably you will want to know which fields need updating, possibly to do some logging or checks on the data. To do this, get all table and column names that contain a `_format` column:

```
select distinct TABLE_NAME, column_name
from information_schema.columns
where TABLE_SCHEMA = 'my_drupal_database_name' and column_name like '%_format';

```

Armed with this data you can build separate queries from those values. Check the output first; you may need to remove some entries that do not pertain to content/revisions. I recommend using a regex-capable editor to build the queries. I turned the data into a big `select [...] union` statement and then ran update queries against it.

Using this approach saved me quite some time when I needed to update thousands of nodes/revisions. Remember to clear the field cache (NOT covered by `drush cc all`!):

```
field_cache_clear();

```

Or with drush:

```
drush sqlq "truncate table cache_field;"

```

### Also removing text filter

If you are also retiring a text filter, afterwards you will need to change the default text format for CTs that had fields that used it. If you don't do this, your users will get permission denied messages within the fields that used the `old_format`. I did this query to find the culprits:

```
select * from field_config_instance where `data` LIKE '%old_format%';

```

To make the changes, I found it easier to use the interface to visit each field settings page and press Save (the data is stored as longblob and was unwieldy to search and replace due to the better formats module data injections). Even fields that had Text processing set to `Plain text` contained the old\_format! For the fields that have Text processing set to `Filtered text (user selects text format)`, you will additionally need to select a new default value and press Save.

You should clear the filter cache after removing a filter (again, not covered by `drush cc all`!):

```
cache_clear_all('*', 'cache_filter', TRUE);

```

Or with drush:

```
drush sqlq "truncate table cache_filter;"

```
> 1 votes

# Answer
You can use the following code, if you have the entity.module installed.

```
// I'm using node_save($node);
$wrapper = entity_metadata_wrapper('node', $node->nid);
$wrapper->body->set(array('value' => body_text, 'format'=>'full_html'));

```
> 0 votes

# Answer
```
update field_revision_body set body_format = 'full_html' WHERE bundle IN ('book','page');
update field_data_body set body_format = 'full_html' WHERE bundle IN ('book','page');

```

did the trick for me. Don't forget to clear caches
> 0 votes

---
Tags: 7, input-formats
---


# Question
Title: How do I implement the login, register and "Forgotten password" forms?
I'm trying to implement the three Drupal 8 user forms : login, register account and forgotten password forms.

I'm creating custom pages in my module for each one of them because I want to display content around those forms, change titles, hook the forms.

I'm having a hard time to do it, especially to get those forms in order to send them to the template and render them.

# Answer
> 0 votes
Here is what I ended up doing in my controllers :

```
# Login form
public function content() {
  $formBuilder = $this->formBuilder();
  $form = $formBuilder->getForm("Drupal\user\Form\UserLoginForm");
  return [
  '#theme' => 'weber_login_form',
  '#login_form' => $form,
  ];
}

# Forgotten password form
public function content() {
  $formBuilder = $this->formBuilder();
  $form = $formBuilder->getForm("Drupal\user\Form\UserPasswordForm");
  return [
    '#theme' => 'weber_password_form',
    '#password_form' => $form,
  ];
}

# Register form
public function content() {
  $entity = \Drupal::entityManager()
  ->getStorage('user')
  ->create(array());

  $formObject = \Drupal::entityManager()
  ->getFormObject('user', 'register')
  ->setEntity($entity);

  $form = \Drupal::formBuilder()->getForm($formObject);
  return [
    '#theme' => 'weber_register_form',
    '#register_form' => $form,
    '#link' => NULL,
  ];
}

```

# Answer
> 0 votes
I would always prefer to customise the built-in pages rather than use the approach OP followed because those pages still exist and can be visited (unless OP is overriding the routing as well, which they did not mention).

There's a lot that can be done by simpler means:

1. Using the block system to inject extra content into the pages. Blocks can be programmatic or content managed, whichever best suits your needs.
2. Using hook\_form\_ID\_alter() to alter the individual forms as required.
3. Using theme overrides to adjust the HTML for theming purposes.

Without knowing the specific changes required it's difficult to advise in more detail. Certain contributed modules might be useful but again without further information I can't really say.

---
Tags: forms
---


title: Migrate media with alternative text

text:
# Question
Title: Migrate media with alternative text
I'm trying to import image with new media module on core 8.5.

I've a json source and on my .yml I've:

```
  field_media_image:
    target_id:
      plugin: migration
      migration: immagini
      source: fid

```

This works, immagini is another importer that imports files.

In the new media there is also an "alt" (mandatory) and "title" attribute on the media entity. But if I try to add something like this, it doesn't work (alt\_text is the correct source for alternative text). The media is created but is not referenced to the correct id:

```
  field_media_image:
    alt: alt_text
    target_id:
      plugin: migration
      migration: immagini
      source: fid

```

How should I pass the alt attribute to this field? I also tried to use a syntax like:

```
  field_media_image:
    target_id:
      plugin: migration
      migration: immagini
      source: fid
  'field_media_image/alt': alt_text

```

But it doesn't work, the media is created but there is no reference to the correct id.

# Answer
`field_media_image/alt` belongs in the `immagini` migration, not in the node migration.

In migration that creates the media item (destination plugin entity:media) you can map the media item's fields:

```
  # Image field see media_entity.bundle.image.yml.
  field_media_image/target_id: fid
  field_media_image/alt: field_file_image_alt_text/0/value
  field_media_image/title: field_file_image_title_text/0/value

  # Description field.
  field_description: field_image_description
  # Caption field.
  field_caption: field_caption

destination:
  plugin: entity:media

```

See https://www.previousnext.com.au/blog/migrating-drupal-7-file-entities-drupal-8-media-entities
> 2 votes

---
Tags: migrations, media
---


# Question
Title: How can I set page specific user view access by user role?
I need to be able to restrict access to specific pages based on user role, I heard that nodeaccess could do that, but I haven't been able to figure out how to do that with it, can you set page specific role access with nodeaccess? if not is there a module that can do that?

# Answer
> 0 votes
First of all, you can install nodeaccess module and then configure it. It works for specific pages to restrict based on user access.

---
Tags: 7, users
---


# Question
Title: Update a content type field's allowed values programmatically
I have a list field in the content type and in the `config` table , the field storage details saved as follows :

```
collection:
name: field.storage.node.field_ip_range_sec_zone
data: a:17:{s:4:"uuid";s:36:"9d20e561-e39c-4c11-b100-ff3a29a75267";s:8:"langcode";
                                            s:2:"en";s:6:"status";b:1;s:12:"dependencies";a:1:{s:6:"module";a:3{i:0;s:17:
                                        "field_permissions";i:1;s:4:"node";i:2;s:7:"options";}}s:20:"third_party_settings";
                                    a:1:{s:17:"field_permissions";a:1:{s:15:"permission_type";s:6:"public";}}s:2:"id";
                                s:28:"node.field_ip_range_sec_zone";s:10:"field_name";s:23:"field_ip_range_sec_zone";
                            s:11:"entity_type";s:4:"node";s:4:"type";s:11:"list_string";s:8:"settings";a:2:
                        {s:14:"allowed_values";a:3:{i:0;a:2:{s:5:"value";s:2:"E1";s:5:"label";s:2:"E1";}
                i:1;a:2{s:5:"value";s:2:"C2";s:5:"label";s:2:"C2";}i:2;a:2{s:5:"value";s:2:"D1";s:5:"label";s:2:"D1";}}
            s:23:"allowed_values_function";s:0:"";}s:6:"module";s:7:"options";s:6:"locked";b:0;s:11:
        "cardinality";i:1;s:12:"translatable";b:1;s:7:"indexes";a:0:{}s:22:"persist_with_no_fields";
    b:0;s:14:"custom_storage";b:0;}

```

As you can see there is Allowed values (**`E1,C2,D1`**) , and now i want to add an additional value to the allowed values , How can i do that ?

**WHAT I HAVE TRIED**

---

I could get the allowed values using the following :

```
$entity_type = 'node';
$bundle = 'ip_range';
$field_name = 'field_ip_range_sec_zone';
$ip_sec_zone_storage_values = \Drupal\field\Entity\FieldStorageConfig::loadByName($entity_type, $field_name);

```

But dont know how to update it , Any idea ??

# Answer
> 3 votes
Those are settings, you get them using `$ip_sec_zone_storage_values->getSetting('allowed_values')`,, in there you'll find those settings, you can add another one, set the settings back with setSetting('allowed\_values', $allowed\_values) and then -\>save() to save the field storage config:

```
$allowed_values = $ip_sec_zone_storage_values->getSetting('allowed_values');
// The new value.
$allowed_values[$ipseczone] = $ipseczone;
$ip_sec_zone_storage_values->setSetting('allowed_values', $allowed_values);
$ip_sec_zone_storage_values->save();

```

# Answer
> 0 votes
After many hours i finally found solution. I dynamically created options for multi select field and got error message on submit that choosen select in wrong option.

It requires add new options to allowed\_values for that field. Here is the solution:

```
 //load your field
 $field_purchasers = \Drupal\field\EntityFieldStorageConfig::loadByName('user', 'field_purchaseres');
 //subscribe new options to this field
$field_purchasers->setSetting('allowed_values_function','module_name_allowed_values_function' );
//save configuration
$field_purchasers->save();

```

In your .module file write in callback function :

```
function module_name_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable) {
  $options = [
    1 => 'My new option 1',
    2 => 'My new option 2',
    3 => 'My new option 3',
   ];
  return $options;
}

```

---
Tags: 8, entities
---


# Question
Title: How do I get the associated node from a webform entity?
I'm preprocessing a webform using hook\_webform\_submission\_form\_alter. The webform is being rendered as a node field. How can I, from inside my form\_alter hook access that node?

```
function MY_MODULE_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
    $parameters = \Drupal::routeMatch()->getParameters();

    if ($parameters->has('node')) {

        // processing goes here
    }
}

```

I'm fetching it from the url parameter right now, but I would prefer to do this in a cleaner way.

# Answer
> 1 votes
After some digging, I've found out the answer.

This is how I get the webform submission, the webform object, and the associated node:

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

        $entity  = $form_state->getFormObject()->getEntity(); // webform submission
        $webform = $form_state->getFormObject()->getWebform(); // webform object
        $node    = $entity->getSourceEntity(); // associated node

        // (...)
    }

```

---
Tags: 8, webforms
---


# Question
Title: Where does a blank theme inherit its templates from?
I just enabled my theme only containing an `MYTHEME.info` file. Now I have one query here.

As a output I got broken page. I have checked source of this page. I got some HTML structure.

As per my knowledge, theme renders from `html.tpl.php`. But my theme doesn't contain this file. So from where did it get its HTML structure?

From any core theme/themes?

I have also disabled all previously enabled themes except for the admin theme.

# Answer
> 2 votes
> So from where it got html structure.

It comes from either your theme's base theme, or the default HTML template file included in the system module.

---
Tags: 7, theming
---