# Question
Title: How can I get the submission ID in a custom submit handler?
I have added a submission handler in a .module file to execute some custom code when a webform is submitted.

```
function mh_newsletter_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'webform_submission_newsletter_node_26_add_form') {
    $form['#validate'][] = 'mh_newsletter_form_validate';
    $form['actions']['submit']['#submit'][] = 'mh_newsletter_form_submit';
  }
}

function mh_newsletter_form_submit($form, &$form_state) {
  // Custom code
}

```

I'm unable to access the webform submission ID. How can I get that value?

# Answer
> 2 votes
To get the webform submission ID in a custom form handler, I used the following code.

```
function MODULE_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id== 'webform_submission_add_form') {
    $form['actions']['submit']['#submit'][] = 'MODULE_custom_submit_handler';
  }
}

function MODULE_custom_submit_handler(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $webform_submission_id = $form_state->getFormObject()->getEntity()->id();
 }

```

# Answer
> 1 votes
Add a webform handler to the webform configuration and use the method submitForm() of the handler, which provides the submission entity as argument:

*mymodule/src/Plugin/WebformHandler/MyWebformHandler.php:*

```
<?php

namespace Drupal\mymodule\Plugin\WebformHandler;

use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformSubmissionInterface;

/**
 * My webform submission handler.
 *
 * @WebformHandler(
 *   id = "my_webform_handler",
 *   label = @Translation("My Webform Handler"),
 *   category = @Translation("Example"),
 *   description = @Translation("Example of a webform handler."),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 *   submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_OPTIONAL,
 * )
 */
class MyWebformHandler extends WebformHandlerBase {

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    $submission_id = $webform_submission->id();
    // my submit logic
  }

}

```

---
Tags: 8, webforms
---


# Question
Title: How can I save an unpublished node skipping required fields validation?
What is the best way to save node without the required field values?

It would be something like "save as unpublished" and the required validation is omitted, but I am not sure in which module I can find this functionality and how to set it up.

# Answer
I finally solved this using the Require on Publish module. It offers an additional checkbox to require only when publishing the node.

> This module allows fields to be required only when the piece of content is being published or is already published. This can be used when you have fields such as tags or SEO information on your piece of content that editors really don't need to fill in until the content is going live.
> 4 votes

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


title: How can I get the page title?

text:
# Question
Title: How can I get the page title?
`drupal_get_title()` has been removed from Drupal 8. How I can get the page title in Drupal 8?

# Answer
> 25 votes
If you check the change records you should find the following: drupal\_set\_title() and drupal\_get\_title() were removed.

You'll have to read the change notice for all of the info, but here is a starting point:

> **drupal\_get\_title()**
>
> As titles on routes now can be set on various ways (see above), drupal\_get\_title() has been removed. In its place you should call the title\_resolver service.
>
> Drupal 7
>
> ```
> <?php
>   $title = drupal_get_title();
> ?>
>
> ```
>
> Drupal 8
>
> ```
> <?php
>   $request = \Drupal::request();
>   if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
>     $title = \Drupal::service('title_resolver')->getTitle($request, $route);
>   }
> ?>
>
> ```

# Answer
> 12 votes
As per `batch_test.module` (D8.4) the following should work just fine:

> ```
> $request = \Drupal::request();
> $route_match = \Drupal::routeMatch();
> $title = \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
>
> ```

For more info see `public function TitleResolver::getTitle`.

# Answer
> 3 votes
### Note

The accepted response for this question is out of date: See Request parameters, route name, and route object should be accessed via RouteMatch.

You should use the *current\_route\_match* service to retrieve the current route, and then read or modify its parameters. This wraps any Symfony etc. magic.

In procedural code, you would use code similar to the following one.

```
$route = \Drupal::routeMatch()->getCurrentRouteMatch()->getRouteObject();
$title = $route->getDefault('_title');

```

In object-oriented code, you should use dependency injection and inject the service.

# Answer
> -3 votes
Drupal 8

```
$request = \Drupal::request();
  // Assuming the Request is $request.
  if ($request->attributes->has('_title')) {
    return $request->attributes->get('_title');
  }

```

# Answer
> -3 votes
In drupal 8 you can use $node-\>getTitle().

---
Tags: 8
---


title: Submitting new alter field

text:
# Question
Title: Submitting new alter field
I created a select/dropdown list and it works:

```
function hook_form_hook_ID_alter(&$form){
  $term_data = array(....) //array of key => values

  $form['elements']['location']['medical_name'] = array(
    '#type' => 'select',
    '#title' => t('Medical Area'),
    '#options' => $term_data,
    '#empty_option' => t('-None-'),
  );
}

```

but when I submit the webform, the field is not submitted. What I mean by submitted, when I go to results of the webform, there does not exist a `medical_name` field, thus the field is not registered. This is an alter function, so yes I am creating `medical_name` field on alter. I checked the `formState->getValue` and it is there. So I am wondering what may be the problem? I want to add the field programmatically.

# Answer
This is not the solution I want, it is temporary:

In the UI, I created a select field with key `medical_area` then with my alter function, it just override the webform and stored it there.

What I want: Without having to create a select field in the UI, to be able to create a field through the alter function.
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: Pretty-printing JSON as preformatted text in translatable string passed as argument to method?
**LENGTHY PREAMBLE:**

In a Service class, I'd like to display onscreen debug info for users with a specific permission.

In `my_custom_module.permissions.yml`:

```
'view debug info':
  title: 'View debug info'
  description: 'Allow user to view DataPartner API debugging messages.'
  restrict access: true

```

In `src/Api/DataPartner.php`:

```
<?php

namespace Drupal\my_custom_module\Api;

/**
 * @file
 * Contains \Drupal\my_custom_module\Api\DataPartner.
 */

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Provides API integration methods.
 */
class DataPartner {

  use StringTranslationTrait;

  /**
   * Private function to determine whether displaying debug info is permitted.
   *
   * @return bool
   *   TRUE if debugging is permitted for current user in current environment.
   */
  private function hasDebugPermission() {
    return MY_CUSTOM_MODULE_DEBUG_FLAG && $this->account->hasPermission('view debug info');
  }

```

There's a bit more to it.

I have left out the dependency injection stuff in `*.services.yml` and in the Service class, which I'm using to provide methods to deal with checking user account permission, writing Drupal messages to the screen, and other stuff. (I included just enough to show what services I'm injecting, and to show that I'm using the `StringTranslationTrait` in the Service class rather than injecting that dependency, in case that is relevant to my question.)

I have also defined the constant `MY_CUSTOM_MODULE_DEBUG_FLAG` to disable the debugging in the production environment and toggle it based on a checkbox in a ConfigForm, but that won't have any effect on my actual question.

Anyway, now I can display the API debugging messages like this:

```
if ($this->hasDebugPermission()) {
  $this->messenger->addMessage($this->t('Step 2: $response = <br><pre>@value</pre>', [
    '@value' => print_r(json_encode($this->response_decode, JSON_PRETTY_PRINT), TRUE),
  ]));
}

```

This is fine, as far as it goes, but I wanted better encapsulation. I tried this:

```
  /**
   * Private function to display debug info if permitted.
   *
   * @param string $message
   *   Translatable message string to be displayed, if permitted.
   * @param array $variables
   *   Values for substitution in translatable string.
   */
  private function displayDebugInfo(string $message, array $variables = []) {
    if ($this->account->hasPermission('view debug info')) {
      $this->messenger->addMessage($this->t($message, $variables));
    }
  }

```

However, this violates Drupal coding standards because:

> **WARNING** | Only string literals should be passed to `t()` where possible

There's an interesting discussion of this here.

The linked issue queue mentions that you can mark the string for translation *before* passing it as an argument to your method, so I tried that:

```
  /**
   * Private function to display debug info if permitted.
   *
   * @param string $message
   *   Translatable message string to be displayed, if permitted.
   */
  private function displayDebugInfo(string $message, array $variables = []) {
    if ($this->account->hasPermission('view debug info')) {
      $this->messenger->addMessage($message));
    }
  }

```

If I do that, I need to display the API debugging messages like this:

```
this->displayDebugInfo($this->t('Step 2: $response = <br><pre>@value</pre>', [
  '@value' => print_r(json_encode($this->response_decode, JSON_PRETTY_PRINT), TRUE),
]));

```

This lengthy preamble brings me to my question.

**ACTUAL QUESTION:**

Passing the translatable string to the method in this way causes the HTML markup to be printed to the screen, so that instead of seeing pretty-printed JSON as preformatted text, the user sees a brick of ugly text and markup.

When I examine the markup in the DOM inspector of the browser's Dev Tools, it looks like regular markup, not escaped HTML entities like `<pre>`.

* Why is the markup not being interpreted by the browser? (I'm assuming there is a security reason.)
* If I want to have my cake (preformatted pretty-printed JSON in `$this->messenger->addMessage()`) and eat it too (with better object-oriented encapsulation), is there any way for me to get what I want?

# Answer
> 2 votes
The simplest method is to use the Markup class directly. This should please coder/phpcs. Core also does this.

```
<?php

namespace Drupal\my_custom_module\Api;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Provides API integration methods.
 */
class DataPartner {

  use StringTranslationTrait;

  /**
   * Private function to determine whether displaying debug info is permitted.
   *
   * @return bool
   *   TRUE if debugging is permitted for current user in current environment.
   */
  private function hasDebugPermission() {
    return MY_CUSTOM_MODULE_DEBUG_FLAG && $this->account->hasPermission('view debug info');
  }

  /**
   * Private function to display debug info if permitted.
   *
   * @param string $message
   *   Translatable message string to be displayed, if permitted.
   */
  private function displayDebugInfo(string $message, array $variables = []) {
    if ($this->account->hasPermission('view debug info')) {
      $this->messenger->addMessage(Markup::create($message)));
    }
  }

}

```

`@file` isn't required for namespaced classes.

---
Tags: 8, i18n-l10n
---


# Question
Title: How to let users allow other users to view specific node content?
I'm using Drupal 9

I would like users to be able to allow other users to view their node content. Ideally a user will request access to view the content and the content owner will grant them view access. How would I go about that?

I've looked at Nodeaccess, but it doesn't seem ready for Drupal 9 yet. Node access user reference has nothing close for Drupal 9

# Answer
You can do it using a small custom module.

1. Make a allowed users/node list (database table oe entity)
2. Implement hook\_entity\_access()
3. return AccessResult::allowed() or AccessResult::forbidden() according to your user/node table
> 3 votes

# Answer
If I understand your question well, you could maybe use also the Group module. It permits you to create groups of entities, that can be visible only by the user roles that has access to a certain group. Also, the roles in groups can be different from the Drupal Roles. So, for each group you can create a moderator role, that can decide the visible content for each one of the other roles of the group.

Regards
> 0 votes

---
Tags: nodes
---


# Question
Title: How do I add a template suggestion for a Views block?
I am very much so new to Drupal and have moved to this platform after working with Magento for 5 years. I am trying to create a template for a view. I have created the twig template under **/templates/views/** called **views-view--partners--partners--sales.html.twig** but do not know how to hook the theme into using this twig template.

# Answer
> 0 votes
You need to name your template based on the rules for Views templates.

For example, "views-view--partners--partners--sales.html.twig" would mean:

* viewid: partners
* view-display-id: partners
* fieldid: sales

If this is correct, then all you need to do is clear the cache and reload; the template should be picked up automatically.

# Answer
> -1 votes
Inside `sites/default/services.yml` add config like this:

```
parameters:
  twig.config:
    debug: true

```

(and clear the cache) and it will turn on twig debug mode, which will give you information (inside html comments in page source) on what templates are used and possible template name suggestions to override those templates.

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


# Question
Title: Views exposed filters do not display in front end
I created a view block. I can see the view block on my page (node/30) no problem. Edited the view by adding filter criteria. I also changed "use Ajax to Yes". I can see the exposed filter in views edit page but I dont see the views at all on my actual page when I add the filter criteria. After I remove the filter criteria, I see the views again on my page. When i added the filter criteria, I also checked "exposed to user option.." I am not sure what I did wrong.

Please help.

D

# Answer
> 2 votes
Mb it's because there is no result. In that way you will see exposed form on edit page, but view will not be displayed on front because it's empty (so, there is no need to display exposed form for user and it's hidden).

Try to go on your view's edit page to No results behavior and make it display some text to see if view has no result

# Answer
> 1 votes
Please check if the 'Exposed form in Block' option under 'Exposed Form' section within the 'Advanced' accordion on the right, is set to 'Yes'.

If so, then your exposed filters will be under 'Disabled' in Structure \> Blocks.

You will have to move that exposed form to the specified region.

Also check if the user who visits node/30 also has access to use the filter criteria used in the block view (That is, if you have any field permissions set).

Hope this helps.

# Answer
> 1 votes
Exposed filters require "Use Ajax" to be set to true for block displays which can also cause this issue. See this issue.

# Answer
> 0 votes
Get to the Exposed filter form section of the ADVANCED box to set Exposed form in block: to "Yes" and doing so will make the filter be displayed in the views page (if you had that in your setting).

In D8, this setting will make the form avialble in the block but not on the page. On D7 the filter will show up in both page and block but in both instance the user must have permission to use search else it will not show up at all. If after all these are done and still not showing up you need to clear cache and/or rebuild permissions!

And if the search is related to searching user information the logged in user must the "View user information" permission to see/use the search exposed filter.

---
Tags: views
---


# Question
Title: Displaying products per store in a marketplace
Don't know if I am skipping an obvious available feature but I am not seeing it.

I am building a marketplace, I have been struggling to display products of particular stores, visiting stores doesn't show the products of the store so I have been trying to make a view of the products belonging to a store. I want on the store page, products belonging to the store will be listed under the store profile. I am using `commerce_marketplace`. I have not been able to get the right contextual filters to display the products of a store on the store profile. What I am building is a showcase of stores, you click a store and find products of the store.

For store owners and admins, `commerce_marketplace` does a great job: on store profiles, there is a 'Product's tab. But for anonymous users and customers, no 'Products per Store' displays.

Is it me missing an obvious way to do this?

# Answer
After 3 days of trying all kinds of Views setting, I finally found a solution to this issue, https://www.drupal.org/project/commerce/issues/3153177
> 0 votes

---
Tags: commerce
---


# Question
Title: What is the syntax for using a contrib module's service from within a hook implementation?
I'm trying to get a list of objects from AWS using the S3fsService from the S3 File System module from within a `hook_cron()` implementation. The following code works:

```
// Fetch list of files in S3.
$config = \Drupal::config('s3fs.settings')->get();
$s3 = \Drupal\s3fs\S3fsService::getAmazonS3Client($config);
$iterator_args = ['Bucket' => $config['bucket']];
$iterator = $s3->getIterator('ListObjectVersions', $iterator_args);

```

…but I'm getting a message saying `Deprecated function: Non-static method Drupal\s3fs\S3fsService::getAmazonS3Client() should not be called statically…`.

How should I be calling it differently?

Thanks!

# Answer
You can access services via `\Drupal::service('service.name')`.

You need to know the service's name to access it, though. Looking at the s3fs module, I can see in the module's *s3fs.services.yml* file that the class your requesting is available with the service name *s3fs*.

```
$s3fs = \Drupal::service('s3fs');
$result = $s3fs->getAmazonS3Client($config);

```
> 2 votes

---
Tags: 8, symfony-services
---


# Question
Title: How can I transition an order from fulfillment to completed?
I'm running Commerce Marketplace and provide store owners a back-end portal for managing their store.

In their portal, they can view orders sitting in the "fulfillment" state with the shipping address. Once they fulfill that order, I need to provide a button for them to move that order to the "completed" state.

How do I move an order to the "completed" state? Do I send the user to a specific checkout route, or can I move the order itself to completed via the API?

Currently, the only way to move the order to "completed" is manually in the order under the Commerce administration.

# Answer
> can I move the order itself to completed via the API?

Create button and create a new route. In that route's class you can do something like this. Example if order number is 1:

```
  $entity_manager = \Drupal::entityTypeManager();
  $entity_storage = $entity_manager->getStorage('commerce_order');
  $order = $entity_storage->load(1); // load order 1
  $current_state = $order->getState()->value;
  if ($current_state == 'fulfillment') {
    $order->set('state', 'completed');
    $order->save();
  }

```

OR alternatively if they need to be able to do this for several orders at the same time. (Checkmark several, and apply to selected items). Instead of a button & route, create a custom View Bulk Operation action and use same code as above, Ex:
> 2 votes

# Answer
Perhaps one way to do this would be similar to what you can find in `modules/contrib/commerce/modules/order/templates/commerce-order--admin.html.twig`

```
{# If the order has possible transitions, render the field for transition buttons. #}
{% if order_entity.getState.getTransitions is not empty %}
<div class="entity-meta__header">
  {{ order.state }}
</div>
{% endif %}

```

If the order is configured to pass from state **fullfilled** to **completed** the appropriate button for moving state should be available there. Make sure your **order\_entity** is passed to the twig template.

Read more about order workflow states
> 1 votes

---
Tags: 8, commerce
---


# Question
Title: Display webform results data in a Google Chart
I'm trying to display webform results as Google Charts. I'm doing this on the theme layer by overriding theme\_webform\_results\_analysis() on my theme's template.php file and using the Chart module. Drupal 6.22, Webform 6.x-3.11.

The webform analysis page normally shows the data in a table, so I'm trying to hack apart the arrays for that table to pass stuff into the Chart API.

**EDIT**: I figured out how to use var\_dump and found that the better approach might be to get up in the $row\_data and $questions arrays separately (instead of using the $rows array that I had in the first version of this question, which was a mashup of both arrays).

**EDIT #2**: I think I've discovered how to grab each piece of the original $questions and $row\_data arrays (see below - the foreach in the other foreach). So now I need to get those pieces into proper arrays (1 per question) and find a way to iterate through all of those.

Here's what I've got in template.php:

```
/**
 * Output the content of the Analysis page.
 * @see webform_results_analysis()
 */
function mytheme_webform_results_analysis($node, $data, $sids = array(), $analysis_component = NULL) {

  foreach ($data as $cid => $row_data) {

    if (is_array($row_data)) {

      // get the questions, put them in an array
      $questions = array();
      $questions[] = array('data' => check_plain($node->webform['components'][$cid]['name']));

      // this will print everything out in the right order - it really needs to
      // make an array for each question that looks like $test_chart below
      foreach ($questions as $question) {
        print $question['data'] . '<br />'; // questions
        foreach ($row_data as $key => $value) {
          print $value[0] . '<br />'; // labels
          print $value[1] . '<br />'; // results
        }
      }

      // Set up the chart
      $chart = array(
        '#chart_id' => 'webform_analysis',
        '#type' => CHART_TYPE_PIE_3D,
        '#size' => chart_size(658, 250)
      );

      // not real data here, this just shows the format I'm shooting for
      $test_chart = array(
        'option 1' => '12',
        'option 2' => '45',
        'option 3' => '122'
      );

      // separate the above array into labels and values, add a percentage to the label
      foreach ($test_chart as $key => $value) {
        $chart['#data'][] = $test_chart[$key];
        $chart['#labels'][] = strip_tags($key) . ' (' . round($test_chart[$key], 2) .  '%)';
      }
      // pick some colors
      $chart['#data_colors'][] = 'b0c73d';
      $chart['#data_colors'][] = '667323';
      $chart['#data_colors'][] = '221f1f';

      $output = chart_render($chart);
    }
  }

  if (count($row_data) == 0) {
    $output = t('There are no submissions for this form.');
  }

  // return the data that goes into chart function, just for testing
  // return $chart_data;

  // someday, this might return a set of webform charts. right now it returns the fake test chart
  // return $output;
}

```

# Answer
> 2 votes
There is another Drupal charts module that provides support for webforms: http://drupal.org/project/fusioncharts

Fusionchart has a little sub-module called fusioncharts\_webform

# Answer
> 1 votes
More then 3 years later now, I know, but things have evolved a bit since then ...

By only considering the title of this question, one might want to address this via the Charts module these days (though the original question started from Chart, which is another module). And this in combination with either Webform Chart or Webform Charts.

Depending on what your actual needs are today, it appears that with these 2 Webform related modules, quite a lot can be achieved by site building activities (probably no more need for Drupal developers skills). Refer to bullet 5 in Modules facilitating charting via the Charts module for some more details about these Webform Chart(s) modules (and link to an interesting discussion).

Use the Comparison of charting modules for potential other alternatives these days (and be ready to really get confused about the dozens of charting modules available ...).

Be aware: I'm a new (co-) maintainer of Chart and Charts, and the author of the Comparison of charting modules. I'm trying to continue Quicksketch's (amazing) contributions to Charts, who is also the maintainer of Webform, and Webform ChartS (with an 's').

PS: Sorry for all those confusing \*chart(s) namespaces, I did not invent them ...

# Answer
> 1 votes
Charts now integrates with webform views (views cumulative field is also quite usable too).

See also charts ecosystem for even more possibilites.

---
Tags: theming, 6, webforms, charts
---


# Question
Title: Getting user agent for error report form in drupal
I have created a website error form in drupal8 and want to grab the user agent when they submit the form. As the user click the submit button the user agent should also be saved to the database along with data of all the fields.

# Answer
> 1 votes
You can do it like this:

1. Add a field to the form to store the user agent.
2. Set permissions for the user agent field to be hidden. You can do this in `hook_form_alter` or use something like the Field Permissions module.
3. In `hook_entity_presave`, save the user agent to the field:

`$user->set('field_text_log_useragent', $_SERVER['HTTP_USER_AGENT']);`

---
Tags: forms
---


# Question
Title: Decoupled Drupal - Security: files structure
I am running a Drupal 8.9.2 site as a content repository accessed via an Angular 8 app. So there is one administrator who uses the Drupal interface to write content / upload files eccc.... and anonymous users view that content via the Angular app.

I have set up some views with REST Export display and have been able to pull the content in my Angular app running both backend and frontend on localhost, but when I deployed to the server problems have arisen...

all my calls fail or get canceled, this was the configuration on localhost: the Drupal website was in a folder in XAMPP/htdocs/example the views rest endpoints were like: http://localhost/example/web/api/content the Angular app was in a folder on the desktop and was served at http://localhost:4200/home now I put all the files for both backend and frontend on the root folder on the server, I also have commented this line ErrorDocument 404 /index.php in the htaccess file found in the web folder so that non existent urls are managed by the Angular app.

So the question is: What is the correct files structure in order to have the frontend at example.com/home and my Drupal site at example.com/web/admin/eccc..... (if it is possible, otherwise please suggest a better option).

# Answer
> 0 votes
I solved my problem, the calls were failing due to a wrong version of PHP (you need 7.2 or higher). As for the files structure I just put all the files in the root folder, both for Drupal and Angular, it works having my Drupal site in the web folder, I don't know for other configurations.

---
Tags: deployment, http-request
---


# Question
Title: The geographic data (latitude, longitude) isn't saved in content
I have installed the Geofield module, created a new content type, and added a *geofield* field.

When I start to add nodes with latitude and longitude, those values aren't saved. Editing again the same node doesn't show any value for latitude and longitude.

What I'm trying to do is to install the Leaflet module, so I need to save the values first with the Geofield module.

>

# Answer
Geofield module doesn't work without the GeoPHP library. You need to download both the module and the library and place them in the correct locations in order for the module to work.

When using Composer to install Drupal and modules the library is automatically downloaded to the correct place.

If you're not using Composer you can do that process manually. You probably already downloaded and installed the module Geofield in the common location `/web/modules/contrib`.

Now you have to download the GeoPHP library, you probably want the latest stable version, from the page noted on the Geofield documentation: https://github.com/phayes/geoPHP

The library is compressed, so you need to extract the archive file to get the folder with the library files. Then place that folder in your Drupal installation, usually in `/vendor` folder that is within Drupal root folder, so you end up with something like `/vendor/geophp/` (I haven't checked the exact path and name).

Check the Status Report that the library is available and read properly by Drupal. Sometimes you need to adjust the library file permissions or ownership so Drupal can use it but I don't expect problems in cPanel.

Not using a Composer makes maintaining your site more difficult. You'll have to do updates manually and check for all dependencies yourself.

If you can invest a bit of time and use your computer for development you should install Composer and use it to build your Drupal site. Then just upload the resulting files to cPanel to host your site, but always keep a local copy with Composer to do the updates and maintenance.
> 1 votes

---
Tags: 8, location
---


# Question
Title: Block visibility role section is missing
I am doing development in drupal 8. All of a sudden, I see that block visibility role section is missing.

How can I bring the block visibility role section back?

# Answer
There is a bug in Rules 8.x-3.0-alpha6 that hides the core block visibility conditions. Please upgrade to Rules 8.x-3.x-dev. See https://www.drupal.org/project/rules/issues/3160347
> 2 votes

---
Tags: 8, blocks
---


# Question
Title: Migration yaml - A colon cannot be used in an unquoted mapping value
I think I might be losing myself here. I am getting an invalid YAML error on a very simple migration file that really should be working fine. Would someone mind taking a look and letting me know if they can see something obvious that I am missing? Error code is:

```
A colon cannot be used in an unquoted mapping value at line 14 (near "  method: row").

```

YAML file is:

```
id: data
label: 'Data'
source:
  plugin: data
  key: migrate
process:
  name: data
    -
      plugin: existing_term
      vocabulary: data_source
      source: data
    -
      plugin: skip_on_empty
      method: row
destination:
  plugin: 'entity:taxonomy_term'
  default_bundle: data_source

```

Migration runs without error if I remove process plugins underneath name. Same error occurs if I get rid of the second process plugin (so with no piping). Basically, if I add anything that is indented more than 1 level, this error throws. I am sure that indention is '2 spaces', and this structure has worked in the past. This is on a vanilla drupal 9 install done with composer.

# Answer
I don't know about the details of the YAML content, but just looking at the YAML it seems to me that `name: data` should be just `name:` otherwise it is not valid YAML.
> 2 votes

---
Tags: migrations
---


# Question
Title: How to bring the REMOTE ID of a commerce payment into the checkout completion page?
We're running on Drupal 7.72 and using Commerce and Commerce Webform to take payments on the website.

We would like to display the REMOTE ID (seen below) on the checkout completion page. We are not able to find any tokens for this purpose readily available in the replacement patterns.

How would we go about trying to achieve this?

Apologies - I'm pretty new to using this module.

# Answer
> 2 votes
Unfortunately, because each order may have any number of payment transactions (meaning there is no strict 1:1 relationship), we cannot provide a simple token to make this available. You could create a custom Order token for the logic you know works on your site (e.g. \[commerce-order:payment-id\] that prints the remote ID of the first successful payment associated with the order). Otherwise you could customize the checkout completion page through a custom checkout pane, message text, etc.

---
Tags: commerce, webforms
---


# Question
Title: Change site logo for different languages
I do believe that should be popular issue but I can't find any questions here about this: is there any way to make site's logo different for different languages? I've found some threads regarding this thing in drupal.org forums, but these solutions are not working for me...

p.s. I am using D7 and currently working on Fusion subtheme Acquia Marina (if it helps)

# Answer
The Internationalization module, after installing and enabling the modules, you can activate it at admin/config/regional/i18n/variable, look for 'theme settings'
> 6 votes

# Answer
For non-coders: You switch to the language in the admin section, per:

https://www.drupal.org/node/313272#comment-1091779
> 0 votes

---
Tags: i18n-l10n
---


# Question
Title: How can I refresh the adjustment tax after changing the line-item price?
I create orders programmatically, and I have a tax problem: the order, after changing the line item price, always has the tax cost with the old product price. How can I refresh the adjustment tax after changing the line-item price?

```
foreach ($entity_ids as $entity_id) {
    $abo = Node::load($entity_id);

    //utilisateur
    $user = $abo->get('field_utilisateur')->getValue()[0]['target_id'];
    $utilisateur = \Drupal\user\Entity\User::load($user);

    //profile
    $entity_manager = \Drupal::entityTypeManager();
    $profile = $entity_manager->getStorage('profile')->load($user);

    //abonnement
    $nid= $abo->id();

    //livraison
    $date_livraison = new DateTime();
    $date_livraison->modify('next friday');

    //ligne de commande
    $line_items = array();
    $abo_array= $abo->get('field_abo_produits')->getValue();

    foreach ($abo_array as $abo_item) {
        $ligne = $abo_item['target_id'];
        //load produit abonnement
        $item = \Drupal\commerce_order\Entity\OrderItem::load($ligne);
        $quantite = $item->getQuantity();
        $produit = $item->getPurchasedEntity();

        $order_item = \Drupal\commerce_order\Entity\OrderItem::create([
            'type' => 'default',
            'purchased_entity' => $produit,
            'quantity' => $quantite,
            //'unit_price' => $role_price,
        ]);

        $order_item->save();
        array_push($line_items,$order_item);
    }

    //creation de la commande
    $order = \Drupal\commerce_order\Entity\Order::create([
        'type' => 'default',
        'store_id' => 1,
        'checkout_flow' => 'boulangerie',
        'uid' => $user,
        'billing_profile' =>$profile,
        'field_abonnement' => $nid,
        'placed' => time(),
        'field_date_livraison' =>$date_livraison->format('Y-m-d'),
        'order_items' =>$line_items
    ]);

    $order->save();
    $order->set('order_number', $order->id());
    $order->save();
    $order->set('state', 'complete');
    $order->save();

    //prix custo
    foreach ($order->getItems() as $ligne_de_commande) {

        $produit = $ligne_de_commande->getPurchasedEntity();
        //prix
        if ($utilisateur->hasRole('biocoop')) {
            $role_price = $produit->get('field_prix_biocoop');
            $role = 'biocoop';
        }

        if ($utilisateur->hasRole('montagne')) {
            $role_price = $produit->get('field_prix_montagne');
            $role = 'montagne';
        }

        if ($utilisateur->hasRole('vente_directe')) {
            $role_price = $produit->get('field_prix_vd');
            $role = 'vente_directe';
        }

        $unit_price = new  \Drupal\commerce_price\Price($role_price->number, 'EUR');

        $ligne_de_commande->setUnitPrice($unit_price);
        $ligne_de_commande->save();

    }

    $order->save();
}

```

# Answer
> 1 votes
As mentioned by @d70rr3s, the OrderRefresh service is used. You can can inject the service interface into your own service or controller or use it directly in procedural code.

The service itself is `commerce_order.order_refresh`.

See:

* Drupal\commerce\_order\OrderRefreshInterface
* Drupal\commerce\_order\OrderRefresh

Example:

```
$orderRefresh = \Drupal::service('commerce_order.order_refresh');
$orderRefresh->refresh($order);

```

# Answer
> 0 votes
Order refresh is done via a service, this service is called every time an order is saved. Check the module documentation.

---
Tags: commerce
---


# Question
Title: how to add class to {% block content %} in twig
Here goes my drupal 8 code, so basically `block.html.twig` is extended to `block--mytheme-sitebranding.html.twig`.

Now I want to add a class to this:

```
{% block content %}

  {% if site_logo %}

    <a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">
      <img src="{{ site_logo }}" alt="{{ 'Home'|t }}" />
    </a>

  {% endif %}
  {% if site_name %}

    <a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">{{ site_name }}</a>

  {% endif %}
  {{ site_slogan }}

 {% endblock %}

```

How can I add a class to `{% block content %}` in Twig for `block--mytheme-sitebranding.html.twig`?

# Answer
> 1 votes
Take a look at block\_class module can help you.

# Answer
> 0 votes
In your block.html.twig file ensure you have a containing div, and that "attributes" are being printed. This will give your block an ID of the block name, and typically the class "contextual-region".

If you need a class specific to this block, you can add the block ID as a class like so:

block.html.twig:

```
{%
    set extraBlockClasses = attributes.id | clean_class
%}

<div {{ attributes.addClass(extraBlockClasses) }}>
    {% block content %}
        {{ content }}
    {% endblock %}
</div>

```

block--override.html.twig:

```
{% extends 'block.html.twig' %}

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

```

Unfortunately, "{% block content %}" is not a "thing" to which you may add a class. Use descendent CSS selectors from your block class.

# Answer
> 0 votes
You can't add a class to `{% block content %}` – but you can add a class to the wrapping element.

Instead of the line `{% extends 'block.html.twig' %}` you can delete all the content of your template `block--mytheme-sitebranding.html.twig` and replace it with the content of the original template `block.html.twig`.

Then alter the elements inside of `{% block content %}` as you like – for example:

```
{%
  set classes = [
    'MY-NEW-CLASS',
  ]
%}
<div{{attributes.addClass(classes)}}>
  {{ title_prefix }}
  {{ title_suffix }}

  {% block content %}

  {% if site_logo %}

    <a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">
      <img src="{{ site_logo }}" alt="{{ 'Home'|t }}"/>
    </a>

  {% endif %}
  {% if site_name %}

  <a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">{{ site_name }}</a>

  {% endif %}
  {{ site_slogan }}

  {% endblock %}
</div>

```

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


# Question
Title: Are page caching and cache tags related?
I'm working with a site which has page cache enabled.

I'd like the page cache for any given node to invalidate when that node is changed. There's a lot of examples out there dealing with cache tags, but I haven't had any luck figuring out the relationship between page caching and cache tags.

I've got a node which starts out being published. I then unpublish it, and publish it again. When I publish it for the second time, the page cache still treats it as unpublished. It does so until i clear the entire (page) cache.

It seems that the `cache_page` entry is updated when i update a published node, but whenever the node goes from unpublished to published - the page cache entry doesn't follow.

I've tried implementing `hook_entity_update` and do a `Cache::invalidateTags(['node:19']);`, but that had no impact.

Is it possible to use cache tags to invalidate page cache entries?

# Answer
Page cache is just the cached values.

Cache tags are tags that are attached to a cached value (simplifying a little bit). This tells Drupal what cached values are related to what cache tags. When a cache tag is invalidated, all cached values that have the invalidated cache tag are invalidated as well. You can find more info on the Drupal documentation page about Cache Tags. The headline is:

> Cache tags provide a declarative way to track which cache items depend on some data managed by Drupal.

So, answering your question, yes, they are totally related and you can (and you should) invalidate page cache entries using cache tags. Because, as stated above, cache tags track content and cache dependencies and thus you can invalidate cached item when content (or the source data of a cached item) changes.

However, this can be tricky. For example, page cache entry of a node view page is always associated with the cache tag `node:[nid]`. When the node is updated, that cache tag is invalidated, thus making the page cache of that node's view page invalidated as well. Views that shows a list of nodes are not associated with each node's cache tag. Blocks are other display elements may not be related to that kind of tags. So you need to know which cache tag you want to invalidate.

The good news is Drupal takes care of the most common cases, so you don't have to care. Usually, you only need to deal with the cache tags when you are developing custom code.

In your case, you may be hitting another cache (browser cache? reverse proxy cache?).
> 1 votes

---
Tags: 8, caching
---


# Question
Title: How the handle an override of the schema of a field type
To add other data to a `state` field, I overrode 2 functions of the StateItem class (from the state\_item module)

```
    public static function schema(FieldStorageDefinitionInterface $field_definition) {
        $schema=StateItem::schema($field_definition);
        $schema['columns']['json']=[
            'type' => 'json',
            'pgsql_type' => 'json',
            'mysql_type' => 'json',
            'not null' => FALSE,
            'description' => "Store data about states in json format",
        ];
        return $schema;
     }
    public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
        $properties=parent::propertyDefinitions($field_definition);
        $properties['json']=DataDefinition::create('string')
        ->setLabel(t('Data'));
        return $properties;
    }

```

As I have already several fields of this type in my website, I got the following errors in the `Status report` page:

```
Entity/field definitions  Mismatched entity and/or field definitions
                          The following changes were detected in the entity type and field definitions.

```

...followed by the fields that must be updated.

Knowing the fact that I am the only user of this custom field, what is the best approach to handle this kind of change?

**Here is the solution**

As explained by @sanzante, I created an UpdateN function which is updating all the fields of the `state` type by adding an appropriate column to the table of each field:

```
function mymodule_update_8001() {
  $spec = [
    'type' => 'json',
    'pgsql_type' => 'json',
    'mysql_type' => 'json',
    'not null' => FALSE,
    'description' => "Store data about states in json format",
  ];
  $schema = Database::getConnection()->schema();
  $state_fields = \Drupal::service('entity_field.manager')
    ->getFieldMapByFieldType('state');
  foreach ($state_fields as $entity_type_id => $fields) {
    foreach (array_keys($fields) as $field_name) {
      $table = $entity_type_id . '__' . $field_name;
      $table_rev = $entity_type_id.'_revision' . '__' . $field_name;
      $new_field_name = $field_name . '_json';
      $schema->addField($table, $new_field_name, $spec);
      $schema->addField($table_rev, $new_field_name, $spec);
    }
  }

}

```

The key points are :

1-how the table names are constructed. (see `$table` and `$table_rev` in the code)

2-how the new field names are constructed. (see `$new_field_name` in the code an the fact that you must use the same column name as defined in `$schema['columns']['json']`)

3-You must use the same spec as the ones defined in `function schema`

After the updated ran, I still got the `Mismatched entity and/or field definitions` error message.

I could solve this by running `drush entup` (the module `devel_entity_updates` must be installed)

# Answer
You have to write an update function that changes those fields live in your database so they match the new definition.

Time ago, this was done using the `drush entity-updates` command. However, this was dangerous in some circumstances. You can check the Support for automatic entity updates has been removed change record to get more information on this.

In this change record you can see:

> Starting with 8.7.0, Drupal core no longer provides support for automatic entity updates. Whenever an entity type or field storage definition needs to be created, changed or deleted, it has to be done with an explicit update function as provided by the Update API, and using the API provided by the entity definition update manager.

Therefore, you need an update function. Probably, you should read the "Updating Database Schema and/or Data in Drupal 8" page, specially the "Adding a new column" section:

> Here's an example of what to put into your hook\_update\_N() function to add a new column to an existing database table:
>
> ```
>   $spec = [
>     'type' => 'varchar',
>     'description' => "New Col",
>     'length' => 20,
>     'not null' => FALSE,
>   ];
>  $schema = Database::getConnection()->schema();
>  $schema->addField('mytable1', 'newcol', $spec);
>
> ```

**Devel Entity Updates module**

As pointed out by @Ales, you may try the Devel Entity Updates module:

> This command should be able to fully replace the legacy drush entup or drush entity-updates commands.

However, this module is not meant to be used in production environments, see the following disclaimer from the module:

> The goal of this module is to have a quick way to apply schema updates while developing new entity types and ending up incrementally adding/removing/changing entity type/field definitions.
>
> When these changes are part of an official release (and not in the scope of a code development session), they should absolutely rely on DB update functions, as explained in the CR above, because that's the only way the entity schema update process can be predictable and reliable.

So, this approach is ok for you if don't have a production environment yet. Of course, you can ignore the warning and install the module on prod, but keep in mind that you may lose data because the operation is not safe.

You can try it on a test environment, and if you finally take the risk and use in prod make sure you have a recent backup at hand.

**Why you need this**

The problem you have a difference between the table data definition in code and the actual data tables in your database. Why does this happen? There are different circumstances that can lead to this. In your case, the State module has some data definitions that are applied when the module is installed. At this point, code data definition and actual data tables are matching. However, if you make any changes on the code that defines the data tables the problem arises: you have one definition on code and different actual data tables in the database.

So what you need to do is modify the tables to match the data definition. That's what my answer tries to explain. The two methods are writing an update function (so you control with that function how to modify the actual tables) or trust an automatic method (the entity update command). The command is easy but it has no brain so it just modifies the tables without thinking on possible issues. That's why you may have problems (data loss, mainly) using that command.
> 6 votes

---
Tags: updating
---


# Question
Title: drush arr (drush archive-restore) says: Missing required argument: file
I have been requested, against my better advice, to try to ensure that a Drupal site for an associated part of our organisation is up to date, although the site developers left no admin maintenance documentation nor information about any custom setup that they may have done, and now seem to be uncontactable (poor project management on the part of the site owners).

The standard Drupal update did not work, and I now have to try to revert the site back from the drush archive that was taken just beforehand.

However, `drush arr` (`drush archive-restore`) says:

> Missing required argument: file.

I'm not sure what file I need to specify (our own installation of Drupal is somewhat customised and clear upgrade instructions, working in a different way, are supplied by the maintainers).

Looking in the drush-backups folder, I seem to have two choices:

```
/root/drush-backups/archive-dump/20200831154526/sitename.20200831_154526.tar.gz
/root/drush-backups/sitename/20200831154744/drupal/

```

(the latter of which seems to contain the Drupal files as-is (not as a .tar.gz file))

Is the .tar.gz file from the archive-dump folder the file that drush arr is wanting, and then drush will know how to find the rest automagically?

# Answer
`drush arr` is expecting a site archive file as an argument. Its sibling drush command,`drush ard`, creates a site archive file. (see the drush codebase for more details on how this command works) The `/root/.../drupal/` path is a backup drush creates when you run `drush up`

The `/root/drush-backups/archive-dump/` path matches the format of `drush ard`'s default output but if you didn't create this archive file you should inspect it (`tar -tvf`) to confirm it has the code/files/DB backup within it.

So yes, `drush arr` will restore from a site backup but you should take necessary precautions since you've inherited an undocumented process.
> 1 votes

---
Tags: drush
---


# Question
Title: How can I prevent cache on any page where a paragraph appears?
I am using the paragraphs module with a custom theme I created. I want to figure out how to clear the cache for any page that a specific paragraph appears on. The custom theme is composed of a bunch of templates (i.e. `paragraph--paragraph-name.html.twig`) and a \*.theme file where I preprocess each of the paragraph types.

```
THEME_preprocess_paragraph__paragraph_name

```

I don't want to disable the entire site's cache. Can I clear the cache in this file? In this way somehow?

# Answer
> 0 votes
You probably want to be really heavy handed and use \Drupal::service('page\_cache\_kill\_switch')-\>trigger();

If you put that in a custom module in hook\_entity\_view\_alter() then you can add a conditional that fires it when your paragraph entity is being built.

---
Tags: 8, caching, paragraphs
---


title: Password reset link gives access denied

text:
# Question
Title: Password reset link gives access denied
Password reset link is not working in drupal 8.6. The email with the one-time login link is sent just fine, but when the user clicks on the Login button, they get "You are not authorized to access this page" message. Even I tried to open `user/reset/{id}` with login as admin still same error. When I figuring out the issue I found one line in `user.module line no 556
\Drupal::moduleHandler()->invokeAll('user_login', [$account]);` is causing the issue. **If** I remove this line then I can reset my password successfully. whats this line is doing? Does it load all active modules in website? than there must be issue in any module. Could I remove this line? Any alter solution?

I tried by clearing cache,cookie, browser history, session table, also `$cookie_domain = $_SERVER['HTTP_HOST'];` this line is not in my settings.php

# Answer
> 0 votes
> whats this line is doing? Does it load all active modules in website?

It invokes a hook (`hook_user_login`), which other installed modules can respond to. It doesn't "load" any modules, but those other installed modules are already available at that point, yes.

> Could I remove this line?

Physically, yes, but it would be a terrible idea. It's important, or it wouldn't be there.

> Any alter solution?

You need to debug your site, preferably with a step-debugger like XDebug. Chances are you have a rogue custom or contributed module doing something it shouldn't be.

# Answer
> 1 votes
Had similar outcome but issue was purely that the User record was still set to Blocked rather than Active.

# Answer
> 0 votes
This is an issue with symfony/http-foundation v3.4.24. See https://www.drupal.org/project/drupal/issues/3045844

Source: Drupal 8 dropping session variables on password reset. Gives 403 Access Denied

---
Tags: 8, users
---


# Question
Title: What is the "contract" for EventSubscriberInterface functions?
The `EventSubscriberInterface` can be used to listen for events, and `getSubscribedEvents` is used to announce which events an implementation would like to subscribe to.

The `getSubscribedEvents` must return an array which holds the type of events an implementation would like to subscribe to, as well as the function which is to be invoked when an event triggers.

```
  public static function getSubscribedEvents() {
    return [
      KernelEvents::REQUEST => [
        ['redirectToLoginPage'],
      ]
    ];
  }

```

The documentation is very sparse on the function :

> The method name to call (priority defaults to 0)

By looking at other implementations, I see that the function may return `TRUE`, `FALSE` and even implementations of `Response`. An example implementation could thus look like this :

```
public function redirectToLoginPage(GetResponseEvent $event) {
  $random = rand(0,2);
  switch($random) {
    case 0:
      return TRUE;
    case 1:
      return FALSE;
    case 2:
     $response = new RedirectResponse('/user/login', 301);
     $event->setResponse($response);
     return TRUE;
  }
}

```

What is the "contract" for the function which subscribes to events? Specifically, what is the impact of returning `TRUE` and/or `FALSE` from this function?

# Answer
The contract is the event class itself. In case of GetResponseEvent (deprecated by the way and will be replaced by RequestEvent in future Drupal releases) you can set a response, this will stop the propagation of this event and the kernel will return the response as an answer to the request.

From where do you have the example code, I'm not sure what case 0/1 is trying to do? In the Symfony default dispatcher the return value is ignored.
> 2 votes

---
Tags: 8, event-subscribers
---


# Question
Title: Programmatically setting video_embed_field URL
I am trying to populate nodes programmatically from a feed (migrating earlier site to Drupal 9). So far I have managed to get everything else to move, but I can't figure out, how to set video\_embed\_field or rather the URL-value of the video. I found an example, but it caters just youtube, but there are also other video providers used.

I have tried the following ideas:

```
$node->set("field_video", $videourl);

$node->field_video = ['input' => $videourl];

$node->field_video = ['value' => $videourl];

```

but so far nothing works.

Could anyone hint me to the right direction?

# Answer
Actually, the last try in my choices seems to work after all.

```
 $node->field_video = ["value" => $item["video"]];

```

I must have done something dumb with my editor like not saving the changes... Well, maybe someone else finds the info here...
> 0 votes

---
Tags: 8, nodes, media
---


# Question
Title: How do I render search block programmatically?
I'd like to render the search block in a twig file.

# Answer
### There is a big gotcha with the search form.

The answer with the `themename_search` only works if the search block is enabled or disabled and **has never been removed** in */admin/structure/block*.

If in */admin/structure/block* you re-add/place it again, the search form ID changes to `formsearch`. It no longer uses the theme name! And again it only works if this block is enabled or disabled, but not when removed.

---

A solution that works when search block has been removed from */admin/structure/block* is to use **Twig Tweak** and then you can place it with

```
{{ drupal_form('Drupal\\search\\Form\\SearchBlockForm') }}

```
> 4 votes

# Answer
please try this

```
/**
 * Implements theme_preprocess_example_hook().
 */
function themename_preprocess_example_hook(&$variables) {

  // Create a variable for the block w/ ID "example_block_id".
  $block = \Drupal\block\Entity\Block::load('example_block_id');
  $variables['example_block'] = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);

}

```

in your twig file

```
{{ example_block }}

```
> 2 votes

# Answer
This is a solution.

```
/**
 * Implements hook_preprocess_page().
 *
 */
function mytheme_preprocess_page(&$variables) {
    $block = \Drupal\block\Entity\Block::load('mytheme_search'); // replace mytheme part with your theme name.
    $variables['block_search_form'] = \Drupal::entityTypeManager()
        ->getViewBuilder('block')
        ->view($block);
}

```

Access it in page.html.twig file

```
{{ block_search_form }}

```
> 1 votes

---
Tags: theming, forms, 8
---


# Question
Title: How do I render search block form in theme template?
I've customized the search block in "block--search-form-block.html.twig" and it works using block layout on Drupal 9. Is it possible to render the Search Block directly in **page.html.twig**?

I've tried this and it giving me error (The website encountered an unexpected error. Please try again later.).

# Answer
Here are the 3 methods I found.

**1 - Use `plugin.manger.block` to render `search_form_block`**

-- in `mytheme.theme`

```
function MYTHEME_preprocess_page(&$variables) {
  $customblock = \Drupal::service('plugin.manager.block')->createInstance('search_form_block', []);
  $variables['content']['custom_block_output'] = $customblock->build();
}

```

-- in `page.html.twig`

```
{{ content.custom_block_output }}

```

**2 - Same as 1 but render a customized search block from `block--search-form-block.html.twig`.**

-- in `mytheme.theme` \- Same as method 1

-- in `page.html.twig`

```
{% include '@MYTHEME/block--search-form-block.html.twig' %}

```

**3 - Use Twig Tweak \- credit to No Sssweat's Post**

1. install the Twig Tweak module
2. insert `{{ drupal_block(search_form_block') }}` on `page.html.twig`
> 2 votes

---
Tags: theming, search, 9
---


title: Migration Multisite D7 to Single D8

text:
# Question
Title: Migration Multisite D7 to Single D8
I have several D7 sites that I inherited that should have been one site. We are now trying to migrate to D8 (not all needed modules are available yet on D9). We would like to migrate them to one site.

When I migrate site 1 nodes and/or webforms/submissions, all goes well. When I migrate site 2, some of site one items are overwritten because they have the same ids. How do I configure a migration so it does not overwrite a previous migration?

# Answer
There is more than one way to migrate Drupal content. Usually if you assign a migration from a database into a different database the assumption is that it's about migrating content into a new structure, without any additional content considerations.

As mentioned in the comment you should export/import the second site content rather than migrate.

You can look into Feeds module to import from a CSV, for example, and you can use Views to create a list of your content then export it into a CSV file. This isn't the only way to go about it, just one suggestion. Try to research the export/import ways of content in Drupal ;)
> 0 votes

---
Tags: migrations
---


# Question
Title: How do I create a view with mixed languages, showing the node's original language by default?
I have a site with mixed languages, Spanish and English. Some content was originally created in English, then translated into Spanish. Other content was originally created in Spanish, then translated into English. The remaining content is either in Spanish or English and is not translated.

How do I create a view that shows all of this content in the original content (non-translated) language, showing a view with a mix of English and Spanish? Then if the user chooses English or Spanish, it will show only those languages.

# Answer
> 0 votes
To show only the "original" nodes in any language don't include any language filters so all languages are shown. This will show all your content, translated or not in both languages.

It's not clear from your question what you mean by "that shows all of this content".

If you want to show only the nodes that were originals, and not a translation of another, add the `Source translation` Filter from the `Content translation` Category. Set it to `Include untranslated content: Yes` if you want only the nodes that haven't been translated yet.

Set it to `No` if you only want to show nodes that already have a translation node.

I'm guessing you'll want the **No** selected, or you won't need the Content translation Filter filter at all.

Then add the `Content: Language` Filter and Expose it to allow visitors to filter the language. Select only the two specific language options and the `Limit list to selected items` if you only want those to be the options your visitors see and are able to choose (so they don't see options like "Site default", "Current", etc).

---
Tags: 7, views, i18n-l10n
---


# Question
Title: Access hook_preprocess_node variables from page controller
I have a custom controller created for a custom URL, where the URL is a URL for an existing node with an additional parameter. The display for the URL defined by the controller needs to use the the same template for the base node route, and the controller just uses a service to get additional data and merge it with the base node data.

To be more specific, I have a node type called `product_group`. It has an entity reference field called `field_products` that attaches `commerce_product` entities. The URL alias pattern for `product_group` nodes is `/products/[node-title]`. My controller is for the URL `/products/[node-title]/[sku]`, where `sku` is the commerce\_product sku. The controller gets the data from the URL, loads the base `product_group` node object, uses the `sku` value to get the `commerce_product` object, and then I have a custom service that gets a bunch of additional data from the product and associated variation.

The tricky part is that the display at the `/products/[node-title]/[sku]` URL is the same as the display at the `/products/[node-title]` URL, with some additional data from the product itself added in. Therefore, I need to get all of the `$variables` data that is available in `hook_preprocess_node()` function in my controller and add my new data on top of it. The problem is, I can't figure how to access it. From what I've seen, you can't access data in a preprocess hook directly from a controller, but I'm guessing there has to be some way I can render the `product_group` node and get the variables that are available in `hook_preprocess_node`. Am I correct, and if so, how do I do it?

# Answer
> 1 votes
So the problem turned out to be an incorrect `#theme` template name in my returned render array. The node type I was adding content to was called `product_group`, but in my controller, I returned this:

```
 return [
   '#theme' => 'node__product_resource__full',
   '#product_group' => $content,
   '#node' => $pg_node,
   '#view_mode' => 'full',
 ];

```

`product_resource` is a valid content type in the site. Once I changed it to

```
'#theme' => 'node__product_group__full',

```

It worked fine.

---
Tags: 8, page-controller
---


# Question
Title: Failed to update and now causes module errors
I recently attempted to update a Drupal 8 site from 8.7.7 to 8.9.3 and had a failure due to server not being on the right version of php7 to run the new 8.9 version.

As a result I am now getting issues within /admin/people view with the following errors

```
The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Drupal\Component\Plugin\Exception\PluginNotFoundException</em>: The "webform_submission_delete_action" plugin does not exist. Valid plugin IDs for Drupal\Core\Action\ActionManager are: comment_delete_action, comment_unpublish_by_keyword_action, comment_publish_action, comment_save_action, comment_unpublish_action, node_promote_action, node_delete_action, node_make_unsticky_action, node_assign_owner_action, node_unpromote_action, node_make_sticky_action, node_save_action, node_publish_action, node_unpublish_action, node_unpublish_by_keyword_action, user_remove_role_action, user_unblock_user_action, user_cancel_user_action, user_block_user_action, user_add_role_action, pathauto_update_alias, entity:delete_action:comment, entity:delete_action:media, entity:delete_action:node, entity:publish_action:block_content, entity:publish_action:comment, entity:publish_action:media, entity:publish_action:node, entity:publish_action:taxonomy_term, entity:publish_action:menu_link_content, entity:publish_action:paragraph, action_message_action, entity:unpublish_action:block_content, entity:unpublish_action:comment, entity:unpublish_action:media, entity:unpublish_action:node, entity:unpublish_action:taxonomy_term, entity:unpublish_action:menu_link_content, entity:unpublish_action:paragraph, action_send_email_action, entity:save_action:block_content, entity:save_action:comment, entity:save_action:file, entity:save_action:media, entity:save_action:node, entity:save_action:taxonomy_term, entity:save_action:user, entity:save_action:font, entity:save_action:menu_link_content, action_goto_action in <em class="placeholder">Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition()</em> (line <em class="placeholder">53</em> of <em class="placeholder">core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php</em>).

```

The webform version went from 8.5.4 to 8.5.19

Within my modules admin, currently webform is showing as uninstalled. When I try to re-enable with drush I get a similar error.

```
php ../drush.phar pm-enable webform

In PreExistingConfigException.php line 65:

  Configuration objects (system.action.webform_submission_delete_action, system.action.webform_submission_make_lock_action, system.action.webform_submission_make
  _sticky_action, system.action.webform_submission_make_unlock_action, system.action.webform_submission_make_unsticky_action, webform.settings, webform.webform.c
  ontact, webform.webform_options.country_codes, webform.webform_options.country_names, webform.webform_options.days, webform.webform_options.education, webform.
  webform_options.employment_status, webform.webform_options.ethnicity, webform.webform_options.gender, webform.webform_options.industry, webform.webform_options
  .languages, webform.webform_options.likert_agreement, webform.webform_options.likert_comparison, webform.webform_options.likert_importance, webform.webform_opt
  ions.likert_quality, webform.webform_options.likert_satisfaction, webform.webform_options.likert_ten_scale, webform.webform_options.likert_would_you, webform.w
  ebform_options.marital_status, webform.webform_options.months, webform.webform_options.phone_types, webform.webform_options.relationship, webform.webform_optio
  ns.size, webform.webform_options.state_codes, webform.webform_options.state_names, webform.webform_options.state_province_codes, webform.webform_options.state_
  province_names, webform.webform_options.time_zones, webform.webform_options.titles, webform.webform_options.yes_no) provided by webform already exist in active
   configuration

```

Has anyone encountered similar and can point me to how to get webform enabled again and to get rid of the errors?

# Answer
> 1 votes
**What seems to the problem**

It seems during the failed update Webform was marked as uninstalled but its configuration objects are still present. This is preventing Webform to be enabled again because you can't install an extension that uses configuration objects already in the system.

**How to solve it**

You can remove all the configuration objects and try to install/enable the module. To remove them, you can use the `cdel` drush command.

Given the configuration object list, the commands to run would be:

```
drush cdel system.action.webform_submission_delete_action
drush cdel system.action.webform_submission_make_lock_action
drush cdel system.action.webform_submission_make_sticky_action
drush cdel system.action.webform_submission_make_unlock_action
drush cdel system.action.webform_submission_make_unsticky_action
drush cdel webform.settings
drush cdel webform.webform.contact
drush cdel webform.webform_options.country_codes
drush cdel webform.webform_options.country_names
drush cdel webform.webform_options.days
drush cdel webform.webform_options.education
drush cdel webform.webform_options.employment_status
drush cdel webform.webform_options.ethnicity
drush cdel webform.webform_options.gender
drush cdel webform.webform_options.industry
drush cdel webform.webform_options.languages
drush cdel webform.webform_options.likert_agreement
drush cdel webform.webform_options.likert_comparison
drush cdel webform.webform_options.likert_importance
drush cdel webform.webform_options.likert_quality
drush cdel webform.webform_options.likert_satisfaction
drush cdel webform.webform_options.likert_ten_scale
drush cdel webform.webform_options.likert_would_you
drush cdel webform.webform_options.marital_status
drush cdel webform.webform_options.months
drush cdel webform.webform_options.phone_types
drush cdel webform.webform_options.relationship
drush cdel webform.webform_options.size
drush cdel webform.webform_options.state_codes
drush cdel webform.webform_options.state_names
drush cdel webform.webform_options.state_province_codes
drush cdel webform.webform_options.state_province_names
drush cdel webform.webform_options.time_zones
drush cdel webform.webform_options.titles
drush cdel webform.webform_options.yes_no

```

**Consecuences**

Removing configuration objects mean you likely are going to lose any Webform configuration you made. This can be not a problem if you can easily redo the configuration or your configuration was not finished or needed changes. I'm not sure if this includes losing all the created webforms.

However, if you dumped the configuration to files (using Drupal configuration system) you may able to recover the configuration using those files.

---
Tags: 8, webforms, updating
---


title: Make EntityQuery Block Table sortable

text:
# Question
Title: Make EntityQuery Block Table sortable
I made a custom EntityQuery Block Plugin with a table output and managed to make the headers sortable using this **$header definition**:

```
        $header = [
            'title'      => [
                'data'      => t('title'),
                'field'     => 'title',
                'specifier' => 'title',
            ],
            'mydate'       => [
                'data'      => t('mydate'),
                'field'     => 'field_date_paragraph',
                'specifier' => 'field_date_paragraph',
            ]
        ];

```

Then I added a **tablesort** when retrieving the nodes:

```
    $nids = \Drupal::entityQuery('node')
        ->condition('status', 1)
        ->condition('type', 'project')
        ->tableSort($header)
        ->condition('field_exhibition.target_id', \Drupal::routeMatch()->getRawParameter('node'))
        ->execute();

```

The output looks fine and column headers are clickable - but nothing happens. Actually the **GET parameters** get correctly added to the URL and look something like:

```
?sort=asc&order=mydate

```

I think the problem is date field (field\_date\_paragraph) which is a paragraph field. Inside the paragraph I have a date field and it is this one which should get ordered. What do I have to add to $header definition to make reference to the date field inside **field\_date\_paragraph**?

# Answer
I think you need to specify a filed name inside a paragraph in the header array, like field\_date\_paragraph.DATE\_FIELD\_NAME (This behavior is, also supported inside condition method) And here is the issue about lack of documentation https://www.drupal.org/project/drupal/issues/1924622
> 1 votes

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


# Question
Title: Installing Drupal module requires ftp access - macOS localhost
I have Drupal 8 running on localhost on macOS Catalina. When I try to install a module, I get prompted to enter ftp credentials (which I don't know). See the following screenshot.

I've seen solutions that suggest this ftp prompt is caused by a permission issue in *sites/default* folder and can be fixed with `chown www-data sites/default` or `chown apache sites/default` for linux but those commands on a mac throw *'chown: www-data: illegal user name'* or *'chown: apache: illegal user name'* error. What do I need to do to enable installing modules/themes without being prompted for ftp?

## **EDIT**

I'm specifically asking about installing modules by the url method from the admin interface.

# Answer
Depending on how you are running this locally (native, Docker, etc) this can differ, but I will assume you are using what comes with macOS to run Drupal.

The difference here is Mac does not have a www-data or apache user like Linux does. If you are running with the defaults, the user you are looking for is \_www (unless you have modified this in Apache confs).

So, you will want to do:

```
chown _www (directory)

```

Technically, this is probably better asked on ServerFault, but I can imagine there are a lot of people trialling or demoing Drupal who just use what is on Mac to do it, and will come across this post finding it helpful.
> 4 votes

---
Tags: installation
---


title: Migrating on an AWS Instance

text:
# Question
Title: Migrating on an AWS Instance
I am given the task of migrating a Drupal 7 site to Drupal 9. I have been given a "mirror" site/exact copy that is being held on an AWS instance. Because the mirror site is up and running, I am assuming a LAMP stack has been installed. Could someone briefly outline how to install D9 onto this instance and migrate content over from D7 to D9? So far I have:

-updated the LAMP stack to make sure it's fully up to date.

-Downloaded D9 through Terminal in a separate folder away from the current D7 files.

-Create a new database in MariaDB.

I am following this tutorial: https://www.drupal.org/docs/installing-drupal

Step 4 has me stuck; do I need to do this since the instanced is fully up and functioning as it's a mirror copy?

Thanks for your help in advance!

# Answer
> 0 votes
To answer your specific question on the tutorial: if your Drupal 7 site is functioning, you don't need to do step 4 anymore. PHP is functioning. You may proceed with step 5.

Indeed you will need to investigate what modules you use in the Drupal7 site and look if these have been ported to D9, or if there are interchangeable modules. Perhaps it's better to go for D8 first if you get stuck finding the appropriate modules and you're not able to make them yourself.

---
Tags: migrations
---


# Question
Title: Altering existing route for translation overview page ie: entity.node.content_translation_overview
I have followed this documentation page : https://www.drupal.org/docs/drupal-apis/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones in attempt to alter access of translation overview page ie: www.example.com/node/1/translations

```
<?php

namespace Drupal\link_enhancements\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {

    $route_name = "entity.node.content_translation_overview";
    var_dump($collection->get($route_name)); exit;
    if ($route = $collection->get($route_name)) {
      $requirements = $route->getRequirements();
      unset($requirements['_permission']);
      // if both role then only we will allow ...code will go here.....
      $route->setRequirement('_access', 'FALSE');
    }

  }

}

services:
  link_enhancements.route_subscriber:
    class: Drupal\link_enhancements\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

```

But below route output is null and similar code works for other routes but requirement to alter translation overview route which returns null.

```
$route_name = "entity.node.content_translation_overview";
    var_dump($collection->get($route_name)); exit;

```

core/modules/content\_translation/src/Routing/ContentTranslationRouteSubscriber.php

route is added in core module by below code and I have searched and tried but not sure how can we alter such routes, please suggest.

```
if ($entity_type->hasLinkTemplate('drupal:content-translation-overview')) {
        $route = new Route(
          $entity_type->getLinkTemplate('drupal:content-translation-overview'),
          [
            '_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::overview',
            'entity_type_id' => $entity_type_id,
          ],
          [
            '_entity_access' => $entity_type_id . '.view',
            '_access_content_translation_overview' => $entity_type_id,
          ],
          [
            'parameters' => [
              $entity_type_id => [
                'type' => 'entity:' . $entity_type_id,
                'load_latest_revision' => $load_latest_revision,
              ],
            ],
            '_admin_route' => $is_admin,
          ]
        );
        $route_name = "entity.$entity_type_id.content_translation_overview";
        $collection->add($route_name, $route);
      }

```

# Answer
> 1 votes
It was not working because in content\_transaltion module priority was set to -210 so make need to change priority of custom module to -220 and it started working.

```
public static function getSubscribedEvents() {
    $events = parent::getSubscribedEvents();
    $events[RoutingEvents::ALTER] = ['onAlterRoutes', -220];
    return $events;
  }

```

---
Tags: routes
---


# Question
Title: Core Update to 8.9.4 Removed Block Visibility Options?
Recently updated core from 8.9.2 to 8.9.4, in doing so the options to place blocks on specify pages is now gone?

# Answer
> 1 votes
I still see it "Drupal core 8.9.4"

---
Tags: blocks
---


# Question
Title: Send email to Commerce customer after order status is changed to Completed
I am attempting to develop a module that will send an email to a customer in my Commerce 2 store when that customer's order's status is updated to "Completed". I am basing my module off of the example shown in the handbook (https://docs.drupalcommerce.org/commerce2/developer-guide/orders/workflows/react-to-workflow-transitions)

Here's what I have so far:

File: /modules/custom/tracking\_number\_email/tracking\_number\_email.info.yml

```
name: Commerce Tracking Number Email
type: module
description: Uses an event subscriber to send an email with tracking number to customer after order status has been updated.
package: Commerce
core: 8.x

```

File: /modules/custom/tracking\_number\_email/tracking\_number\_email.services.yml

```
services:
  tracking_number_email.order_fulfillment_subscriber:
    class: Drupal\tracking_number_email\EventSubscriber\OrderFulfillmentSubscriber
    arguments: ['@language_manager', '@plugin.manager.mail']
    tags:
      - { name: event_subscriber }

```

File: /modules/custom/tracking\_number\_email/src/EventSubscriber/TrackingNumberEmail.php

```
<?php

    namespace Drupal\tracking_number_email\EventSubscriber;

    use Drupal\state_machine\Event\WorkflowTransitionEvent;
    use Drupal\Core\Language\LanguageManagerInterface;
    use Drupal\Core\Mail\MailManagerInterface;
    use Drupal\Core\StringTranslation\StringTranslationTrait;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;

    /**
     * Sends an email when the order transitions to Fulfillment.
     */
    class OrderFulfillmentSubscriber implements EventSubscriberInterface {

      use StringTranslationTrait;

      /**
       * The language manager.
       *
       * @var \Drupal\Core\Language\LanguageManagerInterface
       */
      protected $languageManager;

      /**
       * The mail manager.
       *
       * @var \Drupal\Core\Mail\MailManagerInterface
       */
      protected $mailManager;

      /**
       * Constructs a new OrderFulfillmentSubscriber object.
       *
       * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
       *   The language manager.
       * @param \Drupal\Core\Mail\MailManagerInterface $mail_manager
       *   The mail manager.
       */
      public function __construct(
        LanguageManagerInterface $language_manager,
        MailManagerInterface $mail_manager
      ) {
        $this->languageManager = $language_manager;
        $this->mailManager = $mail_manager;
      }

      /**
       * {@inheritdoc}
       */
      public static function getSubscribedEvents() {
        $events = [
          'commerce_order.fulfill.post_transition' => ['sendEmail', -100],
        ];
        return $events;
      }

      /**
       * Sends the email.
       *
       * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event-
       *   The transition event.
       */
      public function sendEmail(WorkflowTransitionEvent $event) {
        // Create the email.
        $order = $event->getEntity();
        $to = $order->getEmail();
        $params = [
          'from' => $order->getStore()->getEmail(),
          'subject' => $this->t(
            'Regarding your order [#@number]',
            ['@number' => $order->getOrderNumber()]
          ),
          'body' => ['#markup' => $this->t(
            'Your order with #@number that you have placed with us has been processed and is awaiting fulfillment.',
            ['@number' => $order->getOrderNumber()]
          )],
        ];

        // Set the language that will be used in translations.
        if ($customer = $order->getCustomer()) {
          $langcode = $customer->getPreferredLangcode();
        }
        else {
          $langcode = $this->languageManager->getDefaultLanguage()->getId();
        }

        // Send the email.
        $this->mailManager->mail('commerce', 'receipt', $to, $langcode, $params);
      }

    }

```

I am receiving the following error message when this custom module is installed:

> ReflectionException: Class Drupal\tracking\_number\_email\EventSubscriber\OrderFulfillmentSubscriber does not exist in ReflectionClass-\>\__construct() (line 30 of /home1/mysite/public\_html/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php).

If I remove the tracking\_number\_email.services.yml the error goes away, but the module doesn't work (to be clear, it doesn't work whether or not that services.yml file is in place). I assume I have something erroneous in that services.yml file, but I am stuck trying to figure out what is wrong.

# Answer
I didn't read through your code attempts, but have you evaluated Commerce Email yet? The module was basically written to serve this purpose.
> 0 votes

---
Tags: 8, commerce, event-subscribers
---


title: How can I place a view on a page?

text:
# Question
Title: How can I place a view on a page?
I would like to add a view at the bottom of a page. Is it possible? How?

# Answer
You can create block display in your view, then go to the block configuration page (Structure \> Blocks) and place your block in a region at the bottom of your page.
> 1 votes

# Answer
You can use views\_embed\_view() function for that.

https://api.drupal.org/api/views/views.module/function/views\_embed\_view/7.x-3.x

Pass view machine name, display machine name and optionally parameters. Use "embed" display type for a viewto get config links on front-end when embedded.

Example:

```
<?php print views_embed_view('blog_posts','block_1', $node->nid); ?>

```

You can also use `views_get_view_result()` (similar way) to execute view, get it's output. I.e. if you want to execute it from controller and pass value to template.

https://api.drupal.org/api/views/views.module/function/views\_get\_view\_result/7.x-3.x

Or make "block" display for view and add it as a block. Configure that block to be displayed only on specific page.
> 0 votes

# Answer
You may use Panels to build that. Through Page Manager, you may create a page with a specific URL (of course) and then use the Panels magic by adding any element you need, including a View anywhere within the page layout you have chosen (works nice with Display Suite or Bootstrap). This specific layout and content will appear only for the specific page/URL.
> 0 votes

---
Tags: 7, views
---


# Question
Title: How can I untheme a fieldset provided by theme_fieldset()?
I'm allowing users to set their time zone upon registration. However, I don't want to show the "Locale settings" fieldset that is provided (border, title "Locale Settings", etc.) Is there a simple way to use hooks to remove the fieldset markup but not the content of the fieldset itself?

With theme\_devel, I've been able to get the function that makes the fieldset (theme\_fieldset()) as well as the form id (edit-timezone). But I don't know what to do with these to hide the fieldset markup but allow the content to remain.

# Answer
You need to alter the form that contains that fieldset. You could do it using code similar to the following one.

```
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  // Only alter user forms if there is more than one language.
  if (drupal_multilingual()) {
    // Display language selector when either creating a user on the admin
    // interface or editing a user account.
    if ($form_id == 'user_register_form' || ($form_id == 'user_profile_form' && $form['#user_category'] == 'account')) {
      if (isset($form['locale'])) {
        foreach (element_children($form['locale']) as $id) {
          $form[$id] = $form['locale'][$id];
          $form[$id]['#access'] = $form['locale']['#access'];
        }
      }

      unset($form['locale']);
    }
  }
}

```
* The code I wrote removes the fieldset from both the registration form, and the user profile form.
* For the user registration form, the language fieldset is normally hidden to the users that don't have the permission to administer users. There could be a module that shows that fieldset to every user.
* If you want to be sure that your code doesn't create problems to other modules, you should be sure it is executed after all the other modules that add fields to `$form['locale']`.
* Usually there isn't any reason to remove a fieldset. It is convenient for the users to have related fields grouped together; in that way, if they don't need to edit them, they just collapse the fieldset.

To be sure the code of your module is executed after all the other modules, you could do proceed with two methods:

* You can alter the module weight, and increase it. In this way, the hooks implemented in your module would be executed for last.
* You can implement hook\_module\_implements\_alter() to alter the order some hooks are executed.

```
function mymodule_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter') {
    // Move mymodule_form_alter() to the end of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['mymodule'];
    unset($implementations['mymodule']);
    $implementations['mymodule'] = $group;
  }
}

```

The documentation for `hook_module_implements_alter()` reports the following notes:

> Note that hooks invoked using `drupal_alter()` can have multiple variations (such as `hook_form_alter()` and `hook_form_FORM_ID_alter()`). `drupal_alter()` will call all such variants defined by a single module in turn. For the purposes of `hook_module_implements_alter()`, these variants are treated as a single hook. Thus, to ensure that your implementation of`hook_form_FORM_ID_alter()` is called at the right time, you will have to have to change the order of `hook_form_alter()` implementation in `hook_module_implements_alter()`.

Between the two methods, I would use the latter, as it doesn't change the order other hooks are executed, differently from the first.
> 1 votes

# Answer
In Drupal 8, there's an easy way to do this.

```
function MYMODULE_form_user_form_alter(&$form, &$form_state) {
    // Remove the fieldset.
    // The default of 'details' creates a fieldset.
    $form['timezone']['#type'] = 'container';
}

```
> 1 votes

---
Tags: theming, hooks
---


title: Change Link URL in preprocess function

text:
# Question
Title: Change Link URL in preprocess function
I need to slightly modify some URLs that are in a "Link" field on a custom entity type.

In a `mytheme_preprocess_myentity` I've found that field with `$variables['elements']['field_my_url'][0]` I get this output in Kint

I've tried using a number of methods on the `#url` object but I don't think I'm doing it correctly... I'm just confused on how to modify it at this point.

How can I change the external URL to which this particular field is pointing?

# Answer
Drupal's Core Url has a static `fromUri()` method (see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/function/Url%3A%3AfromUri/8.2.x)

With that in mind you should be able to swap out the `['#url']` with a new one thusly:

```
...['#url'] = \Drupal\Core\Url::fromUri('externalURL');

```
> 2 votes

---
Tags: 8, theming
---


title: entity_lookup for user entity type

text:
# Question
Title: entity_lookup for user entity type
I'm trying to link a field in my spreadsheet file to a user that is previously created with a migration from the same spreadsheet. The Backup column consists of multiple names divided by the backward slash (Firstname Lastname/Firstname Lastname)

migrate\_plus.migration.profiles.yml:

```
process:
  field_backup:
    -
      plugin: explode
      delimiter: '/'
      source: 'Backup'
    -
      plugin: entity_lookup
      value_key: name
      ignore_case: true
      entity_type: user
      bundle_key: uid
      bundle: people

```

migrate\_plus.migration.users.yml:

```
process:
    name:
      plugin: concat
      source:
        - 'Firstname'
        - 'Lastname'
      delimiter: ' '

```

The backup field is just skipped when migrating the profiles. The only error I'm getting is when i go to a profile page and check the log messages.

> User error: "attributes" is an invalid render array key in Drupal\Core\Render\Element::children() (regel 97 van /var/www/html/web/core/lib/Drupal/Core/Render/Element.php) #0 /var/www/html/web/core/includes/bootstrap.inc(587): \_drupal\_error\_handler\_real(256, '"attributes" is...', '/var/www/html/w...', 97, Array) #1 \[internal function\]: \_drupal\_error\_handler(256, '"attributes" is...', '/var/www/html/w...', 97, Array) #2
>
> /var/www/html/web/core/lib/Drupal/Core/Render/Element.php(97): trigger\_error('"attributes" is...', 256) #3
>
> ...

Can you not use entity\_lookup for users or am I doing something wrong in my configuration?

Any help would be much appreciated

# Answer
bundle\_key is the name of the column and bundle is any value associated with that column.

In the below example the migration process will look for those column in user table whose status is 1 and uid value is equal to userid.

```
 plugin: entity_lookup
 source: userid
 value_key: uid
 bundle_key: status
 bundle: 1
 entity_type: user
 ignore_case: true

```
> 1 votes

# Answer
If `entity_lookup` is searching for users, then the bundle should also be *user*, since there is no *people* bundle.
> 0 votes

---
Tags: migrations
---


# Question
Title: How to add constraints to custom data arrays?
I am validating csv files. I am thinking of using constraints and constraint validator framework available in Drupal to validate the data in the files. However, these seem to be designed to be attached to entity fields. For example.

```
/**
 Implements hook_entity_base_field_info_alter().
 */
 function projectname_commerce_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
   if ($entity_type->id() === 'commerce_order_item') {
     if (!empty($fields['unit_price'])) {
       $fields['unit_price']->addConstraint('PriceBelowMax');
     }
   }
 }

```

where PriceBelowmax is a custom constraint. I would like to attach this constraint to a custom data array. For example

```
myCustomValidatemethod($data_array, $constraints)

```

where constraints would be the list of constraints defined in Drupal both core and custom. Is there some reference for the above method.

# Answer
> 2 votes
You cannot validate generic data against a list of constraints you create.

Constraints are attached to specific typed data objects, entity fields, or entities. You can only validate them against the constraints they have, and you don't need to get first the list of the constraints that apply.

If `$entity` contains an entity, you can use the following code to check if it validates against its constraints.

```
$violations = $entity->validate();
if ($violations) {
  // The entity didn't pass validation from constraints.
  // For each validation $validation->getMessage() returns the
  // error message. $violation->getPropertyPath() returns the property
  // path for the property that failed validation, for example
  // field_text.0.value, if the validation failed for the value property of
  // field_text.
}

```

To validate only a single entity field, for example field\_text in `$entity`, instead of `$entity->validate()`, which would validate the entity and all its entity fields, the method to call is `$entity->field_text->validate()`.

---
Tags: 8
---


# Question
Title: How to remove images from body field in views?
In the body field of a content type, I have added an image at the start. In my view, I want to show 200 characters from the body field. It also prints the image.

How can I skip the photos from the body field in the view, and print just the text?

# Answer
> 2 votes
Edit the Body Field `Rewrite results` in your Views and enable the option **Strip HTML tags**. Use `Preserve certain tags` if you have other elements within your text you want to show, enter them there.

This option is below the `Trim this field to a maximum number of characters` you're probably using, you'll probably want to also use the suboption `Field can contain HTML`.

---
Tags: views, nodes, media
---


title: Do we upgrade core or PHP first?

text:
# Question
Title: Do we upgrade core or PHP first?
We have Drupal 7 running on PHP 5.6. Do we upgrade to PHP 7 first, or do we first upgrade Drupal?

# Answer
Drupal 7 can run on any PHP version between PHP 5.6 and PHP 7.3. For running on PHP 7.4, it's required at least Drupal 7.71.
Drupal 8 can run on any PHP version that is newer than PHP 5.6. For running on PHP 7.4, it's required at least Drupal 8.8.3.

If the site is running a version of Drupal that is older than Drupal 7.71, I would first upgrade PHP to PHP 7.3, and then upgrade to Drupal 8.
If the site is running on Drupal 7.71 or any newer version, you can upgrade to PHP 7.4, if you mean to upgrade Drupal to Drupal 8.8.3 or a newer version.

I would also test the upgrade on a local test site, as third-party modules you are using could cause problems with newer PHP versions.
It should be safer to upgrade to PHP 7.3, as there are backward incompatible changes in PHP 7.4 that required changing the code in Drupal 7; it's probable the same changes are required in third-party modules, but those changes are still to be applied to those modules.
> 3 votes

---
Tags: upgrading
---


title: How to set up a recurring payment

text:
# Question
Title: How to set up a recurring payment
I need to set up a recurring payment on Drupal 8. I discovered these two possiblity :

What is the difference between these two possiblity ?

The commerce reccuring module looks extremely complex to set up.

# Answer
It's entirely dependent on your business needs. The advantage of Commerce Recurring is that as part of the Drupal Commerce ecosystem, it gives you a complete toolset for building a subscription management interface in Drupal 8. This will let you completely customize the checkout flow, order receipts, other user interfaces and more, but it does require experience with Drupal 8 to build and maintain. For more information, review the documentation at:

https://docs.drupalcommerce.org/commerce2/developer-guide/recurring

If you just want to embed a Stripe widget, I recommend MoonClerk.
> 3 votes

# Answer
There is a Recurly module to integrate the Recurly subscription service.

This module has a stable release for Drupal 8.

The project page also has a fair amount of information on PCI compliance.
> 0 votes

# Answer
There is the Stripe Registration module, which implements Stripe Plans.

It has the important limitation of "one subscription per user".
> 0 votes

---
Tags: 8, commerce, payment-gateways
---