title: Implementing a view relationship plugin

text:
# Question
Title: Implementing a view relationship plugin
Using Drupal 8, I am trying to create a view plugin to add a relationship to an existing view. I'm basing the code off of this example https://www.foreach.be/blog/how-build-complex-filters-drupal-8 since I haven't found an explanation of how to add a relationship in D8.

I don't have any error messages but I'm not sure what I need to do to get this working.

I have a class file for the plugin at module\_name/src/Plugin/views/relationship/CustomRelationship.php

// CustomRelationship.php

```
<?php

namespace Drupal\custom_module\Plugin\views\relationship;

use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\relationship\RelationshipPluginBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Add custom view relationship
 *
 * @ingroup views_relationship_handlers
 *
 * @ViewsRelationship("custom_relationship")
 */

class CustomRelationship extends RelationshipPluginBase {

  /**
   * Relationship plugin.
   *
   *
   */
  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    parent::init($view, $display, $options);
    $this->valueTitle = t('Node Revision');
  }

  public function query() {

    $configuration = array(
      'table' => 'node_revision',
      'field' => 'nid',
      'left_table' => 'node_field_revision',
      'left_field' => 'nid',
      );

    $join = Views::pluginManager('join')->createInstance('standard', $configuration);
    $this->query->addRelationship('node_revision', $join, 'node_field_revision');

  }

}

```

And in the main module folder there is a views.inc file

// custom\_module.views.inc

```
<?php
/**
 * Implements hook_views_data_alter().
 */
function custom_module_views_data_alter(&$data) {
  $data['custom_module']['custom_relationship'] = array(
    'title' => t('Node Revision'),
    'help' => t('Provide node revision relationship.'),
    'relationship' => array(
      // ID of relationship handler plugin to use.
      'id' => 'custom_relationship',
    ),
  );
}

```

# Answer
> 10 votes
You shouldn't need to create a Views relationship plugin, although that might depend on any special cases with your relationship.

I've got two custom entities - a student and a school, which have been scaffolded using Drupal console. The Student has an entity reference field (school\_id) which relates a Student to a School but the opposite relationship - Students belonging to a School - isn't generated by default. So to create the relationship that can be used in views, I built this hook method:

```
/**
 * Implements hook_views_data_alter().
 */
function school_student_views_data_alter(array &$data) {
  $data['school']['student']['relationship'] = [
    'title' => t('Student'),
    'label' => t('Student'),
    'group' => 'School',
    'help' => t('Reference to students of a school'),
    'id' => 'standard',
    'base' => 'student',
    'base field' => 'school_id',
    'field' => 'id',
  ];
}

```

If you examine the $data array, you'll see all the data for all your views tables. It's a big list with lots of array elements. It'll make sense when you look at it. Set a breakpoint in your views\_data\_alter hook to inspect it (or use dpr/kpr/dpm).

What we're doing is creating a relationship from one table to another, as this relationship currently doesn't exist. I believe that the array element names 'school' and 'student' should refer to the table names we are dealing with. We're creating a relationship data alter and so 'relationship' is the child array element we need to create. Below that is just configuration.

**title** refers to the relationship title in your "Add relationship" modal window

**label** is the default name of the relationship when you create it

**group** is the name of the relationship group your new relationship belongs to

**help** is helper text/description for the relationship

This next bit is important!

**id** refers to the the name of the views relationship plugin you are needing to use. Because I'm not creating a complex relationship (basically a simple inner join), I'm using the Standard views relationship plugin (found in *Drupal\views\Plugin\views\relationship\Standard*).

Finally, **base** is the base table we're creating the relationship *from*.

**base field** is the join field in our base table and finally **field** is the field in the school table we're creating our join to.

So in use, views will create a join that in SQL looks like:

```
INNER JOIN {student} student_school ON school.id = student_school.school_id

```

Hopefully this makes sense and helps you or others out.

# Answer
> 1 votes
In your custom\_module.views.inc file you probably need to attach your relationship to the node 'table' so instead of

```
  $data['custom_module']['custom_relationship'] = array(

```

you want

```
  $data['node']['custom_relationship'] = array(

```

... or maybe `node_field_data`

---
Tags: 8, views
---


title: How to skip form validation with ajax?

text:
# Question
Title: How to skip form validation with ajax?
I am building a form with tabledrag and ajax "add more" and "remove item" buttons.

I tried different variations with '#type' =\> 'button' and '#type' =\> 'submit'.

Currently, pressing one of those ajax button always triggers form validation and then a form rebuild. (this means every element is processed twice).

If a user wants to add a bunch of items with required values, then validation errors will block and disrupt the "add more" mechanic, or they will show up with the error colors, which is all undesirable.

I experimented a bit with '#limit\_validation\_errors', but I am not sure this does what I need. If I understand correctly, this only suppresses the error output, but the actual validation is still executed.

I looked at drupal\_process\_form(). The validation and rebuild happens here:

```
  $form = form_builder($form_id, $form, $form_state);

  // Only process the input if we have a correct form submission.
  if ($form_state['process_input']) {
    drupal_validate_form($form_id, $form, $form_state);
    [..]
      $form = drupal_rebuild_form($form_id, $form_state, $form);

```

This means the form is processed one time, then it is validated, and later it is built and processed again.

For my purposes, the entire validation and rebuild could be skipped. I managed to implement the "add more" mechanic in a value callback, so I don't need a #submit handler on the ajax "add more" button.

The code in drupal\_process\_form() suggests that I could skip the validation and rebuild by setting `$form_state['process_input'] = FALSE`. However, this also suppresses the detection of `$form_state['triggering_element']`, which means that ajax\_form\_callback() won't work correctly anymore.

I might figure something out here, but perhaps there is something simpler that I missed.

I think the problem is the same as described here, https://www.drupal.org/project/drupal/issues/2476569.
But I am not going to wait for this issue to be done for D8 and backported to D7. I am looking for something I can do right now.

# Answer
You want #limit\_validation\_errors. Setting this value to an empty array will mean that nothing is validated when the button is clicked.
> 5 votes

---
Tags: 7, forms, ajax
---


# Question
Title: Layout problems (backgrounds and blocks region)
I'm a non professionist dealing with drupal for the first time and it's killing me. I'm trying to create a page without having to code but it seems impossible! I need to adjust the position of the main menu (**how can I move the writings to the center?**), then I need to put a **background**, and basically I need very simple assistance to create this web site for an exam, please help me :'( (yes, i tried to read the guide on drupal.com but it's too difficult for a non-expert

# Answer
You would have to learn CSS and how to work with themes to do this yourself.

An alternative option, for no code solution, you could use Glazed Builder. However, it's not free, but might be worth the price of admission if you no time to learn how to code.

**Important:** There is Glazed builder for Drupal 7 & Drupal 8, remember to get the version of the Drupal version that you are using, as the 7 version will not work for Drupal 8 and vice versa.
> 0 votes

---
Tags: blocks, media, theming
---


title: Webform Message / Custom Module

text:
# Question
Title: Webform Message / Custom Module
I'm trying to create a custom module which will display a message after my webform. I know that in order to display a message, I could use the following code:

```
$message = "Message here";
drupal_set_message(t($message));

```

But rather than having a specific message, I want to have a conditional message based on PHP if statements. E.g.,

```
    if($class == A) {
    print "Correct!";
}

```

So, my question is how can I get the *results* of this PHP code to display on my webform? I'm not familiar with PHP code, so I don't know if I can combine the $message code with the if statement somehow. (I've tried variations of this with no success.)

Thanks for your help.

# Answer
> 3 votes
One of the features and APIs of the Webform module for Drupal 8 that I personally enjoy using is support for inline messages using the WebformMessage element

The WebformMessage element supports dismissal messages and #states API.

Here is the YAML version of a Message element

```
message:
  '#type': webform_message
  '#message_type': warning
  '#message_close': true,
  '#message_storage': user,
  '#message_message': 'This message can be dismissed by a user'

```

Here is the PHP syntax, which can be used in your custom code.

```
$build['message'] = [
  '#type' => 'webform_message',
  '#message_id' => 'custom_message_id',
  '#message_type' => 'warning',
  '#message_close' => TRUE,
  '#message_storage' => WebformMessage::STORAGE_USER,
  '#message_message' => $this->t('This message can be dismissed by a user'),
];

```

---
Tags: 8, webforms
---


# Question
Title: Form #states only work after change, but not on initial load
I've got a paragraph with a select field `field_colorschema`, depending on its value two other fields `field_image` `field_parallax` on the same paragraph are shown or hidden. The code I've written works for most parts, but only AFTER change of `field_colorschema`. It does not set the correct state on page load.

```
function wt_base_field_widget_paragraphs_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
  /** @var \Drupal\field\Entity\FieldConfig $field_definition */
  $fieldDefinition = $context['items']->getFieldDefinition();
  $parentEntityType = $fieldDefinition->getTargetEntityTypeId();
  $parentEntityBundle = $fieldDefinition->getTargetBundle();
  $parentEntityFieldType = $fieldDefinition->getType();
  $parentEntityFieldName = $fieldDefinition->getName();

  /**
   * Conditionally hide background image and parallax depending on row colorschema
   * http://agaric.com/blogs/conditional-fields-paragraphs-using-javascript-states-api-drupal-8
   */
  if ($parentEntityFieldName == 'field_pagebuilder') {

    /** @see \Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget::formElement() */
    $widgetState = \Drupal\Core\Field\WidgetBase::getWidgetState($element['#field_parents'], $parentEntityFieldName, $form_state);

    /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
    $paragraph = $widgetState['paragraphs'][$element['#delta']]['entity'];
    $paragraphBundle = $paragraph->bundle();

    // Determine which paragraph type is being embedded.
    if ($paragraphBundle == 'row') {
      $dependeeFieldName = 'field_colorschema';
      /* field_colorschema option value is one of ['--color-default', '--color-bglight', '--color-bgdark', '--image-bglight', '--image-bgdark'] */
      $selector = sprintf('select[name="%s[%d][subform][%s]"]', $parentEntityFieldName, $element['#delta'], $dependeeFieldName);

      // Dependent fields.
      $element['subform']['field_image']['#states'] = [
        'visible' => [
          [
            $selector => ['value' => '--image-bglight'],
          ],
          [
            $selector => ['value' => '--image-bgdark'],
          ],
        ],
        'required' => [
          [
            $selector => ['value' => '--image-bglight'],
          ],
          [
            $selector => ['value' => '--image-bgdark'],
          ],
        ],
      ];
      $element['subform']['field_parallax']['#states'] = [
        'visible' => [
          [
            $selector => ['value' => '--image-bglight'],
          ],
          [
            $selector => ['value' => '--image-bgdark'],
          ],
        ],
      ];
    }
  }
}

```

I've also tried inverting everything negative logic (`invisible`...), because the default value on `field_colorschema` forces the other 2 fields to be hidden, but again it worked only after change, and not on the initial page load.

What am I missing so that `field_image` and `field_parallax` are correctly following `field_colorschema`s values on the intial page load?

PS: The paragraph subform is inside a Field Group tab, but I think that doesn't matter, because the given code works after selecting values.

# Answer
My given code works correctly. However, there is a bug in Paragraphs that instantly re-shows hidden fields from form API, see:

https://www.drupal.org/project/paragraphs/issues/2868155#comment-12493576 https://www.drupal.org/project/paragraphs/issues/2946856

Applying the patch from issue #2946856 fixed it for me.
> 1 votes

# Answer
Here are 2 ideas for working with this:

1. Frontend: Attach a small custom javascript library to the widget's render array (`#attached`) that will trigger a change event on the dependee element.
This depends on the `$selector` being correct (and since everything works as expected after a change, it seems to be the case). The idea is to simulate a state change after page load, in order to get the states logic to apply.
2. Backend: Check the submitted value of the dependee field (`$form_state->getValue()`) and if there is no submitted values yet, check the default value of the form element (`$form['field_name']['widget']['#default_value']`).
Once you know what the dependee's initial expected value is, you can conditionally set the dependent field to invisible by adding the `visually-hidden` css class to the widget (using `#attributes`).
> 0 votes

---
Tags: 8, forms
---


# Question
Title: Is a mailchimp newsletter with an entity view in the content area possible?
I am a newbie on emailing solutions and I have to design a newsletter system that allows the customer to create a newsletter with some content + the 3 most recent articles.
I guess it could be possible with simplenews, but mailchimp is a requirement. So I was wondering if anyone has already tried to add an entity of view type in the content part of a mailchimp newsletter like it is possible to add a node entity type. Or by using a module like Insert view or by simply adding a little token like this one:

> \[view:my\_view=my\_display\]

The context of the project is D8, but a D7 solution might help.

# Answer
> 0 votes
So nope. But there is another way using simplenews and place the view in the template of the newsletter, and then use another smtp instead of Mailchimp, like Mailjet which now has a release on D8.

---
Tags: views, 8, emails
---


title: execute action on workflow transition

text:
# Question
Title: execute action on workflow transition
I want to execute PHP script in my custom module, when transition occurs. Workflow is assigned to custom entity. I'm using Drupal's core modules Workflow and Content moderation. How can I do that programmatically?

# Answer
You can use hook\_ENTITY\_TYPE\_update to achieve this.

```
/**
 * Implements hook_ENTITY_TYPE_update().
*/

function mymodule_node_update(Drupal\Core\Entity\EntityInterface $entity) {

    //Get the current Moderation state;
    if (isset($entity->moderation_state) && isset($entity->moderation_state->getValue()[0]['target_id'])) {
        $currentState = $entity->hasField('moderation_state') ? $entity->moderation_state->getValue()[0]['target_id'] : null;
    }
    //Get the original Moderation state;
    if ( isset($entity->original->moderation_state ) && isset($entity->original->moderation_state->getValue()[0]['target_id']) ) {
        $originalState = $entity->original !== NULL ? $entity->original->moderation_state->getValue()[0]['target_id'] : null;
    }

    #Get the Transition;
    $workflowTransition = rtrim($originalState.'-->'.$currentState);

    switch ($workflowTransition) {
       case 'published-->needs_review':
       case 'draft-->needs_review':
       //Do something.
      break;
       case 'draft-->needs_review':
      //Do something else;
      break;
    }
 }

```
> 2 votes

---
Tags: 8, workflows
---


# Question
Title: There is data for this field in the database. The field settings can no longer be changed
I have a content type where we reference Taxonomy terms in one of the fields. When the field was created it was set up to Unlimited entries for that field.

The issue is that we need to change this field from Unlimted to Limited to 1.

There are a few nodes where more than one term was referenced. Which means that we can no longer change this fields storage settings until the nodes that have more than one record are changed to 1 term only.

My questions is how to set up a view that will show only nodes that have two or more terms referenced.

Error: There is data for this field in the database. The field settings can no longer be changed.

What needs to be changed: There are 65 entities with 2 or more values in this field.

Solution: If we can change those 65 entries, I know we will be able to limit this filed to 1 term.

How? The question is how do we find those nodes? I can't set up a view that will exclude nodes with 1 taxonomy term but show all with 2 or more.

# Answer
> 3 votes
I haven't tried to lower the settings in a situation where no extra data would prevent it, but it seems it is possible: Changing cardinality lower than highest existing delta causes data loss upon save.

But assuming it can be done, you can also create Views to list content with more than one term in a multi-valued field.

Fields with multiple values track the values with `Delta` starting from `0`. Field with one value has Delta 0. Field with 2 values, has Delta of `0` for the first value, and Delta of `1` for the second value etc.

* Field
    + Value 1 (Delta: 0)
    + Value 2 (Delta: 1)
    + Value 3 (Delta: 2)
    +

Delta is available in Views. This means you can Filter content with regard to it, which is what you want.

1. Create Views of type Content with Filters and Fields appropriate for your initial situation, show Title and the Taxonomy field in question so you can check the results (you probably already have this covered)
2. **Add a Filter** of your field Delta. It will be called something like **MyTags (field\_mytags:delta)**. If you search for your field name it will list both your field and the Delta, choose the Delta option.
3. Set the `Operator` of the Delta Filter to **Is equal to** and enter **1**

This will list all the nodes (provided your other filters are set appropriately) where the second position in the Taxonomy field isn't empty. Meaning there are at least 2 terms recorded in that field. The nodes will only be listed once.

If you set the Delta Filter Operator to `Is greater than` `0`, as you may be tempted, it will also list the nodes that have more than one term in that field, but it will list them as many times as there are terms on that node minus 1. So if a node has 3 tags, it will be listed twice, because it will list one result *for each Delta above 0*.

With this result, you can go on to use Views Bulk operations to edit the listed "offenders", by coding an operation that deletes all but the first value from that field. Or even manually edit each node if coding is not an option.

---
Tags: views, 8
---


title: Enable Twig debug doesn't work?

text:
# Question
Title: Enable Twig debug doesn't work?
Why isn't the Twig debug working on my Drupal 8.2.6 site?

This is the folder structure.

These are the folder permissions.

This is the content of the settings.php file.

```
$settings['hash_salt'] = 'DEVELOPMENT_SALT';
$settings['update_free_access'] = FALSE;
$settings['file_public_base_url'] = 'http://localhost/files';
$settings['file_public_path'] = 'sites/default/files';
$settings['file_private_path'] = 'sites/default/private';
$settings['file_scan_ignore_directories'] = [
  'node_modules',
  'bower_components',
];
if (file_exists(__DIR__ . '/../development/settings.development.php'))     {
  include __DIR__ . '/../development/settings.development.php';
}

```

Here I include /../development/settings.development.php.

```
assert_options(ASSERT_ACTIVE, TRUE);
\Drupal\Component\Assertion\Handle::register();

/**
 * Enable local development services.
 */
$settings['container_yamls'][] = __DIR__ . '/development.services.yml';

$databases['default']['default'] = array(
  'database' => 'dbname',
  'username' => 'dbusername',
  'password' => 'pw',
  'prefix' => '',
  'host' => '127.0.0.1',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
);

$settings['hash_salt'] = 'DEVELOPMENT';

$config['system.logging']['error_level'] = 'verbose';
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] =     'cache.backend.null';
$settings['extension_discovery_scan_tests'] = TRUE;
$settings['rebuild_access'] = TRUE;
$settings['skip_permissions_hardening'] = TRUE;

```

Here I also add development.services.yml.

```
parameters:
  http.response.debug_cacheability_headers: true
  twig.config:
    debug: true
    auto_reload: true
    cache: false
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory

```

Things I have checked/done:

* Checked if all these files are loaded -\> They are
* Checked the indentation of the development.services.yml -\> Checks out
* Cleared all the different caches, rebuild them, etc -\> If I change a template, it changes, but no Twig debugging

sites/default/files AND sites/default/private are not used by Drupal.

# Answer
Try to change your `development.services.yml` to following. this works for me correctly(I hope works for you too) .

```
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory

# Enable Twig debugging.
parameters:
 twig.config:
   debug: true
   auto_reload: true
   cache: false

```

also this article about setting up debugging on Drupal 8 is very good for future visitors of this question.
> 3 votes

# Answer
Services should come before parameters ...also... If you don't want to enable all the 'stuff' you have in settings.local.php you can just add... `$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';`
to the bottom of your settings.php file to turn on twig debug after adding the parameters to development.services.yml.

I use both this and...

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

```

Commenting out one or the other depending on what I need.
> 1 votes

# Answer
It seems everything is correct and I guess you just forget check "Show comments" on your browser.
> 0 votes

---
Tags: theming, 8, debugging
---


# Question
Title: How to properly add a Commerce Shipping Service option via AJAX during checkout
* I have the `Payment` and `Shipping service` block in the same checkout pane.
* I update the Shipping service block with AJAX when selecting a Payment method, as available Shipping services depend on the selected Payment method.

But once the Shipping service block is reloaded, if I select another Shipping service and submit the form, I will be redirected to the initial pane as if my selection was unvalid - with no error message.

This is the code I use to update the Shipping services block, after saving the order to update the available Shipping services. (Inspired by some other posts)

And I can't find a way to make the Shipping selection work on submit after being reloaded via AJAX.

* Should I also update the form state?
* `commerce_shipping_service_rate_order($service, $order)` didn't change anything
* Nor `commerce_shipping_pane_service_details_refresh($form,
$form_state)`

Would someone have an idea what could go wrong?

```
/**
 * Alter checkout shipping form.
 */
function mymodule_checkout_shipping_alter(&$form, &$form_state) {
    // Replace AJAX callback by a custom one.
    $form['commerce_payment']['payment_method']['#ajax']['callback'] = 'mymodule_payment_pane_checkout_form_details_refresh';
}

/**
 * Checkout shipping pane AJAX callback function.
 */
function mymodule_payment_pane_checkout_form_details_refresh($form, &$form_state) {
    // Commands initialization.
    $commands = array();
    // Load the current order
    $order_id = $form_state['order']->order_id;
    $order = commerce_order_load($order_id);

    // Set the newly selected payment option to the order
    $order->data['payment_method'] = $form['commerce_payment']['payment_method']['#default_value'];
    // Refresh the current order (more specific: update it's line items
    commerce_cart_order_refresh($order);
    // save the refreshed order (more specific: recalculate the order total and save it)
    commerce_order_save($order);

    // Default Commerce AJAX callback for the payment pane.
    $commerce_wrapper = '#' . $form_state['triggering_element']['#ajax']['wrapper'];
    $commerce_output = commerce_payment_pane_checkout_form_details_refresh($form, $form_state);
    $commands[] = ajax_command_replace($commerce_wrapper, render($commerce_output));

    // Update Commerce shipping pane.
    $panes = commerce_checkout_panes();
    $shipping_pane = drupal_get_form('commerce_shipping_pane_checkout_form', $panes['commerce_shipping'], $order);
    $form['commerce_shipping']['shipping_rates'] = $shipping_pane['shipping_rates'];
    $form['commerce_shipping']['shipping_service'] = $shipping_pane['shipping_service'];
    $form['commerce_shipping']['service_details'] = $shipping_pane['service_details'];
    $commands[] = ajax_command_replace('#commerce-shipping-service-ajax-wrapper', drupal_render($form['commerce_shipping']));

  return array('#type' => 'ajax', '#commands' => $commands);
}

```

# Answer
> 0 votes
Since Stackexchange does not allow me to comment, did you find a solution? I am experiencing exactly the same issue. Thanks.

---
Tags: 7, ajax, commerce
---


# Question
Title: Template suggestions based on path alias
I'm trying to work out how I can add my own template suggestions based on the set URL alias. I've found lots of information out there regarding Drupal 7, but very little for 8.

I know I can use `hook_theme_suggestions_page_alter(array &$suggestions, array $variables)`.

Basically, I'm looking to convert this to Drupal 8.

```
$alias = drupal_get_path_alias($_GET['q']);
if ($alias != $_GET['q']) {
  $template_filename = 'page';
  // Break it down for each piece of the alias path.
  foreach (explode('/', $alias) as $path_part) {
    // Added the str_replace because path parts with - were not being picked up properly by the theme_hook_suggestions().
    $template_filename = $template_filename . '__' . str_replace("-", "_", $path_part);
    $variables['theme_hook_suggestions'][] = $template_filename;
  }
}

```

# Answer
**OK, I seem to have got it working.**

```
function THEME_NAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $result = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);

  $path_alias = trim($result, '/');
  $path_alias = str_replace('/', '-', $path_alias);

  $suggestions[] = 'page__path_alias__'.$path_alias;
}

```
> 5 votes

# Answer
Adding to Daniel's answer. If you have a dash the path alias, such as "our-community", make sure you additionally convert the dash to an underscore, i.e. 'our\_community'.

```
function THEME_NAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $result = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);

  $path_alias = trim($result, '/');
  $path_alias = str_replace('/', '-', $path_alias);
  $path_alias = str_replace('-', '_', $path_alias);

  $suggestions[] = 'page__path_alias__'.$path_alias;
}

```
> 3 votes

# Answer
If your path continues, you can target more templates, so it's actually just small improvement of previous answers.

E.g your path is: "blog/article-title", you will have two suggestions:

* page--path-alias--blog--article-title.html.twig
* page--path-alias--blog.html.twig

```
function THEME_NAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  $current_path = \Drupal::service('path.current')->getPath();
  $result = \Drupal::service('path.alias_manager')->getAliasByPath($current_path);

  $path_alias = trim($result, '/');
  $path_alias = explode("/", $path_alias);
  $suggestion = "page__path-alias";
  foreach ($path_alias as &$alias) {
     $suggestion .= $alias = "__" . str_replace('-', '_', $alias);
     $suggestions[] = $suggestion;
  }
}

```
> 0 votes

---
Tags: 8, theming
---


# Question
Title: Custom submit handler on node form not picked up
I am altering a node form with hook\_form\_alter and adding a couple of submit handlers. When the form gets submitted they get picked up using:

```
foreach (array_keys($form['actions']) as $action) {
  if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
    array_unshift($form['actions'][$action]['#submit'], 'submit_handler_a');
    $form['actions'][$action]['#submit'][] = 'submit_handler_b';
  }
}

```

Problem is, if the form contains a field that can store multiple values, as soon as I click on the 'Add more' button for that field and a new value for it, when submitting the form my handlers are not being picked up.

What am I doing wrong?

# Answer
I had to change hook\_form\_alter to hook\_form\_BASE\_FORM\_ID\_alter to make it work. My code ended up looking like:

```
function mymodule_form_node_form_alter(&$form, &$form_state, $form_id)
{
  if ($form['#form_id'] == 'node_mycontettype_form') {
    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        array_unshift($form['actions'][$action]['#submit'], 'submit_handler_a');
        $form['actions'][$action]['#submit'][] = 'submit_handler_b';
      }
    }
  }
}

```

My custom handlers are now being picked after a multiple value field submits multiple values. I don't know why this made the difference and can't find anything in the docs, but I hope this helps people that run into the same issue.
> 0 votes

# Answer
Have a look on those form elements in the form array. They might have their own \['#submit'\] in the array and you might need to add your custom handler on those too
> 0 votes

---
Tags: forms
---


title: Modify the images

text:
# Question
Title: Modify the images
I am currently working on Drupal 8 and Drupal commerce.

I have created an image field called "field\_image\_category" in the product-variation-types called "default".

I have created a color field as an attribute called "attribute\_color".

I have copied the file commerce-product.html.twig in my theme.

if I want to show only the image field and the variation field where the color is displayed and the add button to the cart, I do it with the following code

```
{{ product.variation_field_imagen_category }}
{{ product.variations }}

```

if I want to modify the images and only show the small images I do it with the following code

```
    {% for  img in    product.variation_field_imagen_category  %}
     {% if img.entity %}
      {% for  imgv in  img %}
        {# Set product thumbnail. #}
         {% set imagen1 = {
          '#theme':'image_style',
          '#style_name': 'thumbnail',
          '#uri': imgv.entity.uri.value,
          '#alt': imgv.alt}
         %}
       {{ imagen1  }}
      {% endfor %}
     {% endif %}
    {% endfor %}
{{ product.variation_field_imagen_category }}

```

my problem is that if I have two colors as an attribute of a product, the modified images do not change and only the image field called

```
{{ product.variation_field_imagen_category }}

```

How can I achieve that when I select a color, I also automatically change the small images that I have added?

# Answer
I installed the module juicebox, and this module is integrated very well with drupal 8 commerce.
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: Automatically block user that access /wp-login.php
Is it possible to block any users IP if they try to access a specific URL such as /wp-login.php page which does not exist on Drupal.

Basically to automatically blacklist the user, for days or even forever.

Trying to implement this as a security measure. For those who are looking for ways to hack the site.

# Answer
You can use autoban ip

You have to at least enable *Autoban* and *Autoban Core Ban Provider* modules from this package.

Then go to *configuration \> people \> automatic ip address bans* and add a rule with this settings

> **type** page not found
>
> **Message pattern** wp-login.php|/otherURL|anotherURL
>
> **pattern** (can be left blank)
>
> **Threshold** 1 (after how many attempts to ban them)
>
> **IP Ban Provider** Core Ban

NOTE: above I have added multiple patterns delimited with `|` just to demonstrate the possibility

After setting this everytime your cron runs this module will run and it will look through the watchdog messages and ban the IPs that match the above rule.
> 6 votes

# Answer
Aside from banning the IP in Drupal, another thing you can do is add settings in your server to automatically deliver 404s for any Wordpress URLs, or URLs related to other software. This way, Drupal is never called.

Which way you want to go will depend on your application, and how critical it is to save resources in regard to bots that are more or less combing the WHOIS domain list.
> 0 votes

---
Tags: 8, security
---


# Question
Title: Is it possible to add folders in config/install?
I am working on a Drupal 8 module that has a fairly large number of configs (a few content types and fields, with 20-25 config files per content type), and one thought I had for organization was to put the configs for each CT into a subfolder under config/install. However, I see that the configs are not read in this case.

Which is the better way to proceed?

1) Just place everything in config/install, with 100-150 config files.

2) Create sub-modules for each content type, which would require a bit more overhead but could be done given the module's use case.

3) Is there a way to add subdirectories in config/install?

For some background, I wrote a Python daemon that does server monitoring, and the module handles communication between the monitors and a central reporting server. Each content type corresponds to a plugin for the monitor, so someone could turn on only the plugins that they want. However, in the current iteration I would prefer to have a core set of content types that are managed by one module.

# Answer
> 4 votes
No, you can't put config in sub-folders, those are reserved for config collections (e.g. language overrides/translations).

The only option would be submodules as you already said, and it's up to you to decide if that's something that makes sense for you.

> For some background, I wrote a Python daemon that does server monitoring, and the module handles communication between the monitors and a central reporting server. Each content type corresponds to a plugin for the monitor, so someone could turn on only the plugins that they want.

Not sure I fully understand that and it's not exactly the same but our project https://www.drupal.org/project/monitoring might still be interesting? it uses plugins and a single config entity for a sensor, it is about monitoring things about a single drupal site and not other servers (We do then use sensu to collect the data and alerting).

And without having the full picture, using content types/content for something that doesn't really sound like content seems like a strange idea. In Drupal 8, it's pretty easy to create your own entity type with support for bundles, then you could make all the shared fields base fields and would probably get rid of 90% of your configuration.

---
Tags: 8, configuration
---


# Question
Title: How to solve limitations of 32-bit PHP in drupal 8
I am unable to complete the setup of Drupal 8. When I get to the third step then the error below will be displayed stating:

> "You are running on a system where PHP is compiled or limited to using 32-bit integers. This will limit the range of dates and timestamps to the years 1901-2038. Read about the limitations of 32-bit PHP."

I am using a 32-bit windows 7 system. How can I resolve this issue?

# Answer
> 5 votes
There is a "continue anyway" link at the bottom. I've had the same problem, but for the install process this is only a warning, and will not prevent you from using Drupal 8.

Also, credit to Clive for mentioning this first.

# Answer
> 2 votes
To answer the question on how to "solve" the error or indeed the underlying issue - you cannot.

Due to the maximum size of a signed 32-bit integer the latest time/date a 32-bit integer can represent is 03:14:07 UTC on Tuesday, 19th January 2038 the only solution available is to use 64-bit software versions or work around the issue in other ways some ideas for how to resolve the issue are given in an answer to this question.

---
Tags: 8, installation
---


# Question
Title: Hook for a JS library in a custom module not working drupal 8
Well I have created a JS to validate a form, and when I try to attach the hook in my custom module the JS its not showing. My custom module it's call "ajax\_form"

My ajax\_form.libraries.yml

```
ajax_form:
  version: 1
  js:
    js/ajax_form.js: {}
  dependencies:
      - core/jquery

```

My ajax\_form.module

```
<?php
function ajax_form_page_attachments(array &$attachments) {
    $attachments['#attached']['library'][] = 'ajax_form/ajax_form';
}

```

I have a `console.log('test');` in the first line of my JS but this is not displaying.

I have run out of ideas of what it be. Also I'm new to Drupal maybe is that.

# Answer
Just wrong indentation. Dependencies need two spaces indentation:

```
ajax_form:
  version: 1
  js:
    js/ajax_form.js: {}
  dependencies:
    - core/jquery

```
> 3 votes

---
Tags: 8, javascript, hooks
---


title: Setting a standard value to a field

text:
# Question
Title: Setting a standard value to a field
I've created a field with drupal console. That made the following standard folder structure.

```
FieldFormatter
FieldType
Fieldwidget

```

These all have their respected php classes.

Now this field is in a content type that always is used in a Book. I want to this Books name into that field. I know how to retrieve this name trough code but i don't know how to get this value into this field in all new instances of this content type.

I thought i just needed to use a default value but that doesn't seem to work because even though i added 'default' to the schema with that value it doesn't show up?

# Answer
> 1 votes
Normally a default value is configured in the field configuration. Either static in `default_value` or dynamic in `default_value_callback` pointing to a callback function which returns the default value.

For your original question, how to do this in one of the field plugins, see No way for a field to dynamically set default value and especially #6:

> I resorted to creating widgets (extending the base widgets), whose only concern is to set the default value dynamically according to contextual values, e.g. I have a widget that presets a default value to an entity name referenced by the logged in user, something like this:

```
/**
 * Define the {@link AcmeWidget} class.
 *
 * @FieldWidget(
 *   id = "acme_widget",
 *   label = @Translation("Acme Textfield"),
 *   field_types = {
 *     "string"
 *   }
 * )
 *
 * @package Drupal\acme\Plugin\Field\FieldWidget
 */
class AcmeWidget extends StringTextfieldWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

    // Call our parent but set the value using our default value function.
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    // Get the current user organization's name.
    $user = User::load(\Drupal::currentUser()->id());
    $organization = $user->get('field_organization')->entity->title->value;

    // Set the default value if a value hasn't been set.
    $element['value']['#default_value'] = $organization;

    return $element;
  }

}

```

---
Tags: 8
---


title: How do I create a custom action?

text:
# Question
Title: How do I create a custom action?
I want to create simple actions that will change the field\_support\_status field value to 1 or 0. I enabled the "Actions" module and created a custom module with my actions, but after the module is installed the actions do not appear.

In my module, I created files with the following structure:

**/src/Plugins/Action/SupportStatusYes.php**

```
<?php
namespace Drupal\support_action\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Session\AccountInterface;
/**
 * Change support status on yes.
 *
 * @Action(
 *   id = "support_status_yes",
 *   label = @Translation("Change support status on yes"),
 *   type = "node"
 * )
 */
class SupportStatusYes extends ActionBase {

  /**
   * {@inheritdoc}
   */
  public function execute($entity = NULL) {
    /** @var \Drupal\node\NodeInterface $node */
    if ($entity->hasField('field_support_status')) {
      $entity->field_support_status->value = 1;
      $entity->save();
    }

  }

  /**
   * {@inheritdoc}
   */
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
    /** @var \Drupal\node\NodeInterface $object */
    $result = $object->access('update', $account, TRUE)
      ->andIf($object->field_support_status->access('edit', $account, TRUE));

    return $return_as_object ? $result : $result->isAllowed();
  }

}

```

**/src/Plugins/Action/SupportStatusNo.php**

```
<?php
namespace Drupal\support_action\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Session\AccountInterface;
/**
 * Change support status on no.
 *
 * @Action(
 *   id = "support_status_no",
 *   label = @Translation("Change support status on no"),
 *   type = "node"
 * )
 */
class SupportStatusNo extends ActionBase {

  /**
   * {@inheritdoc}
   */
  public function execute($entity = NULL) {
    /** @var \Drupal\node\NodeInterface $node */
    if ($entity->hasField('field_support_status')) {
      $entity->field_support_status->value = 0;
      $entity->save();
    }

  }

  /**
   * {@inheritdoc}
   */
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
    /** @var \Drupal\node\NodeInterface $object */
    $result = $object->access('update', $account, TRUE)
      ->andIf($object->field_support_status->access('edit', $account, TRUE));

    return $return_as_object ? $result : $result->isAllowed();
  }

}

```

**/config/install/system.action.support\_status\_no.yml**

```
langcode: en
status: true
dependencies:
  module:
    - node
id: support_status_no
label: 'Change support status on no'
type: node
plugin: support_status_no
configuration: {  }

```

**/config/install/system.action.support\_status\_yes.yml**

```
langcode: en
status: true
dependencies:
  module:
    - node
id: support_status_yes
label: 'Change support status on yes'
type: node
plugin: support_status_yes
configuration: {  }

```

**/config/schema/support\_action.schema.yml**

```
action.configuration.support_status_yes:
  type: action_configuration_default
  label: 'Change support status on yes'

action.configuration.support_status_no:
  type: action_configuration_default
  label: 'Change support status on no'

```

Tell me please what am I doing wrong?

# Answer
> 0 votes
The correct directory structure is src/Plugin, not src/Plugins.

The files in config/schema/ and config/install/ look correct to me. I struggled with those mightily. And I'll emphasize that actions only seem to be registered when the module is installed.

---
Tags: actions
---


# Question
Title: Img tag getting removed in views drupal 8
I am trying to rewrite the results of a field to include an img tag. The first part of the tag then gets stripped, the second part stays:

```
<img src="http://example.com alt="Image" /> results in alt="Image" />.

```

What is causing it and what will be work around for it.

# Answer
I was using wrong image formatter . Instead of rendering the image the image tag was being rendered.
> 0 votes

---
Tags: views
---


# Question
Title: Modifying contribution modules safely and conventionally
I want to modify a contrib module in such a way that I don't lose my customizations whenever I update the module. Below is my git diff from the changes I want to make. I use git and drush.

What I am wondering is, how can I add something to my own custom help module that will have the same affect?

The change I had made was to disable the function in this Facebook connect module that grabs the user's picture and adds it to the profile.

```
+// Disable facebook profile picture integration (CH)
     // If user pictures are enabled, try to get the profile picture from FB.
-    if (variable_get('user_pictures', 0)) {
-      $fid = simple_fb_connect_get_fb_profile_pic($fb_session);
-      if ($fid) {
-        $fields['picture'] = $fid;
-      }
-    }
+//    if (variable_get('user_pictures', 0)) {
+//      $fid = simple_fb_connect_get_fb_profile_pic($fb_session);
+//      if ($fid) {
+//        $fields['picture'] = $fid;
+//      }
+//    }

```

# Answer
You should not modify the contrib module directly and save it. You should create a patch file and use that patch file in the project. This way every time if there is any update in that module, you run drush command and your changed will be safely applied. Please refer this page to create a patch file if you don't know How to create Drupal patch with git.
> 2 votes

---
Tags: 7, hooks
---


# Question
Title: Passing variables from hook_mail to cutom twig template
Custom twig template into hook\_mail()

```
$body_content = array(
    '#theme' => 'mail_body_content',
    '#node' => $node,
);

```

I would like to access to node Entity and display value into the twig

```
myfield_name: {{ node.get('field_myfield_name').value }}

```

Render code

```
$renderedContent = \Drupal::service('renderer')->renderPlain($body_content);

```

Only myfield\_name: is display. How to get / pass the variable to twig ?

# Answer
> 0 votes
Rather than using node get to print a value just use this in twig.

> node.field\_myfield\_name.value

Otherwise preprocess your twig and get only required fields over sending complete node object to twig.

```
function theme_name_preprocess_mail_body_content(&$variables) {
  $variables['myfield_name'] = $variables['node']->field_myfield_name->value; //$variables['node'] will be render $node from your hook_mail() function.
}

```

And in Twig `myfield_name` will work

# Answer
> 0 votes
Passing content (hook\_mail):

```
$body_content = array(
    '#context' => [
        'node' => $node,
    ],
);
$renderedContent = \Drupal::service('renderer')->renderPlain($body_content);
$message['body'][] = $renderedContent;

```

Get content (twig template file):

```
myfield_name: {{ context.node.get('field_myfield_name').value }}

```

---
Tags: theming
---


# Question
Title: How to make CSS and JS both load in the footer
We have a library `slick_carousel` in our `mytheme.info.yml` and `mytheme.libraries.yml` defined in our sub-theme (see below).

How can we make the CSS and JS **both** load in the footer? Currently only the JS file is showing in the footer.

Current `mytheme.libraries.yml`:

```
slick_carousel:
  css:
    theme:
      //cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css: { type: external, attributes: { async: true } }
  js:
    //cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js: { type: external, minified: true  }
  dependencies:
    - core/jquery

```

We have tried, but didn't work. We need to do this without a module.

1. Removing dependency on `core/jquery`.
2. Change `theme` to `component` under `css`.

# Answer
You can just add 'scope' option and pass either 'header' or 'footer' as the value.

```
slick_carousel:
  css:
    theme:
      slick.min.css: { type: external, attributes: { aysnc: true }, scope:footer }
  js:
    slick.min.js: { type: external, minified: true, scope: footer }
  dependencies:
    - core/jquery

```
> -2 votes

---
Tags: 8, theming
---


title: Drush en failing

text:
# Question
Title: Drush en failing
I was trying to install some modules via Drush 9 (9.2.3) on a Drupal 8 (8.5.3) site and I keep seeing the following.

```
[error]  Unable to install modules devel due to missing modules devel.

[error]  Unable to install modules devel due to missing modules devel.

```

I was installing with the command:

```
drush en module_name

```

It is about as vanilla a site as you can get. I have barely started working on it.

How do I fix this?

# Answer
> 8 votes
Downloading contributed modules using Drush (9) has become deprecated. The recommended way to download modules (and themes) is with Composer. Assuming Composer is installed, you can add the contributed module to your project with `composer require drupal/<module_name>`.

Once the contributed module has been downloaded, you can enable it using `drush en <module_name>`.

---
Tags: 8, drush
---


# Question
Title: “Some files and directories in your install are writable by the server.”
I’m running a Drupal 8.5.3 site and the module: Security Review. One od the “red” results was: **Some files and directories in your install are writable by the server.**

```
Details:
“It is dangerous to allow the web server to write to files inside the document root of your server. Doing so could allow Drupal to write files that could then be executed. An attacker might use such a vulnerability to take control of your site. An exception is the Drupal files, private files, and temporary directories which Drupal needs permission to write to in order to provide features like file attachments.
In addition to inspecting existing directories, this test attempts to create and write to your file system. Look in your security_review module directory on the server for files named file_write_test.YYYYMMDDHHMMSS and for a file called IGNOREME.txt which gets a timestamp appended to it if it is writeable.
Read more about file system permissions in the handbooks.
The following files and directories appear to be writeable by your web server. In most cases you can fix this by simply altering the file permissions or ownership. If you have command-line access to your host try running "chmod 644 [file path]" where [file path] is one of the following paths (relative to your webroot). For more information consult the Drupal.org handbooks on file permissions.”
(long list of files, including those of /core, /modules, /themes, etc)

```

Nevertheless if I set the permissions of the core directory to 644 the site does not work. How can I solve this reported warning?

# Answer
> 1 votes
6/4/4 means read+write/read/read - this is OK for files but not for directories. Directories must be executeable, so set them to something like 755 (read+write+execute / read+execute / read+execute).

---
Tags: security
---


# Question
Title: How to add "Agree to terms" checkbox in Drupal 8 form
I've tried several solutions starting from the Boolean checkbox field in the Drupal 8 contact form to this answer, this answer and even this module but none of them work for me.

Basically I just want to display a checkbox which displays the text, "I agree to the terms and conditions of this site", and the words "terms and conditions" needs to be linked to its respective page on the site - to open in a new tab.

Any ideas on how this could be achieved in Drupal 8, via code or even a module is greatly appreciated

This is the code which I tried using in the .theme file

```
function <theme_name>_form_alter(&$form, $form_state, $form_id) {
  switch ($form_id) {
    case 'field_config_edit_form':
      $form['default_value']['widget'][1] = array(
        '#type' => 'checkbox',
        '#title' => t('Your checkbox'),
        '#size' => 10,
        '#maxlength' => 255,
        '#default_value' => 1,
        '#required' => TRUE,
        '#description' => '<p>' . t('Your checkbox altered.') . '</p>',
    );
    break;
  }
}

```

And I need this done on all contact forms of the site

# Answer
> 4 votes
Your code was D7 and what should a checkbox do with `#size` and `#maxlength`? :)

This answer presumes you have the Devel submodule Kint installed.

```
/**
 * Implements hook_form_alter().
 */
function THEME_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  ksm($form_id); // Remove when done.

  if ($form_id == 'MY_FORM_ID') {

    $form['tos'] = [
      '#type'          => 'checkbox',
      '#title'         => t('Terms and Conditions'),
      '#required'      => TRUE,
      '#default_value' => TRUE,
    ];
  }
}

```

Check out this Introduction to Form API.

---
Tags: forms, emails
---


title: Displaying current date on views

text:
# Question
Title: Displaying current date on views
Is there a way to display the current date on views? I just realized that I couldn't use global tokens nor could I get custom date created on Display Suite on views.

# Answer
> 0 votes
1. Install Token Filter.
2. Got to Configuration \> Text Formats and enable Token Filter ("Replace Tokens") for a text format.
3. In your view add Header/Footer "Global: Text Area" and choose the text format from step 2.
4. In the text area write `[current-date:short]` and optionally check `[x] Display even if view has no result`.

Source: https://ffwagency.com/digital-strategies-blog/how-add-current-date-view-drupal-7

---

To do this in the fields section use Advanced Text Formatter, which allows you to choose a text format for "Global: Custom text" fields.

Source: https://www.drupal.org/project/views/issues/1417266#comment-12245061

---
Tags: 7, views, display-suite
---


title: Default front page not showing https

text:
# Question
Title: Default front page not showing https
My website URL shows in browser https

But on https://test.com/admin/config/system/site-information

It's showing http.

What will be cause of this? Server configuration (apache)?

Does it relate to Base URL?

# Answer
Yes. The field prefix is populated by the `RequestContext:: getCompleteBaseUrl()` method, the underlying property, `completeBaseUrl`, is assigned from `$GLOBALS['base_url']` if it's set.

You'll have to test that out to see if that's the case for you, because you might have a web stack configuration that causes Drupal only to see unencrypted requests (e.g. HTTPS only handled at your load balancer / proxy server level), thus displaying the HTTP base.
> 0 votes

---
Tags: 8
---


# Question
Title: Why do I get an error about the modules/custom directory not existing?
I have installed Drupal 8 on Ubuntu. All works well, but I cannot create a new module using Drupal Console.

When I run `drupal generate:module`, I get the following error message.

> \[InvalidArgumentException\]
> Module path "/var/www/html/maryem/modules/custom" is invalid. You need to provide a valid path.

Why? How can I avoid that error message?

# Answer
There is no such thing as `modules/contrib` or `modules/custom` with the vanilla download of Drupal.

It is a convention you can use for organization. Create the folders yourself. Drupal will still find the modules in either one. The same principle applies to the `themes` folder. Some modules that say "download the JS plugin to /libraries" - you would have to create this folder too.

Drush, Drupal Console, and Composer all understand this, as well. If you are using Composer, you just need to inform it in your root composer.json, example:

```
    "installer-paths": {
        "docroot/core": [
            "type:drupal-core"
        ],
        "docroot/modules/contrib/{$name}": [
            "type:drupal-module"
        ],
        "docroot/modules/custom/{$name}": [
            "type:drupal-custom-module"
        ],
        "docroot/profiles/contrib/{$name}": [
            "type:drupal-profile"
        ],
        "docroot/profiles/custom/{$name}": [
            "type:drupal-custom-profile"
        ],
        "docroot/themes/contrib/{$name}": [
            "type:drupal-theme"
        ],
        "docroot/themes/custom/{$name}": [
            "type:drupal-custom-theme"
        ],
        "docroot/libraries": [
            "type:drupal-library"
        ],
        "drush/contrib/{$name}": [
            "type:drupal-drush"
        ]
    }

```

When requiring modules, profiles, or themes, Composer will then place them in the appropriate directory.
> 3 votes

# Answer
Use chown to change ownership and chmod to change rights.

example: sudo chown -R username:group directory thks !
> 0 votes

# Answer
Old issue still the answer is missing. The path needs to exist before running the console command. The error message means that "/var/www/html/maryem/modules/custom" does not exist. Options:

1. Provide the correct path when the folder does exist
2. Create all the directories in the path in /var/www/html/maryem/modules/custom For instance when custom is missing it should be created in /var/www/html/maryem/modules before I run de console command.

In my case I provided --module-path=/modules/custom which expects to find it in the root of the server. Since I was running the console command in the web server document root of Drupal, I should have used a relative path like this --module-path=modules/custom or a correct absolute path like you did in your example.
> -1 votes

---
Tags: 8, console
---


# Question
Title: Problem changing language - Redirection to installation
By browsing my website in Drupal, I can browse perfectly through all the sections. The website has 3 languages. For Spanish, I can navigate well. For English, I can navigate well

But any page I try to access in Portuguese, redirects me to "core / install.php"

I have cleaned cache, I have reviewed everything, and it only happens to me when I change or try to navigate in Portugues.

Because it can be? Drupal version: 8.3.7 Drush version: 9.0-dev-g105e0aa

# Answer
> -1 votes
Increase the size of max\_allowed\_packet = 16M in the my.cnf file of mysql

---
Tags: i18n-l10n
---


# Question
Title: How to use drush with a specific PHP Instance
What drush command can I use to tell drush to use php 5.6 instead of 7.1 which my site is currently running on.

A million thanks in anticipation.

# Answer
> 0 votes
Drush is just a PHP script at heart so all you need is this:

```
/path/to/my/php /path/to/my/drush  ...

```

---
Tags: drush
---


# Question
Title: How to wrap body text around image for drupal 8
How to wrap body text around image for drupal 8. I found tutorial for drupal 7 here https://www.drupal.org/forum/support/post-installation/2008-06-30/how-to-wrap-body-text-around-image, but I still confused to implement this for drupal 8.

I found some css files inside css folder and which one that I have to edit?

# Answer
Don't edit css files in a contrib theme, because the changes will be overwritten when updating the theme. Create a subtheme and add a library with your own css file, see https://www.drupal.org/docs/8/theming-drupal-8/creating-a-drupal-8-sub-theme-or-sub-theme-of-sub-theme
> 0 votes

---
Tags: media
---


# Question
Title: How do you do a redirect after a batch job?
I'm working on setting up a batch process in Drupal 8 that will gather a bunch of remote information for a collection of entities, cache it, and create a list of the results on its own page. The batch process is kicked off from a form using `batch_set()`.

The batch job runs fine, but I'm not sure how to do the redirect at the end. Since Drupal 8 uses RedirectResponse objects or `$this->redirect('user.page');` in a controller and the callback for a batch job doesn't have a return type, I'm not sure what to use to trigger the redirect.

I've tried using the url\_options value of the batch job definition but that's not working.

```
$batch = [
  'title'    => $this->t('job running'),
  'init_message' => $this->t('starting job'),
  'operations'  => $ops,
  'finished' => '\Drupal\my_module\MyClass::finished',
  'url_options' => [
    'query' => [
      'destination' => '/job/results',
    ],
  ],
];

```

# Answer
> 11 votes
Apparently I needed to ask to see the answer: return a `RedirectResponse` from the finish callback:

```
public static function finished($success, $results, $operations) {
  if ($success) {
    // Here we do something meaningful with the results.
    $message = t("@count tasks were done.", array(
      '@count' => count($results),
    ));
    drupal_set_message($message);
  }

  return new RedirectResponse('/job/results');
}

```

As far as I can tell this is an undocumented behavior.

From the helpful comment below, you can also add `batch_redirect` on the batch array that's either a string or Url object:

```
$batch = [
  'title'    => $this->t('job running'),
  'init_message' => $this->t('starting job'),
  'operations'  => $ops,
  'finished' => '\Drupal\my_module\MyClass::finished',
  'batch_redirect' => '/job/results',
];

```

# Answer
> 8 votes
This does not seem to work when creating the batch in a form submit handler, the redirect part in $batch is simply ignored.

Redirecting from the submit handler like this works for me:

```
$form_state->setRedirect('route.name');

```

---
Tags: 8, batch-operations
---


# Question
Title: CKeditor not showing for authorized users
Drupal 8.5.3, all modules and themes up to date.

The CKEditor only shows up for *administrator* users when creating or editing nodes. The *authorized* users are listed as Roles for the Text Format "Basic HTML" which is the Text Format for the field in the Content Type too.

There is a javascript error being thrown in /core/modules/ckeditor/js/cheditor.js, line 134 saying "drupalSettings.ckeditor" is undefined.

Thanks, Greg

# Answer
It's fixed!

Turns out it was a problem (errant quote) in html.html.twig that was breaking document.querySelector in drupalSettingsLoader.js so *nothing* in drupalSettings was defined...
> 1 votes

# Answer
it would be helpful if you could share a screenshot. However, if you have not yet done so, verify that the CKEditor's permissions are enabled for that role and be sure to also verify the permissions of the directory where the module is located.
> 0 votes

---
Tags: 8, wysiwyg
---


# Question
Title: How do I store node form data between form steps using ajax?
I want to turn a node form into a multi-step form using ajax. I've added ajax-enabled submit buttons and some logic in a `hook_form_alter` (see below) to handle inc- and decrementing steps, and showing and hiding form items based on the current step. The stepping back and forth works great, in terms of rendering the correct elements.

The problem is, if I enter some data in one step, go forward or backward, and then return to the original step, the data I entered is gone from the form. If I check the value of the item for which I entered data using `FormStateInterface::getValue()`, the data is there when my alter hook runs when leaving the original step, but gone on subsequent next/back transitions. This problem also does not apply to data that is already in the form (e.g. when editing an existing node).

Clearly, I need to store the incoming values somewhere, but where? And then, how do I restore them to the form elements on the appropriate step?

My code (minimal example):

```
<?php
/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_module_form_node_ajax_test_form_alter(&$form, $form_state) {
  // Define steps. Each child array is a step, and each string in the
  // a child array is a field that should be present on that step.
  $steps = [
    ['title'],
    ['body'],
  ];
  // Add wrapper.
  $form['#prefix'] = '<div id="ajax-form-wrapper">';
  $form['#suffix'] = '</div>';
  // If the step is not set, this is step 0.
  if (!$form_state->has('step')) {
    $form_state->set('step', 0);
  }
  // Get the current step.
  $step = $form_state->get('step');
  // If we have a triggering element, increment or decrement step as
  // appropriate.
  if ($trigger = $form_state->getTriggeringElement()) {
    switch ($trigger['#name']) {
      case 'next':
        $form_state->set('step', ++$step);
        break;

      case 'back':
        $form_state->set('step', --$step);
        break;
    }
  }
  // Show elements in the current step, hide others. Always show the
  // `actions` element, and all `form_*` elements.
  foreach (Element::children($form) as $element) {
    $form[$element]['#access'] = (
      in_array($element, $steps[$step])
      || $element == 'actions'
      || strpos($element, 'form') === 0
    );
  }
  // Show the back button if this is not the first step.
  $form['actions']['back'] = $step > 0 ? ajax_button('back') : NULL;
  // Show the next button if this is not the last step.
  $is_last_step = $step == count($steps) - 1;
  $form['actions']['next'] = !$is_last_step ? ajax_button('next') : NULL;
  // Show the submit button if this is the last step.
  $form['actions']['submit']['#access'] = $is_last_step;
}

/**
 * Return a render array for an ajax step button.
 */
function ajax_button($name) {
  return [
    '#type' => 'button',
    '#value' => $name,
    '#name' => $name,
    '#ajax' => [
      'wrapper' => 'ajax-form-wrapper',
    ],
  ];
}

```

# Answer
Well, I figured it out. (This was before @4k4's answer, which is very close to what I ended up with).

I needed to build the entity using the submitted form values and then set the form to rebuild (which puts the values from the entity into the form) in a submit handler. Here's how I did it:

```
<?php
/**
 * Return a render array for an ajax step button.
 */
function ajax_button($name) {
  return [
    // Changed from 'button', buttons don't invoke submit handlers,
    // submits do.
    '#type' => 'submit',
    '#value' => $name,
    '#name' => $name,
    // Set the submit handler.
    '#submit' = ['my_module_ajax_form_submit'],
    '#ajax' => [
      'wrapper' => 'ajax-form-wrapper',
    ],
  ];
}

/**
 * Build entity using submitted form data and rebuild form.
 */
function my_module_ajax_form_submit($form, $form_state) {
  // Get the NodeForm object.
  $form_object = $form_state->getFormObject();
  // NodeForm::buildEntity() maps form values into the entity object
  // and returns it.
  $entity = $form_object->buildEntity($form, $form_state);
  // NodeForm::setEntity() stores the entity in the form object which
  // is used to populate form fields when the form rebuilds.
  $form_object->setEntity($entity);
  // Set the form to rebuild.
  $form_state->setRebuild()
}

```

I got here by following very closely the various implementations of `::buildEntity()` and `::buildForm()` in `NodeForm` and its ancestors `ContentEntityForm` and `EntityForm`.
> 1 votes

# Answer
This code is quite impressive. I did not think it was possible to build a multi-step entity form with a few lines in a form alter hook. To keep it this simple you can try to use the entity object to store the values, because the form object is serialized and cached between the steps and a method to build such an entity from the submitted values is part of the entity form class:

```
  if ($trigger = $form_state->getTriggeringElement()) {
    $form_object = $form_state->getFormObject();
    $new_entity = $form_object->buildEntity($form, $form_state);
    $form_object->setEntity($new_entity);

```
> 4 votes

# Answer
I think you need to use the symfony sessions

Set session variable

```
$session = \Drupal::request()->getSession();
$session->set('mymodule_variable', 'value');

```

Later on you can get this variable like this

```
$session = \Drupal::request()->getSession();
$value = $session->get('mymodule_variable', 'default_value');

```

Symfony sessions are equivalent to php $\_SESSION
> 0 votes

# Answer
It seems that the correct way todo this is with PrivateTempStore, if you go to see the CommentAdminOverview in Core you will see this:

```
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
      ...
      $info = [];
      /** @var \Drupal\comment\CommentInterface $comment */
      foreach ($comments as $comment) {
        $langcode = $comment->language()->getId();
        $info[$comment->id()][$langcode] = $langcode;
      }
      $this->tempStoreFactory
        ->get('comment_multiple_delete_confirm')
        ->set($this->currentUser()->id(), $info);
      $form_state->setRedirect('comment.multiple_delete_confirm');
    }
  }

```

In this page you collect the comment id that you want to delete and made a redirect, and the comment deletion happens in `comment.multiple_delete_confirm` (ConfirmDeleteMultiple) that have the following code:

```
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $this->commentInfo = $this->tempStoreFactory->get('comment_multiple_delete_confirm')->get($this->currentUser()->id());
    if (empty($this->commentInfo)) {
      return $this->redirect('comment.admin');
    }
    /** @var \Drupal\comment\CommentInterface[] $comments */
    $comments = $this->commentStorage->loadMultiple(array_keys($this->commentInfo));
  ...
  }

```

Views also works with PrivateTempStorage, this is why when you return to a view that is not saved you can see again the changes.
> 0 votes

---
Tags: 8, nodes, forms, ajax
---


# Question
Title: How to filter users based on address location?
I have a content type "job". There is a field "location" which contains the zip code of area. Now i want to filter users based on distance from job's zip code. Each user also have a zip code. I already have a view which is filtering users on different criteria. Is there any way to achieve this in view?

***EDIT*** here is what exactly i needed. adding a job should have a field to add the zip code of the location of the job. This should change the way the users are filtered for the job as the customer should be able to filter the users using radius selector for 1 km, 5km, 10km, less than 50 km. Thanks

# Answer
> 1 votes
I believe this is what you are looking for https://www.drupal.org/node/1944648

# Answer
> 1 votes
You can use geolocation\_proximity

---
Tags: 7, views, location
---


# Question
Title: Create a custom function to convert a field data
In Drupal 7, I can create a custom function in the template.php file. here is an example of custom function:

```
function myCustomFunction($arg) {
    $data_converted = $arg . 'XXXXX';
    return $data_converted;
}

```

...and in Drupal 7 and inside my template I can call this function with passing a specific data / field data.

In Drupal 8, it's different, and I don't see how to proceed. In my .theme file, I tried to create a custom function. In my twig template I tried to call this custom function but I get an error : function not found.

With drupal 8 how can I proceed to implement a custom function (with args) ? Thanks for your help, and eventualy yours examples.

# Answer
> In Drupal 7, I can create a custom function in the template.php file

To cut a very long story short, in Drupal 7 you should ideally have been calling that function in a preprocess function, to prepare variables for the template, rather than calling it from the template directly.

In Drupal 8 it's now Fine™ to call functions directly in the template. But now you can't use PHP directly, so you need to write a Twig extension.

It's very easy, core even has its own that you can copy from. The important thing is to register the service class with a `twig.extension` tag, so the system picks it up.

See this blog post for a full example.
> 2 votes

---
Tags: 8, theming
---


title: Change View format in PHP

text:
# Question
Title: Change View format in PHP
I have a Drupal 7 site and I would like to change the view format with a button click, so I want to ask if it is a way to change the configuration of a View page with php.

In a view page configuration, the option is this:

Now it has "List without format" value.

# Answer
It is possible to call a View using PHP code. It is also possible modify a view using code such as `hook_views_pre_view()` to change how a View is displayed dynamically.

I actually wouldn't do either for your request. Simply do the following:

* In your View make 2 `displays`.
    + 1 view display that shows the Grid format.
    + 1 view display that shows the list format.

On the page in question use an HTML button, html link, or even a Rules Link that uses Ajax to reload the div on the page and calls the view with the correct display mode you want. Your ajax call will be calling like: `$view = views_embed_view('MY_VIEW_NAME', 'display_id');` and updating the page with `$view` contents via Ajax.

So make 2 view displays, and learn how to call them using Ajax.
> 0 votes

---
Tags: views
---


# Question
Title: Can you tell which page you're on of a DB API pager?
I'm doing the usual sort of Drupal 7 DB API pager stuff to work through a bunch of items, e.g (greatly simplified):

```
$the_nodes = db_select('node', 'n')->extend('PagerDefault');
-- conditions, fields, etc. --
$the_nodes->limit(10);
return $the_nodes->execute()->fetchCol();

```

and then the appropriate rendering code to make the pager study appear, of course.

What I'd like to be able to do is, from inside the function containing this query, to be able to tell which page of the pager I'm on -- in particular, if I'm on the first page, or not. The idea is to insert a couple of other records at the beginning of the list, but only on the first page.

So: Does anybody know if this is possible? Thanks!

# Answer
Instead of access `$_GET` directly, you should use pager\_find\_page().
> 2 votes

# Answer
For future reference: I figured this out. The key is to (duh) check the URL. The first page of a pager looks like:

https://example.com

while the second looks like:

https://example.com?page=1

and so on. So, checking to see if `$_GET['page']` is set (or, for paranoia's sake, has a non-zero value) will tell you if you're on the first page or something else. Comments/criticisms are welcome, but I think this does it.
> 0 votes

---
Tags: 7, database
---


# Question
Title: How can I create a newsletter with the last five news nodes?
I need to create a newsletter where І can send the latest five news nodes in Drupal 8. Maybe you can recommend any module or custom method. I tried to use the Simplenews module, but with Drupal 8 nothing comes out.

# Answer
> 1 votes
1/Create a view with the last new nodes (and their fields) with a block display
2/Make this view's display available as a variable for your newsletter by using a preprocess function in YOURTHEME.theme, something like:

```
function YOURTHEME_preprocess_simplenews_newsletter_body(&$variables) {
$variables['latestnews'] = views_embed_view('latestnews', 'block_1');
}

```

Create a template for the newsletter body simplenews-newsletter-body--\[newsletter\_id\].html.twig (newsletter\_id = machine name). and add your view in it where you'd like to:

```
{{ latestnews }}

```

Then, on top of it, you may need to use Swiftmailer/Mimemail for better styling output. That requires another layer of configuration and template.

# Answer
> 0 votes
I would use free Mailchimp plan and create a campaign that uses an RSS feed to populate its content. The RSS feed can be created by Views. In the View, set a filter to select only News content type, sorted by created DESC, that are published, and set a limit to 5 results only. Then just select the fields from the content type that you want to output in the View.

I have never had a lot of luck trying to run newsletters out of Drupal itself. You wouldn't need any module to do this other than Views.

Mailchimp has a lot of tokens and helpers to help you inject the RSS feed content and work with it. Its how we run our own internal newsletters.

---
Tags: 8, emails
---


# Question
Title: Context condition per menu (not menu item)
I'm using Context module on Drupal 7 to show menu block on pages that's listed in that menu only.

Everything's good, I set 'Menu' condition and reaction is to show the block in some region, but the problem is that I must select menu items in condition and since items changes all the time I need to update Context all the time.

Is there some solution to select menu and not menu item, or to select menu item and automatically to include all submenu items?

# Answer
> 0 votes
There doesn't seem to be a way to select a menu itself in Context Conditions.

Maybe you have something else common among those menu items that you can combine in different Conditions to get the same result? Maybe paths are similar? Or Content types?

Alternatively you can use a module other than Context just for this particular need: Blocks per menu.

# Answer
> 0 votes
Instead of using the `menu` as condition select `path` and enter the relative paths, like:

> articles
>
> articles/\*
>
> page1
>
> page2
>
> content/\*
>
> **content-type-url**/\*

Do you have specific reason to use menu as condition? just wondering!

---
Tags: 7, blocks, navigation
---


# Question
Title: Moving the fields and data from one content type to another content type
I have created a content type called "ContentA" and in that content type I have two fields, "Summary" and "Title". I have already created a new content type called "ContentB" and it is also having the same fields. What I need to do is move the data and fields everything from the first content type "ContentA" to second content type "ContentB" and I'm using Drupal 7. I tried the node convert module, it is allowing only each node at once, I am having approximately 500 nodes, I cannot use that module. So looking for any module/script for bulk transfer

Is this possible with a module or maybe from SQL. I don't know what to do, I've been trying to do this from weeks and I'm stuck :( please help!

# Answer
> 0 votes
you can definitely accomplish this with the migrate module (https://www.drupal.org/project/migrate). Your source DB and your destination DB will be the same, but that is acceptable. You're essentially migrating ContentA nodes into ContentB nodes and since they both have the same fields the mapping should be very simple.

---
Tags: 7, nodes, commerce
---


# Question
Title: PHP Fatal error: Cannot redeclare composerRequireDrupal8()
I recently nstalled Drush using `composer global require drush/drush:dev-master` and it got installed successfully.

I ran command `which drush` and the terminal gave me /home/ravi/.composer/vendor/bin/drush.

I am not able to execute any command from the project root. I get this error.

> PHP Fatal error: Cannot redeclare composerRequireDrupal8() (previously declared in /var/lib/composer/vendor/composer/autoload\_real.php:63) in /var/www/html/study/drupal/8/vendor/composer/autoload\_real.php on line 70

But when I `/home/ravi/.composer/vendor/bin/drush status`, then Drush works perfectly well.

Is there any way to use Drush from the project root?

PS: I have tried updating Composer, but it didn't help.

# Answer
> Please do not install Drush using composer global require.

Quoted from http://docs.drush.org/en/8.x/install-alternative/.

If you have Drupal 8 installed conventionally best practice would be to install Drush 8 globally by downloading the latest drush.phar, see http://docs.drush.org/en/8.x/install/.

If your Drupal 8 site is composer based then Drush 9 is probably already included. If not see http://docs.drush.org/en/master/install/.
> 0 votes

---
Tags: 8, drush, composer
---


# Question
Title: Get node internal path from path alias in Twig template
I want to get the internal path of a node from its path alias. In Drupal 7 we could use `drupal_get_normal_path()` directly in the PHP template.

With Drupal 8, Is there a function to get the internal path from an alias inside a Twig template?

In my Twig template I have tried to use the `url()` function without success...

e.g. `{% set path = url('myalias') %}` ...

# Answer
You should not be running Drupal functions inside TWIG templates, the best approach is to use a pre-processor as mentioned in the comments. You can do this by setting a variable inside a hook being called either in your theme file or custom module and setting like this:

```
$vars['your_custom_variable'] = $unaliasedNodePath

```

And then inside your twig template you can use the variable set in your pre-processor like this:

```
{{ your_custom_variable }}

```

More information can be found here:

https://www.drupal.org/docs/8/theming/twig/twig-best-practices-preprocess-functions-and-templates
> 1 votes

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


# Question
Title: Find specific node to uninstall a module
I want to uninstall a module but I'm getting the following message. The "Name of Module" field type is used in the following field: node.field\_feature\_interest. How can I find this node so I can remove their relationship between each other so that I can delete the module?

# Answer
I figured out how to do it:

1. Go to content types
2. Features Article -\>Manage Fields
3. Delete field
> 0 votes

---
Tags: nodes, installation
---


title: Contextual filter by month and year

text:
# Question
Title: Contextual filter by month and year
We have a site finally patched all the way up to 8.5.3. Our old site (8.4.0) was using a Views patch (just for reference) that allowed for a content date field to be contextually filtered by month and year using a URL like https://example.com/events/042018, which returned all events for April, 2018.

This patch is no longer applicable to the Views module 8.5.3. It seems to be integrated for *Created Date* and *Updated Date*, but I don't need these fields. I am trying to access a content date field that I made.

Does anyone know how to do this?
Can you help me get started on creating a custom views contextual filter handler that can access this custom date field?

**Example of view:** Show all events filtering by date, but instead of an exact date, only grab month and year parts.

>

# Answer
> 1 votes
Views 8 is still developing the use of granular date filters for content daterange fields. This is needed for making month calendars, year calendars, etc.

**SOLUTION**

For Drupal 8.5.x Views, anyone trying to select content by MONTH & YEAR on a daterange field, install the following patch until it's integrated with core:

**2786577-270.patch**

https://www.drupal.org/project/drupal/issues/2786577?page=1

Comment #318. For earlier versions of Drupal 8, simply scroll back in that thread and look for the patch applicable to your version.

**After installing the patch:**

1. Edit your view
2. Under Advanced \> Contextual Filters \> Add
3. Filter by "date"
4. You will now see all of your content date fields with date parts available as filters. Choose year\_month or any other date part you want
5. You can now filter or contextually filter by date part
6. Important: Keep your eye on core updates as newer versions of this patch may need to be applied again

**Displays all content where the custom date field is anytime in April 2018. e.g. Display all events on calendar in April.**

# Answer
> 4 votes
1. Remove your date contextual filter, by clicking remove.
2. click Add a contextual filter, and search for the date field and select the "Year+month" granularity. Then click add.

once you are done you should have your contextual filter look like this:

Now you can go `events/201807` and it would give you the same results.

update: this granularity is available for all date fields under the contextual filter option `(node.field_somedatefield (year_month)` provided the field has been added normally using content types manage fields section:

---
Tags: 8, views
---


# Question
Title: Redirect Module doesn't redirect from node/{nid} to alias
I installed the redirect Module in Drupal 8 but sorrily can't get it to work properly. I enabled all checkboxes in the settings, also the "Enforce clean and canonical URLs" option.

In my page source, the canonical is printed in a meta tag. But if I browse my page and enter a system URL like www.domain/node/5, no redirect to the autopath alias / canonical happens.

Does anyone have any suggestions? I also reinstalled it twice already. Nothing helped.

# Answer
> 2 votes
LEL - it's so stupid, I have to clarify this. The redirect module works without any problem. Everything's just like I wanted it. Maybe it's pointed out anywhere, but I didn't read it.

When the page is set to maintenance mode, it doesn't work. I have some dummy-users that can bypass the "maintenance-page" and use the site. While the site is in maintenance mode, the node/IDs are accessible. When I turned off maintenance mode, the module was redirecting...

---
Tags: 8, uri, redirection
---


# Question
Title: Custom Styles Applying to page.html.twig but not html--front.html.twig
I'm new to drupal and am trying to make my own theme. Currently I have a `page.html.twig` for my pages, and my css styles show up fine. However, when I added a `html--front.html.twig` file, cleared the caches, and checked the homepage, there were no styles, even ones that apply to elements that are in every page (such as `body`). The code in `html--front.html.twig` is identical to the code in `page.html.twig`. I checked the console and the front page *is* successfully templating from `html--front.html.twig`. Every other page works fine. I just don't see why it is now ignoring all my styles for the front page. Here is the code for both pages:

```
<header role="banner">
    {{ page.header }}
  </header>
<div class="layout-container">
  <main role="main">
    <a id="main-content" tabindex="-1"></a>{# link is in html.html.twig #}

    <div class="layout layout-content">
      {{ page.content }}
    </div>

</div>

```

# Answer
> The code in html--front.html.twig is identical to the code in page.html.twig

That's your problem - those are two different templates, it doesn't make sense for them to have the same content.

html.html.twig *contains* (or more accurately, renders) page.html.twig, plus the `<head>` tags and all that lives within, the footer of the document, and so on. If you copied page.html into html.html, that explains why you don't see styles any more - your `<head>` is gone.

It's perfectly valid to have html--front.html.twig and page--front.html.twig, or some other combination, but the html template needs to contain the outer part of the document, and the page template needs to contain the inner part.
> 1 votes

---
Tags: theming
---


# Question
Title: Filling form with user entered values after submit
How do I fill a custom form with the values entered from the users before the form was submitted? I have saved the `$form_state` values, but when I put them back into `$form_state` on loading, the form fields aren't filled.

# Answer
> 3 votes
Drupal 7

If you are not redirecting and want to preserve the values in the Form API fields add `$form_state['rebuild'] = TRUE;` on the submit handler.

```
/**
 * FORM submit handler.
 */
function FORM_form_submit($node, &$form_state) {
  // Rebuild the form and keep the filter values.
  $form_state['rebuild'] = TRUE;
}

```

---

Drupal 8

In Drupal 8 you would use `$form_state-> setRebuild();`

See public function FormState::setRebuild for more detail.

Custom submit handlers in Drupal 8 are dealt with differently — here is some useful discussion on Drupal 8 submit handlers.

# Answer
> 1 votes
I think you want to put them in `$form['element_name']['#default_value']` not `$form_state`. What you're describing sounds odd, though. Why are you adding a user's information back into a form after they already entered it?

# Answer
> 1 votes
Values entered in a form should be validated in a form validation handler. When the validation handler finds values that are invalid, it should call form\_error() or form\_set\_error(); in that case, the form would be presented back to the users with the values they entered. The only form field that is reset is the password form field, for which presenting the previously entered value would not have any sense, since the users would just see a string made of "•" (or the character that replaces the input used by the browser).

The purpose of form submission handlers is not to validate the entered values, but to save them, or using them to create the required output.

# Answer
> 0 votes
When form submit fails you must set `$form_state['redirect']` to `false`. By default after submit form is reloaded and form fields cleared out. But when redirect is set to false form will not be redirected and form fields will remain filled.

---
Tags: forms
---


# Question
Title: views exposed filter does not redirect to itself
I came across to issue with exposed filter in my view. In a view's preview everything works fine. But on the page, after clicking apply button, the site redirects to front page, with get parameters in URL. What is wrong with this? I did everything in a UI and I didn't work with code. Thanks.

# Answer
> 1 votes
Look at the "Advanced" pane on the View config page: There is "Link display" where you can define custom URL for the view - it's something like a "base path" for the view and the exposed filter values will be added to it, e.g.: if you define `my-view-path` than the filtered view has the path `my-view-path-?filter_1=true&filter_2=false&filter_3=&filter_4=0`.

Hint: If you have created a panel pane you have to set "Link to view" to `yes` in "Pane settings" to make use of path/URL defined in "Link display".

# Answer
> 0 votes
I had this problem, although perhaps not in exactly the same configuration as that described in the question.

I have a Views Page with an exposed block. The exposed block works when placed on the page, but not when I place it in a panel. The block would use the path of the current page rather than redirecting to the Views page.

The solution was do disable the "Inherit Current Path" option in the block settings in my panel.

---
Tags: views
---


# Question
Title: Core Drupal8 JS necessary for Drupal theme to function
I have recently noticed that Drupal8 is adding number of JavaScript files. I would like to know if it is necessary for theme to function

```
<script src="/core/assets/vendor/domready/ready.min.js?v=1.0.8"></script>
<script src="/core/assets/vendor/jquery/jquery.min.js?v=2.2.4"></script>
<script src="/core/misc/drupalSettingsLoader.js?v=8.3.7"></script>
<script src="/core/misc/drupal.js?v=8.3.7"></script>
<script src="/core/misc/drupal.init.js?v=8.3.7"></script>

```

My theme does not use any of them. I would like them to be removed. Can anyone here tell me how to remove them?

# Answer
> 0 votes
In your `.info.yml` file specify:

`libraries-override:
 core/drupal.active-link: false`

You may have to remove more libraries, but this one is specifically for the files you mentioned.

---
Tags: theming
---


# Question
Title: How can I add custom classes to each view's generated row?
Is it possible by using the theme preprocessor add some classes to views generated rows?

For example: based on Drupal site about default theme implementation to display a view of unformatted rows.
views-view-unformatted.html.twig:

> Available variables:
> \- **title:** The title of this group of rows. May be empty.
> \- **rows:** A list of the view's row items.
> \- **attributes:** The row's HTML attributes.
> \- **content:** The row's content.
> \- **view:** The view object.
> \- **default\_row\_class:** A flag indicating whether default classes should be used on rows.

I know that it's possible and we can add our desired classes to each row inside the `views-view-unformatted.html.twig`:

```
{% if title %}
  <h3>{{ title }}</h3>
{% endif %}
{% for row in rows %}
  {%
    set row_classes = [
      default_row_class ? 'views-row',
    ]
  %}
  <div{{ row.attributes.addClass(row_classes) }}>
    {{ row.content }}
  </div>
{% endfor %}

```

But I want to understand is it possible to do the same thing for custom views like `front-page` by use of:
function template\_preprocess\_views\_view\_unformatted\__frontpage in particular
or in other template\_preprocess\_views\_view generally?

# Answer
> 10 votes
If you look at /core/modules/views/views.theme.inc at template\_preprocess\_views\_view\_unformatted you'll see this code:

```
function template_preprocess_views_view_unformatted(&$variables) {
  $view = $variables['view'];
  $rows = $variables['rows'];
  $style = $view->style_plugin;
  $options = $style->options;

  $variables['default_row_class'] = !empty($options['default_row_class']);
  foreach ($rows as $id => $row) {
    $variables['rows'][$id] = [];
    $variables['rows'][$id]['content'] = $row;
    $variables['rows'][$id]['attributes'] = new Attribute();
    if ($row_class = $view->style_plugin->getRowClass($id)) {
      $variables['rows'][$id]['attributes']->addClass($row_class);
    }
  }
}

```

This is how if you have set a row class in the view, it gets added.

And the resulting output:

You can copy this function to your custom module and customize it as you like. For example, this will add the "views-row-" plus the name of your view cleaned up using the pathauto cleanstring utility:

```
function mymodule_preprocess_views_view_unformatted(&$variables) {
  $view = $variables['view'];
  $rows = $variables['rows'];

  foreach ($rows as $id => $row) {
    // Add custom class to each row that encorporates the view id.
    $custom_row_class = \Drupal::service('pathauto.alias_cleaner')
      ->cleanString($view->id());
    $custom_row_class = 'views-row-' . $custom_row_class;
    $variables['rows'][$id]['attributes']->addClass($custom_row_class);
  }
}

```

If you would like to add classes to a views rows from hook\_preprocess\_views\_view, you can do it this way:

```
function mitsloan_global_preprocess_views_view(&$variables) {
  $view = $variables['view'];

  if ($view->id() == 'testview') {

    $row_style_plugin = &$variables['rows'][0]['#view']->style_plugin;

    $custom_row_class = 'views-row-' . \Drupal::service('pathauto.alias_cleaner')
        ->cleanString($view->id());

    $row_style_plugin->options['row_class'] = $custom_row_class;
  }

}

```

# Answer
> 3 votes
You can also check various loop variables defined by twig and use them to apply unique classes, e.g.

```
{% for row in rows %}
    {% if (loop.index == 1 ) %}
        {% set is_active = 'is-active' %}
    {% else %}
        {% set is_active = '' %}
    {% endif %}
    <li class="{{ is_active }} counter{{ loop.index }}">
        {{ row.content }}
    </li>
{% endfor %}

```

**loop.index** The current iteration of the loop. (1 indexed)

**loop.index0** The current iteration of the loop. (0 indexed)

**loop.revindex** The number of iterations from the end of the loop (1 indexed)

**loop.revindex0** The number of iterations from the end of the loop (0 indexed)

**loop.first** True if first iteration

**loop.last** True if last iteration

**loop.length** The number of items in the sequence

**loop.parent** The parent context

# Answer
> 2 votes
Not tested, but I think this will work:

```
function template_preprocess_views_view(&$variables) {
  $view = $variables['view'];
  $id = $view->storage->id();

  if ($id == 'view_name' && $view->current_display == 'block_1') {
    $variables['attributes']['class'][] = 'custom-class-name';
  }
}

```

**Note** the `$view->current_display` is the machine name.

* You can remove the `&& $view->current_display == 'block_1'` part if you don't want it to be this specific.
* You can remove the if statement if you want to affect ALL views.

# Answer
> 0 votes
Does it need to be conditional or just a view added to each row? You can do that in the UI. The front page rows can have a class added to them by doing to /admin/structure/views/view/frontpage and clicking on "settings" next to "unformatted list". This has a row class field which might be what you're after.

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


# Question
Title: Theme developer module crashes the whole site when enabled, how to fix?
I'm working on a clean Drupal 7.x installation, downloaded Theme developer and its dependent module simplehtmldom API( another required module for Theme developer) using drush.

I found out that simplehtmldom 7.x-2.x is incompatible; so I removed it, and Installed the 7.x-1.12 version using Drush, enabled it, enabled the *Theme developer* module was available to be enabled. Now the site doesn't work anymore.

All I'm seeing is just some tags like this.

```
< /> < /> < /> < /> < /> < /> < /> < /> < /> < />

```

The problem is fixed when I disable the *Theme developer* module manually with Drush; everything gets back to normal, when I disabled that module.

I've tried to navigate the site using `/node/1` and tried to go to the administration panel; all I noticed is that the title of the page (the one appearing on the browser's tab) appears but the content seems to be the same.

How do I solve this issue?

This is a screenshot.

>

# Answer
> 0 votes
I did manage to get it to work properly … eventually. This is how, on D7 7.5.

1. Download and install Theme Developer 7x. Do not enable yet.
2. Download and install SimpleHTMLDom 7.x-1.12. Do not enable yet.
3. Download SimpleHTMLDom library from http://sourceforge.net/projects/simplehtmldom\] and install to sites/all/libraries, so that your library path is sites/all/libraries/simplehtmldom/simple\_html\_dom.php.
4. Now you can run `drush en -y devel_themer` and it will automatically enable the simplehtmldom.

I did notice that my /tmp folder was not giving correct permissions to the /tmp/devel\_themer folder, so doing a `chmod -R` on that fixed the problem.

# Answer
> 0 votes
I had the same issue and I could solve it by switching from PHP7 to PHP5.6 when using the Theme Developer (7.x-1.x-dev).

---
Tags: 7, theming
---