# Question
Title: missing form tag while embedding and stylizing form elements
I am wanting to embedd a form into a twig template, but place the elements where and how I want them. The idea is to have better control over the layout **without having to use the $form array to include #markup.**

This page will not only have the form on it. It will also display a table of recently entered data.

I started with this in my controller

```
    public function index() {
    $form = \Drupal::formBuilder()->getForm('Drupal\rmdrs\Form\ReminderForm');

    return array (
      '#theme' => 'rmdrs_home',
      '#reminder_form' => $form,
    );
  }

```

Doing this I then went to the .module file and added this:

```
    function rmdrs_theme($existing, $type, $theme, $path) {
  return array(
    'rmdrs_home' => array(
      'variables' => array(
        'reminder_form' => null,
      ),
    ),
  );
}

```

There will be other templates for other pages of this module/app that will use this same process.

In my Twig file I call the individual elements like in this sample:

```
    <div class="rmdrs-form-row-flex form-group-bottom-separator">
    <div style="width: 45%;">
      {{ reminder_form.title }}
    </div>
    <div style="width: 45%;">
      {{ reminder_form.category }}
    </div>
  </div>

```

The problem is that these elements are not wrapped within a form tag. I am curious how do I get this to work without having to manually wrap the code in a form tag? Shouldn't there be a peice of code that places all this within a form tag?

# Answer
You have to nest multiple templates, you can't solve this in a single template. See for example the standard node edit form which is rendered as main content in a block, this block renders the form and the form renders the inner template styling the individual form elements. In your case, the block template would be the controller template.

Visit *www.example.com/node/8/edit* and press CTRL-U to see the HTML source. If you have the Twig debug mode enabled, you see the nested templates in the comments:

```
<!-- BEGIN OUTPUT from 'core/themes/claro/templates/classy/block/block.html.twig' -->
<div id="block-claro-content" class="block block-system block-system-main-block">

<!-- BEGIN OUTPUT from 'core/modules/system/templates/form.html.twig' -->
<form class="node-article-edit-form node-form" data-drupal-selector="node-article-edit-form" enctype="multipart/form-data" action="/node/8/edit" method="post" id="node-article-edit-form" accept-charset="UTF-8">

<!-- BEGIN OUTPUT from 'core/themes/claro/templates/node-edit-form.html.twig' -->

```

This outputs the node-edit-form.html.twig, which contains some helpful information in the doc block:

```
{#
/**
 * @file
 * Theme override for a node edit form.
 *
 * Two column template for the node add/edit form.
 *
 * This template will be used when a node edit form specifies 'node_edit_form'
 * as its #theme callback.  Otherwise, by default, node add/edit forms will be
 * themed by form.html.twig.
 *
 * Available variables:
 * - form: The node add/edit form.
 *
 * @see claro_form_node_form_alter()
 */
#}
<div class="layout-node-form clearfix">
  <div class="layout-region layout-region--node-main">
    <div class="layout-region__content">
      {{ form|without('advanced', 'footer', 'actions') }}
    </div>
  </div>
  <div class="layout-region layout-region--node-secondary">
    <div class="layout-region__content">
      {{ form.advanced }}
    </div>
  </div>
  <div class="layout-region layout-region--node-footer">
    <div class="layout-region__content">
      <div class="divider"></div>
      {{ form.footer }}
      {{ form.actions }}
    </div>
  </div>
</div>

```

To implement this for a custom form see How to render specific form elements from the \*.theme file
> 0 votes

---
Tags: forms
---


# Question
Title: How to set widget for a field on a custom form?
How do I set the widget to be used for a field on a custom form?

I am surprised I haven't been able to find something covering this. Sort of expected it to be something like:

```
$form['interest'] = [
  '#type' => 'checkbox',
  '#title' => t('Are you interested?'),
  '#widget' => 'my_custom_boolean_widget',
]

```

But nothing in the FormAPI regarding anything to do with widgets.

# Answer
The form API is the most basic way to define custom forms in Drupal. It is using form elements to show HTML controls for **form fields**.

(Field) Widgets on the other hand are part of the **entity fields** API:

> Field API widgets specify how fields are displayed in edit forms. \[...\] Widgets are Form API elements with additional processing capabilities.

They control how the form elements of fields attached to entities are rendered and how data provided by the user is written back to the respective fields. Remember, entity fields might have a cardinality. So Widgets must be able to not only provide a simple checkbox, but also form elements for multiple boolean values on the same entity field. They are basically another abstraction layer on top of the form API, and thus not known to the form API itself, which you'd use to create your custom forms.

To use the very same HTML controls in an entity field widget and for the value of a plain form API form field, you'd first have to create an according custom form element (which then could be included in your form via the `#type` property), and use this element in a custom field widget as well. This is how you'd do it for very complex elements like file upload elements with drag'n'drop functionality and so on.

More often, using the generic form API controls and adding CSS classes (`#attributes`), custom process (`#process`) or pre-render functions (`#pre_render`) in conjunction with a bit custom CSS and/or JavaScript is sufficient to achieve similar UI behavior between field widgets and their custom form element counterparts. You might even be able to re-use JavaScript or CSS provided by a library attached to a widget when adding the very same CSS classes to the form element and attaching the widget library to your form. A look into the source code of the widget you'd love to use in your form might give you an according idea.
> 2 votes

# Answer
Although I selected Mario's answer as "correct". It is only telling me that I cannot do what I want to do. The webomelette link I posted however does provide a neat "trick" to accomplish what I need to accomplish. It allows "grabbing" fields (and their selected widget) from entity forms and using them on your custom form.

The simplified code from that post is basically this in your custom buildForm():

```
// Fields pulled from Widgets entity to use Field widget
$widget_fields = [array of field names I want to pull from the entity];
$extra_fields = [];
foreach ($form_display->getComponents() as $name => $component) {
  if (!in_array($name, $widget_fields)) continue;
  $widget = $form_display->getRenderer($name);
  if (!$widget) continue;
  $items = $entity->get($name);
  $items->filterEmptyItems();
  $extra_fields[$name] = $widget->form($items, $form, $form_state);
  $extra_fields[$name]['#access'] = $items->access('edit');
}

```

I used Console to create a custom entity (Widgets) solely for the purpose of grabbing fields/widgets for my custom forms.

I then just grab fields from $extra\_fields to add to my custom form.

```
$form['my_field'] = $extra_fields['field_my_entity_field'];

```

As Marios explains, field widgets are part of the EntityAPI and therefore require entity context to associate a field with a widget. This technique uses a "fake" entity to tie EntityAPI and FormAPI together.
> 0 votes

# Answer
I encountered a similar challenge, and after some experimentation, I found a solution that works well for my specific case.

```
public function blockForm($form, FormStateInterface $form_state): array {
    $config = $this->getConfiguration();
    $form = parent::blockForm($form, $form_state);

    // Define a standalone field definition(label, required, etc.).
    $field_definition = BaseFieldDefinition::create('some_field_type')
      ->setName('some_field_type')
      ->setLabel('My best field');
    // Create a new field item list.
    $items = new FieldItemList($field_definition, 'some_field_type');
    // Set default values.
    $items->setValue($config['my_field']);
    // Build the widget form element.
    $widget = $this->widgetPluginManager->getInstance([
      'field_definition' => $field_definition,
      'configuration' => [
        // Widget ID.
        'type' => 'some_field_widget',
        // Widget settings.
        'settings' => [
          'show_label' => TRUE,
        ],
      ],
    ]);
    // We need to specify a #parents key on our form definition.
    $form['#parents'] = [];
    // Build the widget form element.
    $form['my_field'] = $widget->form($items, $form, $form_state);

    return $form;
  }

```
> 0 votes

---
Tags: 9, forms
---


# Question
Title: Template suggestions are shows, even though all debug settings are off
We recently upgrade our Drupal 9 site to Drupal 10. The TWIG debug information now outputs all the template suggestions.

We have all debug setting off (FALSE) in the the *services.yml* file.

Of course, Drupal 10 has the new UI interface to control the debug settings, but there are already off by default. I've tried enabling, disabling, and clearing caches, but the debug information is still output on the page.

# Answer
Check

```
drush ev "var_dump(\Drupal::getContainer()->getParameter('twig.config'));"

```

If the debug value is TRUE, any \*services.yml file could have set the container parameter.

Then check all hits except the scaffold default file:

```
grep -r 'twig.config:' --include *.yml

```

If not a YAML file it's possible a module sets the array in PHP `setParameter('twig.config', $config)`.
> 1 votes

---
Tags: 10
---


# Question
Title: Make a header of a view page to appear only in the view's first page
I have a view-page with a pager of about **10 pager-pages**.

This view also has a a view-header. The text of this header repeats itself in all pager-pages of that view, which is a bit funny because in page 2 or even in page 10 the user could read the same header text "welcome to my blog".

How to make a header of a view page to appear only in the view's first page?

# Answer
You can use hook\_preprocess\_views\_view\__HOOK() hook (in .module/theme file) for display header conditionally:

```
function Mymodulename_preprocess_views_view__machine_name_of_view(&$vars) {
  $view = $vars['view'];
  $pager_number = $view->pager->current_page;
  // current page key value start from 0
  // Added condition header should display only for first page
  if($pager_number != 0){
     unset($vars['header']);
  }
}

```
> 1 votes

# Answer
Install the Filter Twig module:

```
composer require 'drupal/filter_twig:^2.2'
drush en filter_twig

```

Visit */admin/config/content/formats/add*, enter the name "Views Twig", check "Replaces Twig value" and save.

In the View add a Header: Global: Text area, select the text format *Views Twig* and fill in the text:

```
{% if [view:current-page] == 1 %}
  Page 1
{% endif %}

```
> 0 votes

---
Tags: views, 10
---


# Question
Title: Inform the user what page of the pager it is -- on top of the page as well
When we create a View of pages we can give it a pager. That pager typically appears **underneath** the view. This can cause an accessibility problem of a user mistakenly clicking to go to a next page without understanding what the current page is, especially if the page is very long and the the fold of the new page doesn't indicate what is the current page on the pager series.

The pager is rendered as in the following screenshots.

>

>

How can I show the user the current page **above** the view as well?

# Answer
You can use template\_preprocess\_views\_view() hook to get current page number

```
function Mymodule_preprocess_views_view(&$vars){
  $view = $vars['view'];
  $id = $view->storage->id();
  if($id == 'view_name'){
   $pager_number = $view->pager->current_page;
   // current page key value start from 0 so add by 1
   // set current_page variable that can access in view twig
   $vars['current_page'] = $pager_number + 1;
  }
}

```

**Note:** Now you can use the "current\_page" in views-view.html.twig by rendering like this: {{ current\_page }} Make sure override view twig by view name displayed by theme suggestion

**To override view twig can follow naming convention like this:** views-view--machine\_name.html.twig
> 1 votes

# Answer
In the View add a Header: Global: Text area and fill in the text:

```
[view:current-page]

```

There is a list with more pager variables in the section *Available global token replacements*.
> 0 votes

---
Tags: views, 10
---


# Question
Title: How do I prevent a form from being cached for anonymous users?
I have a form that is pre-populated with information specific to an anonymous user's session information. However, the form appears to get cached for all anonymous users by default.
'Internal Dynamic Page Cache' is enabled, 'Internal Page Cache' is not.

How do I disable caching of this form? It should be rebuilt fresh every time it is displayed.

# Answer
> 16 votes
To update:

In order to prevent a form from caching at all, you can include the following #cache key in your form:

```
$form['#cache'] = ['max-age' => 0];

```

# Answer
> 6 votes
In your mymodule.module file, located at the root of your module directory:

```
/**
 * Workaround to prevent form caching for anonymous users.
 */
function mymodule_form_myregistration_form_alter() {
    \Drupal::service('page_cache_kill_switch')->trigger();
}

/**
 * Workaround to prevent form caching for anonymous users.
 */
function mymodule_form_mylogin_form_alter() {
    \Drupal::service('page_cache_kill_switch')->trigger();
}

```

This is using Drupal 8's Form Alter

# Answer
> 5 votes
The correct way to do this is with the following line.

```
$form['#cache']['contexts'][] = 'session';

```

See also Cache contexts.

At some stage, `max-age` has stopped working.

# Answer
> 1 votes
Some forms generated by Drupal 8(.7.8)'s FAPI crash when cached server side using Drupal 8's cache, and loaded by an anonymous user.

If you clear the server side cache(`$ drush cr`), the anonymous user can then load the form successfully; on refresh it crashes once cached server side and reloaded by the user.

In this case, BrianV's answer (`$form['#cache'] = ['max-age' => 0];`) solves the issue on Drupal 8.7.8.

I think we're seeing different types of caching issues here, with different solutions that resolve them, and it might be useful to provide a concise accurate description of your situation which caused a form caching issue, an error log(if it produces errors) as well as the solution you used to fix it.

There might be different problems for a straight FAPI form vs. a webform, vs. say a CiviCRM extension form and providing details will help people a lot more than just saying "well this code worked for my situation" without describing the situation in detail.

Providing the exact Drupal minor version you're on is also important.

The stack trace that my situation was producing was (formatted for readability):

```
TypeError: Argument 1 passed to Drupal\\Core\\Routing\\RequestContext::fromRequest() must be an instance of Symfony\\Component\\HttpFoundation\\Request, null given, called in DRUPAL_ROOT/core/lib/Drupal/Core/Routing/RequestContext.php on line 31 in DRUPAL_ROOT/core/lib/Drupal/Core/Routing/RequestContext.php on line 37
#0 DRUPAL_ROOT/core/lib/Drupal/Core/Routing/RequestContext.php(31): Drupal\\Core\\Routing\\RequestContext->fromRequest(NULL)
#1 [internal function]: Drupal\\Core\\Routing\\RequestContext->fromRequestStack(Object(Symfony\\Component\\HttpFoundation\\RequestStack))
#2 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(329): call_user_func_array(Array, Array)
#3 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'router.request_...')
#4 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(487): Drupal\\Component\\DependencyInjection\\Container->get('router.request_...', 3)
#5 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(326): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#6 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(502): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'private__zpo0hT...')
#7 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(237): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#8 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'url_generator')
#9 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(487): Drupal\\Component\\DependencyInjection\\Container->get('url_generator', 1)
#10 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(237): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#11 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'link_generator')
#12 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(487): Drupal\\Component\\DependencyInjection\\Container->get('link_generator', 1)
#13 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(237): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#14 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'plugin.manager....')
#15 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(487): Drupal\\Component\\DependencyInjection\\Container->get('plugin.manager....', 1)
#16 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(237): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#17 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'geocoder')
#18 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(487): Drupal\\Component\\DependencyInjection\\Container->get('geocoder', 1)
#19 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(237): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#20 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'nfb.address_ada...')
#21 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(487): Drupal\\Component\\DependencyInjection\\Container->get('nfb.address_ada...', 1)
#22 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(237): Drupal\\Component\\DependencyInjection\\Container->resolveServicesAndParameters(Array)
#23 DRUPAL_ROOT/core/lib/Drupal/Component/DependencyInjection/Container.php(173): Drupal\\Component\\DependencyInjection\\Container->createService(Array, 'nfb_contact_inf...')
#24 DRUPAL_ROOT/core/lib/Drupal/Core/DependencyInjection/DependencySerializationTrait.php(80): Drupal\\Component\\DependencyInjection\\Container->get('nfb_contact_inf...')
#25 [internal function]: Drupal\\Core\\Form\\FormBase->__wakeup()
#26 DRUPAL_ROOT/core/lib/Drupal/Core/Cache/DatabaseBackend.php(167): unserialize('O:31:"Drupal\\\\Co...')
#27 DRUPAL_ROOT/core/lib/Drupal/Core/Cache/DatabaseBackend.php(122): Drupal\\Core\\Cache\\DatabaseBackend->prepareItem(Object(stdClass), false)
#28 DRUPAL_ROOT/core/lib/Drupal/Core/Cache/DatabaseBackend.php(92): Drupal\\Core\\Cache\\DatabaseBackend->getMultiple(Array, false)
#29 DRUPAL_ROOT/core/modules/page_cache/src/StackMiddleware/PageCache.php(306): Drupal\\Core\\Cache\\DatabaseBackend->get('https://dev.nfb...', false)
#30 DRUPAL_ROOT/core/modules/page_cache/src/StackMiddleware/PageCache.php(124): Drupal\\page_cache\\StackMiddleware\\PageCache->get(Object(Symfony\\Component\\HttpFoundation\\Request))
#31 DRUPAL_ROOT/core/modules/page_cache/src/StackMiddleware/PageCache.php(82): Drupal\\page_cache\\StackMiddleware\\PageCache->lookup(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#32 DRUPAL_ROOT/core/modules/ban/src/BanMiddleware.php(50): Drupal\\page_cache\\StackMiddleware\\PageCache->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#33 DRUPAL_ROOT/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\\ban\\BanMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#34 DRUPAL_ROOT/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\\Core\\StackMiddleware\\ReverseProxyMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#35 DRUPAL_ROOT../vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\\Core\\StackMiddleware\\NegotiationMiddleware->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#36 DRUPAL_ROOT/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\\StackedHttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)
#37 DRUPAL_ROOT/index.php(19): Drupal\\Core\\DrupalKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request))
#38 {main}

```

# Answer
> 0 votes
In order to prevent a form from caching at all, you can include the following #cache key in your form along with max-age & context attributes:

```
$form['#cache'] = [
 'max-age' => 0,
  'contexts' => ['session'],
];

```

**Informative Tips:** Follow these documentation to know more about context & max-age attributes.

---
Tags: forms, 8, caching
---


# Question
Title: How can I hide a specific region according to its url?
I need to hide the footer region on all pages with whose URL contains */people/*, similarly to what is possible to do with blocks.

# Answer
> 0 votes
You can use hook\_preprocess\_page() hook (.modue/.theme file) to hide footer region conditionally:

```
function Mymodulename_preprocess_page(&$vars) {
  $vars['display_footer_region'] = true;
  $current_path = \Drupal::service('path.current')->getPath();
  $ex_string = '/people';
  // set the display_footer_region false conditionally
  if (strpos($current_path, $ex_string) !== false) {
    $vars['display_footer_region'] = false;
  }

}

```

Then go to page.html.twig & add the footer region inside condition:

```
{% if display_footer_region == true %}
  {{ page.footer }}
{% endif %}

```

Make sure override the page.html.twig inside the custom theme

---
Tags: theming
---


# Question
Title: Button that enrolls students for a course and leads to the enrollment form
I have an *actions.yml* file with the following content.

```
student_enrollment.enroll_course:
  route_name: student_enrollment.enroll
  route_parameters:
    course_id: 1
  title: Enroll
  appears_on:
    - entity.node.canonical

```

This is a button located in /node/{node\_id}.

How can I make the *course\_id* route parameter dynamic so that when the node ID is for example 5, course\_id will be 5 too?

This actually is a button for enroll students in a course. When the enrollment button is clicked, students should be redirected to the enrollment form shown in the student\_enrollment.enroll route.

This is the definition for that route.

```
student_enrollment.enroll:
  path: '/enroll/{course_id}'
  defaults:
    _title: 'Enroll for the course'
    _form: 'Drupal\student_enrollment\Form\StudentEnrollmentForm'
  requirements:
    _permission: 'enroll for a course'
  options:
    parameters:
      course_id: \d+

```

# Answer
> 1 votes
You can add "class" parameter in mymodule.links.actions.yml file

```
class: 'Drupal\student_enrollment\Plugin\Menu\LocalAction\EnrollCourseAddLocalAction

```

Complete code : mymodule.links.actions.yml

```
student_enrollment.enroll_course:
  route_name: student_enrollment.enroll
  title: Enroll
  appears_on:
    - entity.node.canonical
  class: 'Drupal\student_enrollment\Plugin\Menu\LocalAction\EnrollCourseAddLocalAction'

```

Create: EnrollCourseAddLocalAction.php file in this folder: src/Plugin/Menu/LocalAction

```
<?php

namespace Drupal\student_enrollment\Plugin\Menu\LocalAction;

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Menu\LocalActionDefault;

/**
 * Modifies the local action to set value of dynamic parameter course_id.
 */
class EnrollCourseAddLocalAction extends LocalActionDefault {

  /**
   * {@inheritdoc}
   */
  public function getRouteParameters(RouteMatchInterface $route_match) {
    // Here you use parameter that you are getting from route it can be course_id/nid/id
  // Added get course id from node object
    $node = $route_match->getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      $course_id = $node->id();
    }
    return ['course_id' => $course_id];
  }

}

```

---
Tags: actions
---


title: Views Row Classes Not Appearing

text:
# Question
Title: Views Row Classes Not Appearing
I'm using a view to display articles, I want to see **views row classes** in the code, like this:

```
div class="views-row views-row-1 views-row-odd views-row-first

```

But for some reason the rendered code is missing these row-specific div wrappers and just shows the nodes like this:

```
div id="node-4" class="node node-article"

```

Even more frustrating, the code in the views PREVIEW shows the desired **views row classes** `div class="views-row views-row-1"` but those div wrappers don't appear in the rendered site code.

On the last site I made, the views-row classes appeared automatically. Now for some reason they're not appearing. I've been frantically googling and pulling my hair out for two days on this so any help you could provide would be greatly appreciated :-)

# Answer
Did you check:

1. Template (\*.tpl.php file) override. I am not sure if preview shows template overrides.
2. Template.php for altering hooks
3. Contrib modules for altering hooks
> 3 votes

# Answer
Copy-pasting a core template into my theme helped resolve this issue:

```
cp ../../core/modules/views/templates/views-view-unformatted.html.twig \
  templates/views/views-view-unformatted.html.twig

```
> 0 votes

---
Tags: views
---


# Question
Title: How do I clear settings from the Drupal object?
I have a module, which renders an AJAX form, which passes data to a script via `drupal_add_js` and stores it in the settings property of the Drupal object. My problem is that I cannot seem to remove old data from the object (a user can toggle options on the form and send new datasets to the javascript). Logically, I thought passing an empty array would clear the values, but it doesn't.

```
// Clear old data from settings.
$js = array(
  'd3' => array(
    'inventory' => array(
      'chart' => array(
        'dataset' => array(),
      ),
    ),
  ),
);
drupal_add_js($js, 'setting');

```

I need something like `drupal_remove_js($js, 'setting')`? or a method for removing object properties?

# Answer
drupal\_add\_js adds javascript to the page `<head>`, so as far as I know you can't change that anymore with AJAX. Thus placing it in an AJAX callback doesn't work. You need to solve this at Javascript level in the the browser.

You'll have to make sure all data for all options is sent to the client during rendering and then use simple jQuery selectors to enter the correct part of data into the visualizer.
> 0 votes

# Answer
I realize this is a very old question, but I had to figure this out recently when using the plotly\_js library to make charts.

```
/**
 * pos_charts_clear
 *
 * The js settings don't get reset as forms are rebuilt
 * Need to remove traces of chart settings between form rebuilds in a
 * heavy handed way. There's no way to do this without dipping into the
 * cache directly.
 *
*/

function pos_charts_clear($key = 'pos_charts') {
  $js = &drupal_static('drupal_add_js');
  foreach ($js['settings']['data'] as $k => $exist) {
    if (key($exist) == $key) {
      unset($js['settings']['data'][$k]);
    }
  }
}

```
> 0 votes

---
Tags: 7, javascript
---


# Question
Title: How can I restrict users to only see products of a certain store?
I am using Drupal 10 with Commerce 2. I would like to add a user, where the user can only see the products of a single store. For example, let's say there is Store A and Store B. I'd like to be able to create a User A and User B where User A only sees products from Store A and User B only sees products from Store B.

As of right now, the permissions for a certain role only allow me to restrict a user to Delete, Update, Create own/all products. For View products, it's either all or nothing.

This question is similar, but I wasn't able to figure out how the Group module could help. This was also for Drupal 8... I'm thinking maybe with Drupal 10 there's a more trivial answer.

# Answer
There is no more trivial answer; Drupal 10 is functionally equivalent to Drupal 8 in many respects. As with any content entity, if you want to control access in a fine-grained fashion, you'll have to use a separate module. Group might do just fine for ya, with some custom code ensuring products are related to groups that correspond to stores. (I haven't looked recently, but modules like Content Access or ACL supporting any content entity type would do the trick, too ... I just can't say if they've abstracted their functionality to this extent yet.)
> 0 votes

---
Tags: commerce
---


title: Make a custom action with form

text:
# Question
Title: Make a custom action with form
I am trying to make a custom user action where the selected users will have a node created manually, however I need to create a form to save the data that this node will have, such as: title, start date, end date. I have this code in my `my_module/Plugin/Action/ActionTest.php`

```
    <?php

namespace Drupal\my_module\Plugin\Action;

use Drupal\Core\Action\ActionBase;
use Drupal\views_bulk_operations\Action\ViewsBulkOperationsActionBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginFormInterface;
/**
 * Create custom action
 *
 * @Action(
 *   id = "test_action",
 *   label = @Translation("Test action"),
 *   type = "user",
 * )
 */
class ActionTest extends ViewsBulkOperationsActionBase implements PluginFormInterface {

    use StringTranslationTrait;
    /**
     * {@inheritdoc}
     */
    public function execute($entity = NULL) {

        $nid = $entity->id();
        $uid = \Drupal::currentUser()->id();

        $payment = \Drupal::entityTypeManager()->getStorage('node')->create([
          'type' => 'payments',
          'title' => "Payment ${nid}",
          'langcode' => 'es',
          'field_payment_state' => 1,
          'field_user' => $nid,
          'field_last_plan_purchased' => 2156
        ]);
        $payment->save();
  }
  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['title'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Title'),
      '#required' => TRUE,
    );

    return $form;
  }
    /**
     * {@inheritdoc}
     */
    public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {

    return true;
  }

}

```

But I can't get the selected action to go to the form, any idea on how I can achieve this?

I have the .schema.yml file like this

```
action.configuration.my_module:
 type: test_action
 label: 'Action custom'

```

and the configuration .yml file

```
langcode: es
status: true
dependencies:
 module:
   - user
id: test_action
label: 'Action custom'
type: user
plugin: test_action
configuration: {  }

```

I'm using drupal 10.1.4 and php 8.1 I appreciate any answer you can give me

# Answer
> 1 votes
In above code this **"system.action.test\_action.yml" file missing** : **add** this **file** inside this folder: **module/config/optional**, **only then custom action 'll start appear under action select list**

```
langcode: en
status: true
dependencies:
 module:
   - user
id: test_action
label: 'Test action'
type: user
plugin: test_action
configuration: {  }

```

After this newly added "Test action" start appear in select list of Action field on people listing page(/admin/people)

**Note:** Make sure uninstall then install module so that "system.action.test\_action.yml" config installed

After **adding** this file "**system.action.test\_action.yml**" at proper folder structure, only then **action** 'll start **appear**.

**ActionTest.php need to place here**: my\_module/**src**/Plugin/Action/ActionTest.php instead of here my\_module/Plugin/Action/ActionTest.php

Here in this file name convention : system.action.test\_action.yml , test\_action denotes machine name of custom action plugin

**If you want to configure action from UI along with custom action with the ConfigurationForm**

1. install "Actions" module in the core
2. Then visit to the actions overview page: /admin/config/system/actions
3. Here you 'll see "Create an advanced action" field, select the "Test action"(newly added custom action) from drop down & then click on create button
4. Then form 'll appear , fill the value in the field & click on save
5. Now the "Newly added custom action" 'll appear in available action list

Note : In this approach you don't need to create "system.action.test\_action.yml" file

I have noticed this buildConfigurationForm() not defined, so need to remove this line:
$form = parent::buildConfigurationForm($form, $form\_state);

---
Tags: forms, 10, actions
---


# Question
Title: How to style the h2 title of "search results"?
The "search results" H2 element on the search results page does not appear to be controlled by any specific template. I'm using stable9 as the base. How can I style it?

# Answer
There is not a template file for that `<h2>` element because it is not rendered using a theme implementation, but from `SearchController::view()`, which uses the following code.

```
  if (count($results)) {
    $build['search_results_title'] = [
      '#markup' => '<h2>' . $this->t('Search results') . '</h2>',
    ];
  }
  $build['search_results'] = [
    '#theme' => [
      'item_list__search_results__' . $plugin->getPluginId(),
      'item_list__search_results',
    ],
    '#items' => $results,
    '#empty' => [
      '#markup' => '<h3>' . $this->t('Your search yielded no results.') . '</h3>',
    ],
    '#list_type' => 'ol',
    '#context' => [
      'plugin' => $plugin->getPluginId(),
    ],
  ];

```

The part of that method that renders the search form is the following one.

```
$build['search_form'] = $this->formBuilder()->getForm(SearchPageForm::class, $entity);

```

`$build['search_results_title']` is not part of the `$build['search_form']` form, so implementing `hook_form_alter()` (or one of its variations) would not help. Attaching CSS styles to the page with `hook_page_attachments()` that target that `<h2>` element would not be possible without targeting all the `<h2>` elements in that page (or other pages) as Drupal core does not add specific classes to `<h2>Search results</h2>`.

The only possibility I see is changing the route callback used for that page, as described in Altering existing routes and adding new routes based on dynamic ones, keeping in mind that the route for the node search page is *search.view\_node*, which is defined in `SearchPageRoutes::routes()` as:

```
    $routes["search.view_{$entity_id}"] = new Route('/search/' . $entity->getPath(), [
      '_controller' => 'Drupal\\search\\Controller\\SearchController::view',
      '_title' => 'Search',
      'entity' => $entity_id,
    ], [
      '_entity_access' => 'entity.view',
      '_permission' => 'search content',
    ], [
      'parameters' => [
        'entity' => [
          'type' => 'entity:search_page',
        ],
      ],
    ]);

```

The controller method that renders that page is `SearchController::view()`. You can look at its code to understand what it is expected to render/do.
> 1 votes

---
Tags: views
---


# Question
Title: How can I add animation/fade to modal/dialogue boxes?
The current state of a modal/dialog opening in Drupal 8 (and 7 for that matter) is pretty clunky from a user experience perspect. Leveraging some type of animation/fade would really enhance the elegance + cohesiveness of the modal. I notice bootstrap allows a "fade" class on the modal, which gives it a fade effect (I assume). Is there a way to add this type (or any type) of animation to a Drupal 8 modal without needing bootstrap? Am I missing something simple?

Edit: Thanks for quick replies and patience with a newbie. So I'm opening a node/add form into a modal with a link like so..

```
<a class="use-ajax" data-dialog-options="{"width":800}" data-dialog-type="modal" href="/node/add/article">Add Article</a>

```

I'd like the modal to open/close with a fade effect (or slide in, etc). Is there a way to leverage JS, CSS or Drupal itself to create this animation?

Is there a better solution all together to displaying a node/add form in a popup/lightbox type element with ajax?

Thank you!

# Answer
What do you need the modal to do? I often use animated modals for my Drupal projects - http://joaopereirawd.github.io/animatedModal.js/

It seems to work pretty well for menus and forms in my experience.

It uses animate.css ( https://daneden.github.io/animate.css/ ) which you can use also to create some nice transitional effects.
> 0 votes

# Answer
You can use

```
<a class="use-ajax" data-dialog-options='{"width":"800","dialogClass":"custom-class-modal","show":"fadeIn","hide":"fadeOut"}' data-dialog-type="modal" href="/node/add/article">Add Article</a>

```
> 0 votes

---
Tags: 8, theming, modal-dialogs
---


title: How to run global PHP?

text:
# Question
Title: How to run global PHP?
More of a general understanding question then a problem to solve question.

In Drupal core version 10.X.X, is there a PHP file in which a user can freely run global PHP commands that would effect **any** webpage in the website?

An example command is:

```
<?php
    echo 'This ' . 'string ' . 'was ' . 'made ' . 'with concatenation.' . "\n";
?>

```

I ask about a file where the very last PHP in the queue would be executed, similar to how the very last JS or CSS in the queue would be globally executed at say `behavior.js` or `style.css`.

A "Test any PHP globally here, **in the last line of the file**" kind of file.

How to run global PHP?

# Answer
Really global would be `index.php`. But don't change this file. Drupal doesn't want you to change any core files, so they've implemented stacked middlewares where you can run your PHP code before or after the Drupal kernel:

```
  public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response {
    // Run code before executing the Drupal kernel
    $response = $this->httpKernel->handle($request, $type, $catch);
    // Run code after executing the Drupal kernel
    return $response;
  }

```

Use `drush gen middleware` to generate the scaffolding including the service definition:

```
 mymodule.middleware:
    class: Drupal\mymodule\MymoduleMiddleware
    tags:
      - { name: http_middleware, priority: 1000 }

```

Use a very high priority if you want to run the first or rather the last PHP code.
> 3 votes

# Answer
Yes. Implement an event subscriber as directed in this change record.
> 0 votes

---
Tags: 10
---


# Question
Title: Do content types play any role for ecommerce product webpages?
Content types (Node types) have always been a great way to organize Drupal content, especially when combining blocks in nodes of certain content types and/or certain node IDs or preventing them from appearing in these programatically.

We consider to build an ecommerce website with Drupal, something we never did.

Do content types play any role for ecommerce product webpages?
For example, should content types be utilized to organize types of "product nodes" or should the traditional Drupal ecommerce modules provide a whole different secondary mechanism to organize product webpages?

# Answer
> 1 votes
As of Drupal 8, Commerce Core defines a new type of content entity named Product to serve the function of product display page as opposed to Node, which we used in Drupal 7 and earlier. Modules that used to only work with Node generally work with any type of content entity, and we have rarely encountered a scenario where the default Product entity type is insufficient. (e.g., I think comments may not work on every type of content entity yet - can't recall, been a while since I tried.)

---
Tags: commerce, 10
---


# Question
Title: How to configure a multistep webform with custom alias to use GET instead of POST
I have a multi step webform, which I'm using as a kind of configurator. I want to allow people to share the link, so they can land on the last page of teh form with all the other values already set.

I configured a **custom path** (people will ask for a nice url instead of the default one)

I configured **GET (custom)** und Webform \> Settings \> Form \> Form Custom Settings

I'm forced there to enter a submission url, so I entered the same url as for the custom path.

The issue is now, that I'm stuck on the first page - a lot of params are added to the url, but I'm not getting to page 2.

If I use a different submit url, then the forms on I land on a 404 page.

How can I solve this?

# Answer
Alright, so the maintainer was very clear, that he will not support GET in a multistep webform. In order to still realise our requirements I had to become creative:

* multistep webform for the configuration process (dissabled submit button)
* on the last page I added a custom link via the "computed twig" form element which leads to a view with exposed filters

```
<a class="btn btn-primary" href="{{path('view.viewId.pageId', {arg_0: data.state, title: data.title, other_field: data.other_field})}}">link text</a>

```
* the view has then a context filter (arg\_0) and exposed filters, which correspond with the parameters from the link. The exposed filter itself is configured to be a block ,so it is not shown.

It works pretty well, and if you choose the urls right, the flow is frictionless

In case it helps somebody else :fingers\_crossed:
> 0 votes

---
Tags: webforms
---


# Question
Title: How to add attribute to element in twig before render?
I have a template for one of my forms and I want to add css class to the element before I render it but since I am printing the element as a whole I am not sure how to alter the attributes.

I was told on IRC to have a look at the merge method but so far no luck.

```
{% set submit_attributes = form.submit.attributes %}
{% submit_attributes.addClass('test') %}
{% form.submit.attributes|merge(submit_attributes) %}
{{ form.submit }}

```

or

```
{% form.submit.attributes.addClass('test') %}
{{ form.submit }}

```

# Answer
It looks like at this moment this is just not possible. I have created an issue at drupal.org for this. Maybe some day it will get implemented and we can get rid of the phptemplate engine for good.

https://www.drupal.org/node/2567759
> 3 votes

# Answer
Here is my solution for adding a placeholder to a custom text field being used for inputting search terms in a form. I could not use `element.attributes.setAttributes()` because in my case the key for attributes is `#attributes`.

```
{% set attr = form.search_api_fulltext['#attributes']|merge({'placeholder': 'Enter search term'|t}) %}
{% set search = form.search_api_fulltext|merge({'#attributes': attr}) %}
{{ search }}

```

Here is the same expanded a little for clarity:

```
{% set search = form.search_api_fulltext %}
{% set attr = form.search_api_fulltext['#attributes'] %}
{% set attr = attr|merge({'placeholder': 'Enter search term'|t}) %}
{% set search = search|merge({'#attributes': attr}) %}

{{ search }}

```

Or add a third merge and merge the field back into the form. Then output the form as usual:

```
{% set search = form.search_api_fulltext %}
{% set attr = form.search_api_fulltext['#attributes'] %}
{% set attr = attr|merge({'placeholder': 'Enter search term'|t}) %}
{% set search = search|merge({'#attributes': attr}) %}

{% set form = form|merge({'search_api_fulltext': search}) %}
{{ form }}

```
> 5 votes

# Answer
It is possible using merge filter, I do this with great success on menu items:

```
{% set item = item|merge({'attributes': item.attributes.addClass('new-class')}) %}

```

I think you should able to do something like this with deeper nesting:

```
{% set form_submit = form.submit %}
{% set form_submit = form_submit|merge({'attributes': form_submit.attributes.addClass('test')}) %}
{% set form = form|merge({'submit': form_submit}) %}
{{ form.submit }}

```

Though you could just as well render `form_submit` and exclude it from being rendered along with `form` elsewhere.
> 3 votes

# Answer
Well, I really don't know if you have a particular reason(like keeping everything on the HTML file) to do this in Twig, not in preprocess, but I can give you a code that worked for me on preprocess:

```
function hook_form_FORM_ID_alter(&$form, &$form_state) {
  $form['actions']['submit']['#attributes']['class'] = array('btn-primary form-control');
}

```

This code should be in the your\_theme.theme file(like the old template.php for Drupal 7).
> 2 votes

# Answer
for twig form add attribute :

```
  {# add a "foo" class to it #}
  {{ form_widget(form.name, { 'attr': {'class': 'foo'} }) }}
 for buttons
 {{ form_widget(delete_form.submit, { 'attr': {'class': 'btn btn-danger btn-lg', 'type': 'button'} }) }}

```

=============================================

if your question for drupal form then code is give below and it's working for me.

```
function MY_MODULE_Name_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id == 'user_register_form') {
      $form['actions']['submit']['#attributes'] = array('onclick' => 'if(!confirm_reg(this.id)){return false;}');
    }
 }

```

and this code should not be in theme file it's in your modulename.module file hope this helps you...
> 1 votes

# Answer
Add to your templates folder

**input--submit.html.twig**

```
{%
set classes = [
   'test',
   'test2',
 ]
%}
<input{{ attributes.addClass(classes) }} />

```
> 1 votes

# Answer
Everyone is quite right, the 'drupal' way of doing things is to have hook\_form\_alter - preferably hook\_form\_FORM\_ID\_alter and add the class before it gets rendered.

If you are looking for an alternative way - you could get the form element HTML from drupal using render($form\['submit'\]) (I am assuming this is for the submit button) so

```
$submitHTML = render($form['submit']);

```

You can then pass this HTML to your TWIG template as a variable.

```
$markup = array('markup' => $submitHTML);
$template = $twig->loadTemplate('myTwigFile.twig');
$output = $template->render($markup);

```

In your TWIG template you can wrap the HTML in whatever you want and simply render the raw HTML you got from drupal.

```
<div class="clearfix">
  {{markup[0]|raw}}
</div>

```

Note that I am referencing the submit button markup as the first element of the markup array - so you could add other form elements to the same array.

I have omitted some plumbing code (setup) - but hopefully you get the idea.
> 0 votes

# Answer
I wanted to do something similar but I also wanted to make it as short as possible. Here's my take. I simply add some classe to a field content :

```
{% set attr = {'class': 'badge text-bg-primary'} %}
{% set tag = item.content|merge({'#attributes': attr}) %}

```
> 0 votes

---
Tags: 8, theming
---


# Question
Title: How to change the title and add a placeholder to password and confirm password field through hook_form_alter?
How can i remove the label of the password and the confirm password field through hook\_form\_alter functionality ?

Tried the below:

> $form\['pass'\]\['#title'\]= t(''); $form\['pass'\]\['#description'\]= t('');
>
> $form\['account'\]\['pass'\]\['pass1'\]\['#attributes'\]\['placeholder'\]= t('Password');
>
> $form\['account'\]\['pass'\]\['pass2'\]\['#attributes'\]\['placeholder'\]= t('Confirm Password');

But no change in the behavior.

This is the exact code that i have written in my .theme file.

```
   function THEMENAME_form_user_pass_reset_alter(&$form, &$form_state, $form_id) {
  // Get default process function array:
  $element_info = element_info('password_confirm');
  $process = $element_info['#process'];
  // Add our process function to the array:
  $process[] = 'port_process_password_confirm';
  $form['account']['pass']['#process'] = $process;
}

function port_process_password_confirm($element) {
  $element['pass1']['#title'] = t('New password');
  $element['pass2']['#title'] = t('Confirm new password');
  return $element;
}

```

The output that i am getting is as per the below image

# Answer
> 2 votes
In D8 You can try the code below:

```
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\PasswordConfirm;

function mymtheme_form_user_pass_reset_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['account']['pass']['#process'][] = 'mytheme_form_user_register_form_process_pass';
}

function mytheme_form_user_register_form_process_pass(&$element, FormStateInterface $form_state, &$complete_form) {
  $element = PasswordConfirm::processPasswordConfirm($element, $form_state, $complete_form);
  $element['pass1']['#placeholder'] = t('Password here please');
  $element['pass2']['#placeholder'] = t('Password again here please');
  $element['pass1']['#title'] = t("New password");
  $element['pass2']['#title'] = t("New password confirm");
  return $element;
}

```

See more PasswordConfirm.php

In D7

```
function mymtheme_form_user_pass_reset_form_alter(&$form, &$form_state, $form_id) {
   // #process handler to modify the password element expanded by Field API.
   $form['pass']['#process'] = array('form_process_password_confirm', 'register_alter_password_confirm');
}

/**
 * Alter password and confirm password fields to remove title and insert placeholder.
 */
function register_alter_password_confirm($element) {
    $element['pass1']['#attributes']['placeholder'] = t("Password");
    $element['pass2']['#attributes']['placeholder'] = t("Confirm password");
    $element['pass1']['#title'] = t("New Password");
    $element['pass2']['#title'] = t("New password confirm");
    return $element;
}

```

See more https://www.drupal.org/project/drupal/issues/540340#comment-2782800

# Answer
> 1 votes
You're altering the wrong form, you should alter the user\_form, like this:

```
function THEMENAME_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id){
  $form['account']['pass']['#process'][] = '_THEMENAME_process_password_confirm';
}

function _THEMENAME_process_password_confirm($element, FormStateInterface $form_state, &$complete_form){
  $element = PasswordConfirm::processPasswordConfirm($element, $form_state, $complete_form);
  $element['pass1']['#title'] = t('New password');
  $element['pass2']['#title'] = t('Confirm new password');
  return $element;
}

```

# Answer
> 1 votes
Code to Alter pass & confirm pass field title along **with password strength indicator display**: Drupal(8/9/10)

```
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\PasswordConfirm;

function mytheme_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id){
  $form['account']['pass']['#process'][] = 'mytheme_form_user_register_form_process_pass';
}

function mytheme_form_user_register_form_process_pass(&$element, FormStateInterface $form_state, &$complete_form){
  $element = PasswordConfirm::processPasswordConfirm($element, $form_state, $complete_form);
  // Update the title
  $element['pass1']['#title'] = t('New password');
  $element['pass2']['#title'] = t('Confirm New password');
  // Added core 'user_form_process_password_confirm' function
  // so that Password strength indicator visible after title  update
  $element['password_confirm']['#process'][] = 'user_form_process_password_confirm';
  return $element;
}

```

**Note :** Whenever update title of pass & confirm pass field , **password strength indicator missing in case of user register & user edit page** , so added below line code to display password strength indicator along with update title of pass & confirm pass field

```
$element['password_confirm']['#process'][] = 'user_form_process_password_confirm';

```

# Answer
> -1 votes
The above solution worked for me but the problem was wrong function name. The solution that worked for me :

```
function THEMENAME_form_user_pass_reset_alter(&$form, FormStateInterface $form_state, $form_id){
    $form['pass']['#title'] = t('');
    $form['pass']['#description'] = t('');
    $form['pass']['#process'][] = 'test_form_user_register_form_process_pass';
    $form['actions']['submit']['#attributes'] = ['class' => ['registerbtn']];
}

function test_form_user_register_form_process_pass(&$element, FormStateInterface $form_state, &$complete_form) {
  $element = PasswordConfirm::processPasswordConfirm($element, $form_state, $complete_form);
  $element['pass1']['#placeholder'] = t('Password here please');
  $element['pass2']['#placeholder'] = t('Password again here please');
  $element['pass1']['#title'] = t("");
  $element['pass2']['#title'] = t("");
  return $element;
}

```

---
Tags: theming, forms, hooks
---


# Question
Title: The service "redirect.request_subscriber" has a dependency on a non-existent service "path_alias.manager"
We have inherited a Multisite Drupal setup and are managing the migration for a client. We have the codebase set up locally and have two of the sites up and running. We are hitting an error on the third though:

> Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: The service "redirect.request\_subscriber" has a dependency on a non-existent service "path\_alias.manager". in Symfony\Component\DependencyInjection\Compiler\CheckExceptionOnInvalidReferenceBehaviorPass-\>processValue() (line 86 of /Users/{hidden}/Sites/{hidden}/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php).

We're not sure why this error is displaying on this one site and not on the others. Can anyone help please? Drupal core is up to date - running 9.3.12.

# Answer
> 0 votes
For me, a search and replace in the .sql file changed path\_alias.manager data entries unwanted ... so needed to get my data back right ..

---
Tags: dependency-injection
---


title: Get page title form url

text:
# Question
Title: Get page title form url
How can I get the page title by its URL, for example http://example.com/en/news-events, which is not for the current page?

# Answer
> 0 votes
From below code example you can get the page title as your requirement

```
 $path = \Drupal::service('path.alias_manager')->getPathByAlias('/news-events');
 if(preg_match('/node\/(\d+)/', $path, $matches)) {
  $node = \Drupal\node\Entity\Node::load($matches[1]);
 }
 echo $node->getTitle();

```

Hope this helps. :)

# Answer
> -1 votes
Try this solution for get title from view page url.

in your custom module ==\> .module file

```
use Drupal\views\ViewExecutable;

function display_form_mode_views_post_render(ViewExecutable $view) {
   print($view->getTitle($title));
}

```

Hope this helps.

---
Tags: 8, uri
---


# Question
Title: Expose taxonomy term contextual filter in Layout Builder
I have created a view block for a content type of card. The card content type also has a taxonomy vocabulary where users can add new terms to that taxonomy vocabulary. I have a contextual filter on this view block which filters by taxonomy ID. And this works in the views preview pane, e.g. I enter `1` and cards with the taxonomy term ID 1 are rendered in the preview.

However, when I use Layout Builder and select the view block, I do not get an option to input what taxonomy term ID I want to use for the block. What am I doing wrong?

# Answer
> 0 votes
Pass value in contextual filter programmatically : using hook\_views\_pre\_view(): (can add either .theme/.module file)

```
use Drupal\views\ViewExecutable;

function Mythemename/Mymodulename_views_pre_view(ViewExecutable $view, $display_id, array &$args) {

  if ($view->id() == 'view_machine_name' && $display_id == 'view_display_machine_name') {
      $node = \Drupal::routeMatch()->getParameter('node');
      if ($node instanceof \Drupal\node\NodeInterface) {
        // get taxonmoy field value from current node page
        $tid = $node->get('field_taxonomy')->target_id;
        if(!empty($tid)){
          $args[0] = $tid;
        }
      }
  }
}

```

---
Tags: views, layout-builder
---


# Question
Title: How can I delete an existing path alias?
In Drupal 7, a path alias can be deleted with code similar to the following one.

```
path_delete(array('source' => "problem/{$problem->nid}/{$problem_src->nid}"));

```

How can I delete path aliases in Drupal 9?

Thanks..

# Answer
> 4 votes
Delete path alias: Drupal(8/9/10)

```
$path_alias_manager = \Drupal::entityTypeManager()->getStorage('path_alias');
// Load path alias by path
$alias_objects = $path_alias_manager->loadByProperties([
  'path' => '/node/' . $nid
]);
foreach ($alias_objects as $alias_object) {
  // Delete the path alias
  $alias_object->delete();
}

```

Note: Drupal(8/9/10) **"path"** field column maintained instead of **"source"** column

---
Tags: 9, path-aliases
---


# Question
Title: How to programmatically add content to a group in the Group Module?
I'm using the Group module. If I have a group type such as Project, and I have a content type such as Article, and I programmatically created a new article node using Node::create(), how can I in the same code add this article as content to a project that I choose?

# Answer
If the problem is just to add an article to a group, the group module directly offers the following function for this. See `GroupInterface.php`

```
public function addContent(ContentEntityInterface $entity, $plugin_id, $values = []);

```

In an example `$group->addContent($node, $pluginId);`
> 1 votes

# Answer
Given you have the group entity and node entity, you can simply create a GroupContent entity.

```
$groupEntity = ... The group entity.
$node = ... The node entity.

$type = $type = $groupEntity->getGroupType()->id() . '-group_node-' . $node->getType();

$groupContentEntity = \Drupal\group\Entity\GroupContent::create([
    'gid' => $groupEntity->id(),
    'entity_id' => $node->id(),
    'type' => $type,
]);
$groupContentEntity->save();

```
> 0 votes

# Answer
Once installed the type of relationship in the group with the code feels should be sufficient for Drupal 8, 9, 10.

```
$node = Node::create([
  'type' => 'node_type',
  'title' => 'My title',
  'uid' => $uid,
]);
$node->save();

$group->addRelationship($node, 'group_node:company_access_request');

```
> 0 votes

---
Tags: nodes, 8, group
---


# Question
Title: How can I programmatically save node components?
There is a site with number of nodes including layout canvas and site studio components available in a node.

When there will be changes in one of the components (new field added with default value), if I want new component changes to existing page/node, I will need to edit the node, save the component, and save the node. After these steps, I am getting the component change reflected on the node.

Is there any way to programmatically doing that?

With `\Drupal::entityTypeManager()->getStorage('cohesion_layout')->load($uid)`, I get the older JSON component value.

# Answer
```
$entity = \Drupal::entityTypeManager()->getStorage('cohesion_layout')->load($node->get('field_layout_canvas')->getValue()[0]['target_id']);
            $layoutCanvas = $entity->getLayoutCanvasInstance();
            foreach ($layoutCanvas->iterateCanvas() as $element) {
                if ($element->getProperty('uid') === 'cpt_cmpt') {
                    $model = $element->getModel();
                    if (!property_exists($model->getValues(), '4df4fbe1-1e4e-4a4d-9032-5f81f270731b')) {
                        $model->setProperty('5ef0h4e0-1e4e-4a4d-9032-5f81f849012b', "the value");
                    }
    $entity->setJsonValue(json_encode($layoutCanvas));
                    $entity->save();
                }
            }

```

Try like this, it worked for me
> -2 votes

---
Tags: nodes, 9
---


# Question
Title: Generate new bearer token with simple_oauth programmatically?
I have a custom service and in the custom service, I want to generate a new Bearer token for the current user ( it's logged in) with simple\_oauth module. in its documentation is has not mentioned how can I generate new a new token for current logged in user. **So, how can I generate a new Bearer token for current logged in user?**

# Answer
> 2 votes
I assume you need an access token for some API call, so to have it generated automatically when you call some API method in your service.

I usually go with the following set up:

1. Install kamermans/guzzle-oauth2-subscriber with composer
2. Define config `my_module.auth.yml` and import it

```
client_id: test
client_secret: test
base_uri: 'https://some-external-service/auth/token'

```
3. Create the following services/factories `my_module.services.yml`

```
services:
  my_module.handler_stack:
    class: GuzzleHttp\HandlerStack
    factory: ['GuzzleHttp\HandlerStack', 'create']
    calls:
      - [push, ['@my_module.oauth2_middleware']]

  my_module.client_factory:
    class: Drupal\my_module\Client\ClientFactory
    arguments: ['@config.factory']

  my_module.oauth2_middleware_factory:
    class: Drupal\my_module\Auth\OAuth2MiddlewareFactory
    arguments: ['@config.factory']

  my_module.oauth2_middleware.client:
    class: GuzzleHttp\Client
    factory: 'my_module.client_factory:createClient'
    arguments:
      - 'my_module.auth'

  my_module.oauth2_middleware:
    class: kamermans\OAuth2\OAuth2Middleware
    factory: 'my_module.oauth2_middleware_factory:createMiddleware'
    arguments:
      - '@my_module.oauth2_middleware.client'
      - 'my_module.auth'

```
4. Define your middleware factory `OAuth2MiddlewareFactory.php`

```
<?php

namespace Drupal\my_module\Auth;

use Drupal\Core\Config\ConfigFactoryInterface;
use GuzzleHttp\ClientInterface;
use kamermans\OAuth2\GrantType\ClientCredentials;
use kamermans\OAuth2\OAuth2Middleware;

/**
 * Factory for OAuth2 Guzzle middleware, configured from configuration objects.
 *
 * @package Drupal\my_module\Auth
 */
class OAuth2MiddlewareFactory {

  /**
   * The configuration factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  private $configFactory;

  /**
   * OAuth2MiddlewareFactory constructor.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The configuration factory to use.
   */
  public function __construct(ConfigFactoryInterface $configFactory) {
    $this->configFactory = $configFactory;
  }

  /**
   * Creates an OAuth2 Guzzle Middleware.
   *
   * @param \GuzzleHttp\ClientInterface $client
   *   The guzzle HTTP client to use for obtaining client credentials.
   * @param string $configName
   *   Name of the configuration object to use.
   *
   * @return \kamermans\OAuth2\OAuth2Middleware
   *   The Guzzle Oauth2 middleware.
   */
  public function createMiddleware(ClientInterface $client, string $configName): OAuth2Middleware {
    $configuration = $this->configFactory->get($configName);

    $reauth_config = [
      'client_id' => $configuration->get('client_id'),
      'client_secret' => $configuration->get('client_secret'),
      'state' => time(),
    ];

    if ($configuration->get('scope')) {
      $reauth_config['scope'] = $configuration->get('scope');
    }

    $grant_type = new ClientCredentials($client, $reauth_config);

    return new OAuth2Middleware($grant_type);
  }

}

```
5. Define client factory `ClientFactory.php`

```
<?php

namespace Drupal\my_module\Client;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;

/**
 * Factory for Guzzle HTTP clients, configured from configuration objects.
 *
 * @package Drupal\my_module\Client
 */
class ClientFactory {

  /**
   * The configuration object factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * ClientFactory constructor.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The configuration object factory.
   */
  public function __construct(ConfigFactoryInterface $configFactory) {
    $this->configFactory = $configFactory;
  }

  /**
   * Creates a Guzzle HTTP client.
   *
   * @param string $configName
   *   Name of the configuration object to use.
   * @param array $clientConfig
   *   Additional configuration settings for the Guzzle HTTP client.
   *
   * @return \GuzzleHttp\Client
   *   A configured Guzzle HTTP client.
   */
  public function createClient(string $configName, array $clientConfig = []): Client {
    $config = $this->configFactory->get($configName);

    $prepared_config = $this->prepareClientConfig($config, $clientConfig);

    return new Client(
      $prepared_config
    );
  }

  /**
   * Prepares the configuration of the Guzzle HTTP client.
   *
   * Priority of the configuration:
   *   1. configuration in $config, limited to certain common settings
   *   2. configuration in $clientConfig passed in via the service container
   *   3. defaults set in this method.
   *
   * @param \Drupal\Core\Config\ImmutableConfig $config
   *   The configuration object to use.
   * @param array $clientConfig
   *   Additional configuration settings for the Guzzle HTTP client.
   *
   * @return array
   *   The client configuration.
   */
  protected function prepareClientConfig(ImmutableConfig $config, array $clientConfig = []): array {
    $prepared_config = $clientConfig;

    $prepared_config['base_uri'] = $config->get('base_uri');

    $defaults = [
      RequestOptions::TIMEOUT => $clientConfig[RequestOptions::TIMEOUT] ?? 10,
      RequestOptions::CONNECT_TIMEOUT => $clientConfig[RequestOptions::TIMEOUT] ?? 10,
    ];

    foreach (array_keys($defaults) as $option) {
      $prepared_config[$option] = $config->get($option) ?? $defaults[$option];
    }

    return $prepared_config;
  }

}

```
6. Define your client by using the factory in `my_module.services.yml`

```
  my_module.my_service.client:
    class: GuzzleHttp\Client
    factory: 'my_module.client_factory:createClient'
    arguments:
      - 'my_module.my_service'
      - auth: oauth
        handler: '@my_module.handler_stack'

```

where `my_module.my_service.yml` is

```
base_uri: 'https://some-external-service/a-service-namespace/'

```
7. Create your service that will trigger API by using the client you created by the factory earlier

```
  my_module.service.region:
    class: Drupal\my_module\Service\MyService
    arguments: ['@my_module.my_service.client']

```

and this is `MyService.php`

```
<?php

namespace Drupal\my_module\Service\Region;

use GuzzleHttp\ClientInterface;

/**
 * API client for my service.
 *
 * @package Drupal\my_module\Service
 */
class MyService {

  /**
   * A guzzle HTTP client.
   *
   * @var \GuzzleHttp\ClientInterface
   */
  private $client;

  /**
   * MyService constructor.
   *
   * @param \GuzzleHttp\ClientInterface $client
   *   A Guzzle HTTP client.
   */
  public function __construct(ClientInterface $client) {
    $this->client = $client;
  }

  /**
   * Finds something from the my service.
   *
   * @param string $langCode
   *   The language code.
   * @param string $postalCode
   *   The postal code.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   */
  public function findSomething(string $langCode, string $value): Region {
    $response = $this->client->request('GET', 'my-service-uri/find',
      [
        'headers' => [
          'Accept' => 'application/json',
          'Accept-Language' => $langCode,
        ],
        'query' => [
          'value' => $value,
        ],
      ]
    );

    $json = $response->getBody()->getContents();

    // Do something here, you may use serializer to deserialize the content
    // here with the custom defined model or some other fancy stuff.

  }

}

```

This might too much, but you may find some useful code

# Answer
> 0 votes
POST request to /oauth/token generates a new token (don't forget to add proper body params)

You can also use a refresh token to generate a new access token by using grant\_type 'refresh\_token'

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


# Question
Title: Revolution slider issue with AjaxResponse
I have an issue after drupal update to version 10 with Revolution Slider. This is an error I get:

```
Exception Error: "Call to undefined method Drupal\\\\Core\\\\Ajax\\\\AjaxResponse::create()" at /web/modules/custom/revslider/src/Controller/RevSliderAjax.php line 78.

```

This is the function with a code generation error:

```
protected function ajaxMediaHandle() {
    $action = RevSliderFunctions::getRequestVariable('action');
    switch ($action) {
      case 'delete_media':
        $fid = RevSliderFunctions::getRequestVariable('fid');
        RevSliderMedia::removeFile($fid);
        break;

      case 'upload_media':
        RevSliderMedia::uploadMedia();
    }
    $result = RevSliderMedia::getMedia();
    return AjaxResponse::create($result); // line 78

    }

```

Please advise, thanks!

# Answer
JsonResponse::create() was deprecated and is in the current Symfony version no longer available. It did not added any features other than that you need now an extra pair of brackets for daisy-chaining:

```
return (new AjaxResponse())->addCommand(new AlertCommand('Alert'));

```
> 2 votes

# Answer
Thanks!

I have been trying to resolve this issue and found the correct syntax to get the module up and running...

I have change the line 78 from

```
return AjaxResponse::create($result);

```

to

```
return new AjaxResponse($result);

```

And that fix my issue.
> 0 votes

---
Tags: ajax
---


# Question
Title: I am trying to install Drupal Commerce, I get error that prevents installation, I don't get what it says about ../private folder
Can somebody specify where this folder should exist?

I created it in the directory containing the *vendor* directory, in the *files* directory, outside of the *files* and in the site root directory, but I keep getting this error message.

> Writable (public download method)
> The directory ../private is not writable. An automated attempt to create this directory failed, possibly due to a permissions problem. To proceed with the installation, either create the directory and modify its permissions manually or ensure that the installer has the permissions to create it automatically. For more information, see INSTALL.txt or the online handbook.

# Answer
> 3 votes
The private files directory is a standard Drupal setup task, and is well-documented. Below is its description in `default.settings.php`. It is in `settings.php` where you configure this directory. Not that the directory "must be absolute", meaning, it must start with a `/` on Linux filesystems.

"Writable" means that the directory's permissions must be such that Drupal must be able to write files into the directory you specify.

```
/**
 * Private file path:
 *
 * A local file system path where private files will be stored. This directory
 * must be absolute, outside of the Drupal installation directory and not
 * accessible over the web.
 *
 * Note: Caches need to be cleared when this value is changed to make the
 * private:// stream wrapper available to the system.
 *
 * See https://www.drupal.org/documentation/modules/file for more information
 * about securing private files.
 */
# $settings['file_private_path'] = '';

```

---
Tags: 9
---


# Question
Title: How do I override settings.php for Symfony Mailer to use Mailhog for local development?
Now that I am supporting Drupal 10, I needed to set up Mailhog to allow local capturing of emails when I'm testing in my local Docker environment.

I used to use the SMTP and Mail System modules and used overrides in my settings.php file to set the port and host etc to mailhog i.e. host 'mail' and port '1025' as per my local Docker set up.

I have switched to using Symfony Mailer now for sending emails in production. What is the syntax for the override in settings.php? I have searched but there is not a clear answer - there was a lot of discussion around Sendmail and Swiftmailer, but I want a simple answer to overriding my SMTP transport setting to use another hostname and port.

# Answer
These are the correct overrides for Symfony Mailer for my setup. Just replace the host, port username and password with your own. The 'Perform TLS peer verification' tickbox is dealt with on the last line - 'query\_peer'. 'True' sets this checkbox to yes.

```
$config['symfony_mailer.mailer_transport.smtp']['configuration']['port']="1025";
$config['symfony_mailer.mailer_transport.smtp']['configuration']['host']="mail";
$config['symfony_mailer.mailer_transport.smtp']['configuration']['user']="";
$config['symfony_mailer.mailer_transport.smtp']['configuration']['pass']="";
$config['symfony_mailer.mailer_transport.smtp']['configuration']['query']['query_peer']=true;

```

If you do a `drush config:get` on your production setup, you will get something like this:

```
www-bridge-user@a8e972098567:/var/www/html$ vendor/bin/drush config:get symfony_mailer.mailer_transport.smtp
uuid: a0c04a65-de79-4c81-9466-ad87c6ea1298
langcode: en
status: true
dependencies: {  }
id: smtp
label: SMTP
plugin: smtp
configuration:
  user: ''
  pass: ''
  host: your-smtp-host-name.com
  port: 587
  query:
    verify_peer: true
    local_domain: ''
    restart_threshold: null
    restart_threshold_sleep: null
    ping_threshold: null

```

I used the same YML structure in creating a block for settings. Each indent is a new set of brackets after the top level key of `symfony_mailer.mailer_transport.smtp`

**NOTE WELL: If you look at the UI or go a config:get, you will NOT see the overrides you have put in settings.php, so ensure you test this thoroughly.**

Hope this helps others. Might be useful if you wish to keep your SMTP settings out of the UI as well.
> 1 votes

---
Tags: emails, configuration
---


# Question
Title: How can I export all webform structures?
How can I export forms generated from a Drupal 7 site using webform?

The data is meant to be used to recreate a form generator tool by another team (who is not necessarily using Drupal).

# Answer
> 0 votes
node export is a first option

it gives

```
   array(
  (object) array(
      'vid' => '3593',
      'uid' => '1',
      'title' => 'test',
      'log' => '',
      'status' => '1',
      'comment' => '0',
      'promote' => '0',
      'sticky' => '0',
      'vuuid' => '584c561c-cb8c-498e-a4f2-303afcf444be',
      'nid' => '3280',
      'type' => 'webform',
      'language' => 'fr',
      'created' => '1700668763',
      'changed' => '1700670699',
      'tnid' => '0',
      'translate' => '0',
      'uuid' => '806f4462-86b1-4cbd-bebe-478d1efc4894',
      'revision_timestamp' => '1700670699',
      'revision_uid' => '1',
      'field_diffusion' => array(
        'und' => array(
          array(
            'tid' => '36',
          ),
        ),
      ),
      'field_form_header' => array(),
      'field_form_files' => array(),
      'rdf_mapping' => array(
        'rdftype' => array(
          'sioc:Item',
          'foaf:Document',
        ),
        'title' => array(
          'predicates' => array(
            'dc:title',
          ),
        ),
        'created' => array(
          'predicates' => array(
            'dc:date',
            'dc:created',
          ),
          'datatype' => 'xsd:dateTime',
          'callback' => 'date_iso8601',
        ),
        'changed' => array(
          'predicates' => array(
            'dc:modified',
          ),
          'datatype' => 'xsd:dateTime',
          'callback' => 'date_iso8601',
        ),
        'body' => array(
          'predicates' => array(
            'content:encoded',
          ),
        ),
        'uid' => array(
          'predicates' => array(
            'sioc:has_creator',
          ),
          'type' => 'rel',
        ),
        'name' => array(
          'predicates' => array(
            'foaf:name',
          ),
        ),
        'comment_count' => array(
          'predicates' => array(
            'sioc:num_replies',
          ),
          'datatype' => 'xsd:integer',
        ),
        'last_activity' => array(
          'predicates' => array(
            'sioc:last_activity_date',
          ),
          'datatype' => 'xsd:dateTime',
          'callback' => 'date_iso8601',
        ),
      ),
      'path' => array(
        'pid' => '68243',
        'source' => 'node/3280',
        'alias' => 'public/test-0',
        'language' => 'fr',
      ),
      'webform' => array(
        'nid' => '3280',
        'next_serial' => '1',
        'confirmation' => '',
        'confirmation_format' => NULL,
        'redirect_url' => '<confirmation>',
        'status' => '1',
        'block' => '0',
        'allow_draft' => '0',
        'auto_save' => '0',
        'submit_notice' => '1',
        'confidential' => '0',
        'submit_text' => '',
        'submit_limit' => '-1',
        'submit_interval' => '-1',
        'total_submit_limit' => '-1',
        'total_submit_interval' => '-1',
        'progressbar_bar' => '0',
        'progressbar_page_number' => '0',
        'progressbar_percent' => '0',
        'progressbar_pagebreak_labels' => '0',
        'progressbar_include_confirmation' => '0',
        'progressbar_label_first' => 'Début',
        'progressbar_label_confirmation' => 'Terminé',
        'preview' => '0',
        'preview_next_button_label' => '',
        'preview_prev_button_label' => '',
        'preview_title' => '',
        'preview_message' => '',
        'preview_message_format' => NULL,
        'preview_excluded_components' => array(),
        'record_exists' => TRUE,
        'roles' => array(
          '1',
          '2',
        ),
        'emails' => array(),
        'components' => array(
          1 => array(
            'nid' => 3280,
            'cid' => '1',
            'pid' => '0',
            'form_key' => 'select',
            'name' => 'select',
            'type' => 'select',
            'value' => '',
            'extra' => array(
              'items' => "option_1|option 1\r\noption_2|option2",
              'multiple' => 0,
              'title_display' => 'before',
              'description_above' => 0,
              'private' => 0,
              'wrapper_classes' => '',
              'css_classes' => '',
              'aslist' => 0,
              'empty_option' => '',
              'optrand' => 0,
              'other_option' => NULL,
              'other_text' => 'Autre...',
              'description' => '',
              'custom_keys' => FALSE,
              'options_source' => '',
              'analysis' => TRUE,
            ),
            'required' => '0',
            'weight' => '0',
            'page_num' => 1,
          ),
          2 => array(
            'nid' => 3280,
            'cid' => '2',
            'pid' => '0',
            'form_key' => 'texte',
            'name' => 'texte',
            'type' => 'textfield',
            'value' => '',
            'extra' => array(
              'title_display' => 'before',
              'description_above' => 0,
              'private' => 0,
              'wrapper_classes' => '',
              'css_classes' => '',
              'width' => '',
              'maxlength' => '',
              'minlength' => '',
              'field_prefix' => '',
              'field_suffix' => '',
              'disabled' => 0,
              'unique' => 0,
              'description' => '',
              'placeholder' => '',
              'attributes' => array(),
              'analysis' => FALSE,
            ),
            'required' => '0',
            'weight' => '1',
            'page_num' => 1,
          ),
        ),
        'conditionals' => array(
          array(
            'nid' => '3280',
            'rgid' => '0',
            'andor' => NULL,
            'weight' => '-9',
            'rules' => array(
              array(
                'nid' => '3280',
                'rgid' => '0',
                'rid' => '0',
                'source_type' => 'component',
                'source' => '1',
                'operator' => 'equal',
                'value' => 'option_1',
              ),
            ),
            'actions' => array(
              array(
                'nid' => '3280',
                'rgid' => '0',
                'aid' => '0',
                'target_type' => 'component',
                'target' => '2',
                'invert' => '0',
                'action' => 'show',
                'argument' => '',
              ),
            ),
          ),
        ),
      ),
      'name' => 'admin',
      'picture' => '0',
      'data' => 'a:2:{s:7:"overlay";i:1;s:5:"block";a:1:{s:10:"aggregator";a:1:{s:6:"feed-2";i:1;}}}',
      'workbench_access' => array(
        42 => '42',
      ),
      'menu' => NULL,
      'node_export_drupal_version' => '7',
    ),
)

```

---
Tags: 7, webforms, migrations
---


title: Date popup in exposed filter

text:
# Question
Title: Date popup in exposed filter
I'm using Drupal 7 with views 3.

I have used an exposed filter for a date field and I want to provide option to choose date from datepopup for date filter? How can I do this?

# Answer
> 14 votes
The Better Exposed Filters module integrates with the date type fields, including the date popup. You can use this module to easily add an exposed filter with the date popup.

There are some known issues with BEF's integration with the date module; from the module page:

> (Note: Support for fields supplied by the Date module is a little funky until #392836: Exposed Date filter format (in Views) and/or #502824: Date format in exposed filter (views) are resolved).

Also, you can only add this type of filter to entity fields at the moment, not properties. There are various discussions going on about this.

# Answer
> 13 votes
You don't need BEF to get popup calendar with exposed view filters. You just need "Date pop up" and "date views" submodules.

* When creating new exposed filter in "Filter" dropdown select "Date"
* then choose the Date filter
* choose a date field (for instance "Date: Date (node)")
* in extra settings config , in the "Date selection form element" section select "Popup"
* follow other regular steps.

# Answer
> 0 votes
Drupal 9/10 I Just did a normal exposed filter (for a timestamp / date) field Selected between dates left all defaults blank then added (in a module)

```
/**
 * Implements hook_form_ID_alter().
 */
function SOMEMODULE_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $view_ids = ['my_view_id'];
  if ($form_id === 'views_exposed_form') {
    $view = $form_state->getStorage('view');
    if (!empty($view) && in_array($view['view']->id(), $view_ids)) {
      $form['field_timestamp_wrapper']['field_timestamp']['min']['#type'] = 'date';
      $form['field_timestamp_wrapper']['field_timestamp']['max']['#type'] = 'date';
      $form['field_timestamp_wrapper']['field_timestamp']['min']['#title'] = t('From');
      $form['field_timestamp_wrapper']['field_timestamp']['max']['#title'] = t('To');
    }
  }
}

```

---
Tags: views, datetime
---


# Question
Title: BaseFieldDefinition setDisplayOptions ... type = 'string_textfield' ... unable to set default placeholder or size?
I'm unable to get a default placeholder and/or size to register against a BaseFieldDefinition. I'm trying something like:

```
$fields['company_name'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Company Name'))
      ->setDescription(t('What\'s your company called?'))
      ->setDefaultValue('')
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'settings' => [
          'display_label' => TRUE,
          'size' => 10,
          'placeholder' => '',
        ],
        'weight' => '9',
      ])
      ->setDisplayConfigurable('form', TRUE);

```

But when I enable my module, and check the 'Manage Form Display' tab for the relevant entity, it shows the defaults (size = 60, placeholder = {null}).

Does anyone know how to get these working..? Especially the `placeholder` one.

# Answer
> 0 votes
```
$fields['mobile_number'] = BaseFieldDefinition::create('string')
  ->setRevisionable(TRUE)
  ->setLabel(t('Mobile Number'))
  ->setDescription(t('Enter Mobile Number with Country Code.'))
  ->setRequired(TRUE)
  ->setSetting('max_length', 255)
  ->setPropertyConstraints('value', ['Length' => ['max' => 20]])
  ->addPropertyConstraints('value', ['Regex' => ['pattern' => '/^(\+|00)[0-9]+$/']])
  ->addConstraint('UniqueField')
  ->setDisplayOptions('form', [
    'type' => 'string_textfield',
    'weight' => -5,
    'settings' => [
      'size' => 30,
      'placeholder' => '+919876543210',
    ],
  ])
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayOptions('view', [
    'label' => 'above',
    'type' => 'string',
    'weight' => -5,
  ])
  ->setDisplayConfigurable('view', TRUE);

```

This works for me.

---
Tags: 8, entities, plugins
---


# Question
Title: Is possible to have OR logic on block visibility?
I am on D10.

I need to place several blocks on Block Layout having different visibility conditions: for example one of them should visible BOTH in the home page and in every article of the site.

I'd use therefore "Content Type" condition and "Request Path". However,I've realized that different condition plugins work with AND logic: if I check both, the block isn't visible in neither front page or articles.

Is possible somehow to specify that I want the conditions to work with OR logic?

I'd avoid to place every block several time, one for each condition, to avoid the cluttering of the block layout and the difficulties to maintain it in the future.

# Answer
> 4 votes
Use the module Block Visibility Groups, This module not only allows you to combine conditions with OR logic, but also makes them reusable, so you don't need to repeat the complex logic for each block if you have multiple blocks showing on the same pages.

---
Tags: blocks, plugins
---


title: Adding a Javascript library

text:
# Question
Title: Adding a Javascript library
I apologize for asking this for the 100th time but I just cannot understand the previous answers. There are 2 modules (form placeholder and chosen)where cannot get their libraries included.

Step 1: I downloaded their libraries and placed them in the `libraries` folder. Step 2: I included 2 new libraries in the `THEME.info.yml`

```
libraries-extend:
  bootstrap/framework:
    - bootstrap_kampuster/framework

libraries:
  - bootstrap_kampuster/chosen
  - jquery.placeholder

```

However, neither one of the 2 is loading right now. Is there anything else I need to add somewhere? FYI, my `THEME.libraries.yml` looks like this;

```
framework:
  css:
    theme:
      css/style.css: {}
      css/animate.min.css: {}

  js:
    js/custom.js: {}
    js/misc/waypoints.min.js: {}

    dependencies:
    - core/jquery

```

# Answer
You need to add this to YOURTHEME.theme file:

```
function siderise_preprocess_block(&$variables) {
  // Attach the global-scripts library to all blocks.
  $variables['#attached']['library'][] = 'YOURTHEME/YOURFRAMEWORK';
}

```

make sure you update the function with your theme and your framework in the bottom line
> 0 votes

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


# Question
Title: For ECA, how can I create a flag that unpublishes a comment, using 'classic modeller'?
Rules and Rules\_flag is not working well in Drupal 10.1, though I had a solution working in Drupal 9.5.

The goal: a flag on each comment that unpublishes the comment, when a user clicks the flag.

Since this no longer works in Drupal 10, I've attempted to create this solution in ECA module with ECA\_flag and the Classic Modeller (eca\_cm).

The modeler is mystifying, however. I'm pretty much randomly keying in guesses and selecting random values from dropdowns.

Can anyone who has been able to build this functionality with ECM share an example? An example using any of the modelers would be helpful. Since this is a very basic use case, I've gone with Classic Modeller, but I'm not married to it.

# Answer
> 1 votes
Asking for examples is off topic for this site, so the question will probably be closed.

Unfortunately, the Flag module is not currently actively maintained, so it's a bit hard to find examples.

However, I would suggest skipping Rules/ECA and doing this all in a custom module. This is because if you do it in a custom module, it will continue to work in new Drupal versions unless Flag itself changes, whereas with Rules/ECA, you may get left behind in Drupal version updates.

I would take the following approach:

1. Use `hook_entity_type_update()` for the flagging.
2. Confirm that you have the right type of flagging (check the flag bundle).
3. Get the comment entity id from `$flagging->field_comment_entity_reference->target_id`.
4. Unpublish the comment.

---
Tags: flags
---


title: Form with two submission buttons

text:
# Question
Title: Form with two submission buttons
I try to create a form with two submit buttons and each button will use a different function: the default `submitForm` function and a custom `submitFormEndSession` function. So I have this code:

```
class EndSessionForm extends FormBase {

  /**
   * @var \Drupal
   */
  private $drupal;

  public function __construct() {
    $this->drupal = new Drupal();
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'end_session_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state): array {

    // ... some fields

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => 'Close the session',
      '#name' => 'btnEnd',
    ];

    $form['stop'] = [
      '#type' => 'submit',
      '#value' => 'Stop the session',
      '#name' => 'btnStop',
    ];

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Function to call with the btnEnd button
  }

  public function submitStopForm(array &$form, FormStateInterface $form_state) {
    // Function to call with the btnStop button
  }
}

```

According to the documentation of Drupal 9.2.x, the only thing I had to do is add a `#submit` parameter to the `$form['stop']` element like this:

```
$form['stop'] = [
  '#type' => 'submit',
  '#value' => 'Stop the session',
  '#name' => 'btnStop',
  '#submit' => [ $this, 'submitStopForm' ] // link to the second submit function
]

```

But it doesn't work.

After many tries and researches, I've found a partial solution by adding this in `buildForm`:

```
$form['#submit'][] = [$this, 'submitStopForm'];

```

The two buttons are now linked to `submitForm` and `submitStopForm`, no matter if I put a `#submit` parameter on the buttons or not, `submitStopForm` is executed first then `submitForm`. But I'm wonder how I can link the first button to `submitForm` and the second one to `submitStopForm` properly and without enter in both functions when we click on one button.

Thanks and have a nice day!

# Answer
> 3 votes
I think you have to wrap the sumbit callback in another array, if you are using that callable notation. So either:

```
$form['stop'] = [
  '#type' => 'submit',
  '#value' => 'Stop the session',
  '#name' => 'btnStop',
  '#submit' => [ [$this, 'submitStopForm'] ] // Array of callables (which are arrays)
];

```

or this

```
$form['stop'] = [
  '#type' => 'submit',
  '#value' => 'Stop the session',
  '#name' => 'btnStop',
  '#submit' => [ 'submitStopForm' ] //Array of submit functions
]

```

You can also get the element that triggered the action from inside the submit function, but i tend to think the previous solution is better.

```
public function submitForm(array &$form, FormStateInterface $form_state) {
    $submitButton = $form_state->getTriggeringElement();
    dump($sumbitButton);
}

```

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormState.php/function/FormState%3A%3AgetTriggeringElement/8.2.x

# Answer
> 0 votes
#submit: Specifies an alternate callback for form submission when the submit button is pressed. Use '::methodName' format or an array containing the object and method name (for example, \[ $this, 'methodName'\] ).

```
  /**
   * @param array $form
   * @param FormStateInterface $form_state
   * @return array
   */
  public function buildForm(array $form, FormStateInterface $form_state)
  {
    $form['actions'] = [
      '#type' => 'actions',
    ];

    $form['actions']['submit1'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit One'),
      "#weight" => 1,
      '#submit' => array([$this, 'submitFormOne']),
      '#limit_validation_errors' => array()
    ];

    $form['actions']['submit2'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit Two'),
      "#weight" => 2,
      '#button_type' => 'primary',
      '#submit' => array([$this, 'submitFormTwo']),
      '#limit_validation_errors' => array()
    ];

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitFormOne(array &$form, FormStateInterface $form_state)
  {
    //TODO: write your code
  }

  /**
   * {@inheritdoc}
   */
  public function submitFormTwo(array &$form, FormStateInterface $form_state)
  {
    //TODO: write your code
  }

```

---
Tags: forms, 9
---


# Question
Title: How do I inject a dependency into a @FieldType plugin?
I am implementing custom fields in Drupal 8 (types, widgets, formatters).

@FieldType plugins are instantiated by their respective plugin manager (`\Drupal\Core\Field\FieldTypePluginManager`) which does not care about dependency injection. That is possible for both @FieldFormatter and @FieldWidget plugins if they only implement `\Drupal\Core\Plugin\ContainerFactoryPluginInterface`.

What would be the alternative way to inject a dependency into a @FieldType plugin?

### Notes

# Answer
> 9 votes
An example for a field formatter plugin with dependency injections. This works differently from services. First parameter injected is the container to get all services needed.

**Drupal\Core\Field\Plugin\Field\FieldFormatter**

```
class StringFormatter extends FormatterBase implements ContainerFactoryPluginInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a StringFormatter instance.
   *
   * @param string $plugin_id
   *   The plugin_id for the formatter.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The definition of the field to which the formatter is associated.
   * @param array $settings
   *   The formatter settings.
   * @param string $label
   *   The formatter label display setting.
   * @param string $view_mode
   *   The view mode.
   * @param array $third_party_settings
   *   Any third party settings settings.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['label'],
      $configuration['view_mode'],
      $configuration['third_party_settings'],
      $container->get('entity_type.manager')
    );
  }

```

# Answer
> 0 votes
The accepted answer works for the field widget and field formatter classes. The actual @fieldType definition class constructor requires this signature:

```
public function __construct(
   \Drupal\Core\TypedData\ComplexDataDefinitionInterface $definition,
   $name = NULL,
   \Drupal\Core\TypedData\TypedDataInterface $parent = NULL
)

```

This works for Drupal 8, 9 and 10. For an example, refer to the FieldItemBase class.

---
Tags: 8, plugins
---