# Question
Title: How can I temporarily prevent any login?
I've a high visitor website in Drupal 6. For performance reasons I've removed Captcha on all pages.

I don't want anybody to log in and we don't logout.

Can I rename any Drupal file related to login-functionality? I have SSH access and also use `drush`. When I want to enable login functionality I've move the file back.

# Answer
> 0 votes
create a simple custom module, by getting the help of hook\_form\_FORM\_ID\_alter to disable login form by the following snippet.

**solution A:**

```
function hook_form_user_login_alter(&$form, &$form_state) {
  unset($form);
  $form = array();
  // or disable it with the following
 //$form['#access'] = false;
}

```

**solution B:**

```
function hook_form_user_login_alter(&$form, &$form_state) {
 $form['#access'] = false;
}

```

**solution C:** disable submit button

```
function hook_form_user_login_alter(&$form, &$form_state) {
 $form['submit']['#access'] = false;
}

```

# Answer
> 1 votes
The correct way to avoid users can access the login form is changing the access callback of the route used for the login form and removing the login block from any page.
Altering the form with `hook_form_alter()` or `hook_form_FORM_ID_alter()` and setting `$form['#access']` to `FALSE` would just hide the form to the users, who would just see a blank page.
Altering the access callback, users would see an access denied error page if they try to access the login page entering directly the login path in the address bar of the browser (http://example.com/user/login, if clear URLs are enabled, or http://example.com/?q=user/login, in the case clear URLs aren't enabled) which would make clear the login page is not accessible to them. Plus, Drupal wouldn't show any link pointing to the login page, if users don't have access to that route. This means that, if you have a module that adds a link to the login page, that link would not be shown to the users who cannot access the login page.

Since the User module is already using an access callback for user/login, it's sufficient to change it, for example with the following code.

```
function mymodule_menu_alter(&$items) {
  if (isset($items['user/login']) {
    $items['user/login']['access callback'] = FALSE;
  }
}

```

Setting the access callback to `FALSE` makes user/login not accessible from any user.

I would not use that code, if I am not totally sure users aren't automatically logged off, for example because the session cookie has expired, or because there is a module that logs them off when their session lasted too long.

---
Tags: 6
---


title: Hide block if no submenu in Twig

text:
# Question
Title: Hide block if no submenu in Twig
I'm creating a node--page.html.twig and I'm using twig\_tweak to help render a block for my sidebar to display the sub-menus. Is there a way to hide it if the page doesn't have any submenus?

Here's my code:

```
<div class="page-sidebar grid-3 alpha">
  <div class="sub-region page-sidebar clearfix widgets widget-sidebar">
    <div class="contextual-links-region panel-pane pane-menu-tree pane-main-menu">
    {{ drupal_entity('block', 'mainmenu', check_access=false) }}
  </div>
</div>

```

Is there some sort of `if` statement I could use to hide the block if the page has no submenu?

Thank you!

# Answer
I generally handle this sort of thing like:

```
// First render my content and set it to a variable.
{% set submenu = drupal_entity('block', 'mainmenu', check_access=false)|render %}
// Next, check if the variable have content.
{% if submenu %}
  // If variable has content, render with wrapping div(s).
  <div class="my-wrapping-div">
    {{ submenu }}
  </div>
{% endif %}

```

It's important to render the submenu whether or not it has any displayable content to make sure it's cache settings are bubbled up.

Note: this will only work if whatever your rendering returns no html. If you're seeing some wrapping divs, etc return, but no content, you can alter your if statement like `{% if submenu|striptags|trim %}` to strip html and check for only content.
> 0 votes

---
Tags: theming, blocks
---


# Question
Title: How to clear the a block cache programmically
I have a custom block that display some information from a custom configuration form. I want the block to be cached, however, I want the block cache to be cleared every time I save the form.

I would like to do this in the `submitForm` function. How do I go about and do this?

# Answer
When displaying information from a config object add it also as cache dependency to the render array.

For example in a preprocess hook:

```
  $config = \Drupal::config('mymodule.settings');
  $config_value = $config->get('some_field');
  $variables['some_field'] = [
    '#markup' => $config_value,
  ];
  // add the cache tag, so that the output gets invalidated when the config is saved
  \Drupal::service('renderer')->addCacheableDependency($variables, $config);

```

See How to clear cache for config entity after making changes?

**You don't need to change form submit because saving a config object automatically invalidates cache entries having this cache dependency (cache tag).**

---

Another example based on the block code from your answer and using a different method to add the cache tag:

```
  /**
   * Config settings.
   *
   * @var string
   */
  const SETTINGS = 'uw_cbl_special_alert.settings';
  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = \Drupal::config(static::SETTINGS);
    return [
      '#markup' => $config->get('message'),
      '#cache' => [
        'tags' => $config->getCacheTags(),
      ],
    ];
  }

```

---

## Access caching

As asked in the comments, you can add cache dependencies to access results as well:

```
AccessResult::allowed()->addCacheableDependency($config)
AccessResult::forbidden()->addCacheableDependency($config)

```
> 8 votes

# Answer
Ok I believe I figured it out. This works for me.

```
use Drupal\Core\Cache\Cache;
class ConfigurationForm extends ConfigFormBase {
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Invalidate block cache.
    Cache::invalidateTags(['config:block.block.{block_id_tag}']);
  }
}

```

I had to search the cachetags table in the database to find the block id tag.
In my case my custom block id in the annotation was `uw_cbl_special_alert` but the block id tag was `specialalert`

In case you are interested, code snippet from custom block

```
  /**
   * Config settings.
   *
   * @var string
   */
  const SETTINGS = 'uw_cbl_special_alert.settings';
  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = \Drupal::config(static::SETTINGS);
    // Turn caching off as this is a special message and show never be cached.
    return [
      '#markup' => $config->get('message'),
    ];
  }

```
> -2 votes

---
Tags: 8
---


title: hook_form_alter() Ajax suffix replace

text:
# Question
Title: hook_form_alter() Ajax suffix replace
I'm trying to rewrite a form item's suffix on an AJAX callback and it keeps prepending the first choice and then doing nothing else. My code:

```
function my_dashboard_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  if($form_id == 'node_job_listing_owner_job_form_form'){
    $tid = $form_state->getValue('field_job_description')[0]['target_id'];
    if(empty($tid)){
      $tid = $form['field_job_description']['widget']['#default_value'][0];
    }
    $link = null;
    if(!empty($tid)){
      $link_url = \Drupal\Core\Url::fromRoute('entity.taxonomy_term.canonical', [
        'taxonomy_term' => $tid
      ], [
        'attributes' => [
          'class' => ['use-ajax'],
          'data-dialog-type' => 'dialog',
          'data-dialog-options' => \Drupal\Component\Serialization\Json::encode(['width' => 420]),
          'data-dialog-renderer' => 'off_canvas',
        ],
      ]);
      $link = \Drupal::l('Preview Job Description...'.$tid, $link_url);
    }

    $form['field_job_description']['#suffix'] = $link;
    $form['field_job_description']['widget']['#ajax'] = [
      'callback' => 'updateJobDescriptionPreviewLink',
      'wrapper' => 'edit-field-job-description-wrapper',
      'event' => 'change',
    ];
  }
}

function updateJobDescriptionPreviewLink(&$form, \Drupal\Core\Form\FormStateInterface $form_state){
  return $form['field_job_description'];
}

```

Basically, I'm trying to put a link below the "Job Description" drop down to preview the description of that term. I have the term id appended to the link text temporarily so I can see what happens. When I edit an existing node, it renders the link correctly the first time (i.e. "Preview Job Description...102"). But then, if I select a different option, it prepends another link to the existing suffix (i.e. "Preview Job Description...99 Preview Job Description...102"). Both links work correctly, but obviously two links aren't what I want. And also after that, it won't change anymore no matter what I select.

I feel like there's something simple I'm overlooking, but I confess Drupal AJAX has always confused me somewhat. Any ideas? Thanks!

# Answer
> 1 votes
I think the estrange behaviour it's because the suffix is after and not inside the wrapper, thus not get replaced and since you're ajaxly returning `$form['field_job_description'];` which contains the wrapper; thus, you end up with two same ID wrappers and fails on the second run.

Move the link generation to a function.

Here is an alternative AJAX approach where we target the link wrapper rather than the form wrapper.

```
function my_dashboard_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  if($form_id == 'node_job_listing_owner_job_form_form'){
    $link = _my_dashboard_get_term_link($form, $form_state);
    $form['field_job_description']['#suffix'] = '<div class="term-link">' . $link . '</div>'; // wrap link
    $form['field_job_description']['widget']['#ajax'] = [ // removed 'wrapper' =>
      'callback' => 'updateJobDescriptionPreviewLink',
      'event' => 'change',
    ];
  }
}

function updateJobDescriptionPreviewLink(&$form, \Drupal\Core\Form\FormStateInterface $form_state){
  $link = _my_dashboard_get_term_link($form, $form_state);
  $response = new \Drupal\Core\Ajax\AjaxResponse();
  $response->addCommand(new \Drupal\Core\Ajax\HtmlCommand(".term-link", $link));
  return $response;
}

function _my_dashboard_get_term_link(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $tid = $form_state->getValue('field_job_description')[0]['target_id'];
  if(empty($tid)){
    $tid = $form['field_job_description']['widget']['#default_value'][0];
  }
  $link = null;
  if(!empty($tid)){
    $link_url = \Drupal\Core\Url::fromRoute('entity.taxonomy_term.canonical', [
      'taxonomy_term' => $tid
    ], [
      'attributes' => [
        'class' => ['use-ajax'],
        'data-dialog-type' => 'dialog',
        'data-dialog-options' => \Drupal\Component\Serialization\Json::encode(['width' => 420]),
        'data-dialog-renderer' => 'off_canvas',
      ],
    ]);
    $link = \Drupal::l('Preview Job Description...'.$tid, $link_url);
    return $link;
  }
}

```

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


title: array_flip() error when using phpunit

text:
# Question
Title: array_flip() error when using phpunit
I've got a form, which when I use normally works perfectly fine, but when I load the form in phpunit I get the following error :

> 1. Drupal\digest\tests\DigestSubscriptionFormTest::testFormDisplay Exception: Warning: array\_flip(): Can only flip STRING and INTEGER values! Drupal\Core\Entity\EntityStorageBase-\>loadMultiple()() (Line: 261)

Within `buildForm` I have something like this :

```
    $digest_storage = $this->entityTypeManager->getStorage('digest');
    $digests = $digest_storage->loadMultiple();
    $subscription_storage = $this->entityTypeManager->getStorage('subscription');

    /** @var \Drupal\digest\Entity\DigestInterface $digest */
    foreach ($digests as $digest) {

      $query = $subscription_storage->getQuery();
      // There should never be more than one ID returned.
      $subscription_id = $query->condition('digest', $digest->id())
        ->condition('uid', $this->currentUser->id())
        ->execute();

      /** @var \Drupal\digest\Entity\SubscriptionInterface $subscription_entity */
      $subscription_entity = $subscription_storage->load(current($subscription_id));
      $entity_exists = isset($subscription_entity);

```

Now when I am using this on my own it works just fine. No errors or warnings at all.

As soon as I get the page from phpunit I get the above error. Here's the test

```
  public function testFormDisplay() {

    $this->drupalLogin($this->adminUser);

    // Create some basic digests to view.
    $digest_storage = \Drupal::entityTypeManager()->getStorage('digest');
    $digest_storage->create([
      'id' => 'viewOne',
      'label' => 'View One',
      'enabled' => TRUE,
      'title' => 'Custom Title',
      'description' => 'Custom description',
      'send_at' => 'Monday',
    ])->save();
    $digest_storage->create([
      'id' => 'viewTwo',
      'label' => 'View Two',
      'enabled' => FALSE,
      'title' => 'Ghost',
      'description' => 'I\'m invisible',
      'send_at' => 'Friday',
    ])->save();

    // Load the subscription form.
    $this->drupalGet(Url::fromRoute('digest.digest_subscriptions'));

```

Adding the `drupalGet` line makes the test fail. If I remove the creation of the entities it works.

I'm not only wondering how to fix this but also why? This is a functional test so it should have a full site meaning I should be able to use the entityTypeManager as normal correct? Mocking is only needed for unit and some kernel tests right?

# Answer
In the code shown for `buildForm()` there are two calls to `loadMultiple()`:

* The explicit call in the `$digests = $digest_storage->loadMultiple();` line
* The implicit call in the `$subscription_entity = $subscription_storage->load(current($subscription_id));` line

The second line is an implicit call to `loadMultiple()` because the default implementation of `load()` (`EntityStorageBase::load()`) uses the following code.

```
assert(!is_null($id), sprintf('Cannot load the "%s" entity with NULL ID.', $this->entityTypeId));
$entities = $this->loadMultiple([$id]);
return isset($entities[$id]) ? $entities[$id] : NULL;

```

`EntityStorageBase::loadMultiple()` uses the following code.

```
$entities = [];
$preloaded_entities = [];

// Create a new variable which is either a prepared version of the $ids
// array for later comparison with the entity cache, or FALSE if no $ids
// were passed. The $ids array is reduced as items are loaded from cache,
// and we need to know if it is empty for this reason to avoid querying the
// database when all requested entities are loaded from cache.
$flipped_ids = $ids ? array_flip($ids) : FALSE; // This is line 261, in Drupal 9.0.x.

```

`array_flip()` raises the *Can only flip STRING and INTEGER values!* warning when the array passed as argument doesn't contain a string or an integer value, which also happens when the array contains one or more `NULL` values, or even `FALSE` values.
This means, for example, that the following line isn't setting `$subscription_id` to an integer or a string, possibly because there aren't any *digest* entity whose ID is `$digest->id()` associated with the *subscription* entity, or associated with the currently logged-in user.

```
$subscription_id = $query->condition('digest', $digest->id())
  ->condition('uid', $this->currentUser->id())
  ->execute();

```

This is the probable cause, giving that the code of that test isn't creating any *subscription* entity. If creating a *digest* entity is supposed to create a *subscription* entity, then it's not creating a *subscription* entity that is associated with a *digest* entity with that ID or with the currently logged-in user.

(I assume `$digest->id()` is returning an integer, since that is the usual case. I would verify that too, but since it's the test that is failing, it seems more probable the cause of the warning is the one I described.)
> 2 votes

---
Tags: testing, 9
---


# Question
Title: How can I change which view wins over two using the same path?
I have two views in Drupal 8.

1. The standard **Taxonomy term (content)** view, path: `/taxonomy/term/%`
2. My custom view for just one term at path: `/term-alias`

When I go to my custom term, I see the view for all terms (#1), when I want to force it to #2. How can I do that?

# Answer
> 3 votes
Use the internal path of the term:

```
/taxonomy/term/123

```

Route matching operates only on internal (unaliased) paths and route #2 having more fixed parts wins.

See https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Routing%21RouteCompiler.php/function/RouteCompiler%3A%3AgetFit/9.0.x

---
Tags: views, taxonomy-terms, path-aliases
---


# Question
Title: REST API OAuth Authorization and Authentication
I am very much confused about the way OAuth authorization and authentication works in Drupal 8/9. Let me put my points first, please correct me if I am wrong.

* Authorization is when an entity proves a right to access.
* Authentication is when an entity proves an identity.

I have done the following to implement a REST API which is intended to be consumed by mobile applications (Android and iOS).

* Installed and/or enabled modules: Simple OAuth, REST UI, RESTful Web Services, Serialization.
* Created a new role for specifying the scope of simple OAuth consumer, and set required permissions.
* Created a consumer by adding RSA key pair, password and scope.
* Succeeded in getting the response from `/oauth/token` by submitting a request body containing `grant_type`, `client_id`, `client_secret`, `username` and `password`.

The question is, why we need to send the `username` and `password`, for getting the `access_token`, since we are only trying to **Authorize the API Request and NOT Authenticate the User**?

Also, what should I do to **Authorize the API request with OAuth but need to access contents without authentication**? Should I create a dummy user and always send this user credentials to get access\_token?

It would be very helpful if someone can explain the concept and how should one proceed.

Reference I followed: https://dev.acquia.com/blog/decoupled-drupal-authentication-oauth-20

# Answer
> 0 votes
Actually, I got the solution. It was my mistake, that I was trying to use OAuth2 3-legged authorization, but I am actually need OAuth 2-legged authorization.

More Details on oAuth Flow and Grant Types: oAuth Grant Types

---
Tags: authentication-authorization, 9
---


# Question
Title: Make the suggestions of an autocomplete exposed form clickable
I'm using Drupal 7 and Views.

I have an exposed form of type "autocomplete".

I would like the suggestions to be clickable, which avoids having to click on apply.

Do you know how to do it ?

# Answer
Install Better Exposed Filters module , got to your views, in *Advanced* section In **Exposed form style:** select *better exposed* .

> The Better Exposed Filters module replaces the Views' default single- or multi-select boxes with radio buttons or checkboxes, respectively. Description fields and Select All/None links can be added to exposed filters to make for a better user experience. Views Filters is a powerful tool to refine the results returned by a given view. When you expose a filter, you allow the user to interact with the view making it easy to build a customized, advanced search. For example, exposing the node type field as a filter lets your site visitor limit their search queries to just blog entries. Better Exposed Filters gives you greater control over the rendering of exposed filters.
>
> Why use this module? Because it provides a better user experience than the default option. Try telling a client that they should click on an option, then scroll to the next option and ctrl+click on it. Don't just click 'cause you'll lose your first selection. Oh, and ctrl+click again to unselect an option... Yeah, not user friendly.

additionally,

> **What else can you do with BEF?**.
> The BEF handbook page provides some basic recipes making exposed filters a much better user experience.
>
> Add help text for each exposed filter Tame long lists with scrollable checkbox/radio button lists or select all/none links Provide instant feedback by updating the View using AJAX whenever an exposed filter is changed Use the jQuery Slider widget for greater-than, less-than or in-between types of filters If you've got any ideas not covered on the handbook page, add a feature request to the issue queue. You can also rate this module on DrupalModules.
> 0 votes

---
Tags: 7, views
---


title: Configuration Mime Types error

text:
# Question
Title: Configuration Mime Types error
I have a Drupal 8 installation and am developing the site. It's not operational yet.

I have 2 problems i think are related. First of all a selected image in a custom content type isn't uploaded or shown in new content of the content type. It is a standard image field.

When searching for a solution i got an error log saying that there is a problem with a missing MIME Map extension in sophron. When looking at the Mime types in the Configuration section, my second problem arises.

I get the following error when clicking MIME Types:

> The website encountered an unexpected error. Please try again later. Error: Class 'FileEye\MimeMap\MapHandler' not found in Drupal\sophron\EventSubscriber\SophronEventSubscriber-\>initializeMap() (line 68 of modules\sophron\src\EventSubscriber\SophronEventSubscriber.php). Drupal\sophron\EventSubscriber\SophronEventSubscriber-\>initializeMap(Object, 'sophron.map.initialize', Object) call\_user\_func(Array, Object, 'sophron.map.initialize', Object) (Line: 111) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher-\>dispatch('sophron.map.initialize', Object) (Line: 129) Drupal\sophron\MimeMapManager-\>setMapClass('Drupal\sophron\Map\DrupalMap') (Line: 105) Drupal\sophron\MimeMapManager-\>getMapClass() (Line: 152) Drupal\sophron\Form\SettingsForm-\>buildForm(Array, Object) call\_user\_func\_array(Array, Array) (Line: 520) Drupal\Core\Form\FormBuilder-\>retrieveForm('sophron\_settings', Object) (Line: 277) Drupal\Core\Form\FormBuilder-\>buildForm(Object, Object) (Line: 91) Drupal\Core\Controller\FormController-\>getContentResult(Object, Object) call\_user\_func\_array(Array, Array) (Line: 123) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() (Line: 573) Drupal\Core\Render\Renderer-\>executeInRenderContext(Object, Object) (Line: 124) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>wrapControllerExecutionInRenderContext(Array, Array) (Line: 97) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() (Line: 151) Symfony\Component\HttpKernel\HttpKernel-\>handleRaw(Object, 1) (Line: 68) Symfony\Component\HttpKernel\HttpKernel-\>handle(Object, 1, 1) (Line: 57) Drupal\Core\StackMiddleware\Session-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\KernelPreHandle-\>handle(Object, 1, 1) (Line: 106) Drupal\page\_cache\StackMiddleware\PageCache-\>pass(Object, 1, 1) (Line: 85) Drupal\page\_cache\StackMiddleware\PageCache-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\ReverseProxyMiddleware-\>handle(Object, 1, 1) (Line: 52) Drupal\Core\StackMiddleware\NegotiationMiddleware-\>handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel-\>handle(Object, 1, 1) (Line: 694) Drupal\Core\DrupalKernel-\>handle(Object) (Line: 19)

Does anyone have an idea?

# Answer
> -1 votes
Based on the https://www.drupal.org/project/sophron module page. you should install it with

```
composer require drupal/sophron

```

the error is complaining about missed class that you need to install the module by composer way ( as what recommended in module page)

> **Installation**

> Require the module via
>
> $ composer require drupal/sophron
>
> This will download both the module and any dependency. Then, enable the module as usual.

---
Tags: 8
---


# Question
Title: Query remaining field names from a database table
There's a database table. I know only one field name on the database table: username. How do I view remaining field names on the table?

```
namespace Drupal\fixx_helper\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

class AutocompleteController extends ControllerBase
{
   public function handleAutocomplete(Request $request)
   {
      $results = [];

      $input = $request->query->get('q');
      $database = \Drupal::database();
      $my_query = $database->query("select distinct username from banner_exports.ws_students where username like '$input%'");

      while($result = $my_query->fetchAssoc()){
         $matches[] = array('value' => $result['username'], 'label' => $result['username']);
       }
       return new JsonResponse($matches);

```

}}

# Answer
There are multiple table locations for Drupal field data: the base User entity table `users_field_data` & the `user__$FIELD` tables that contain the custom fields defined by site builder / developer. If you need *field data* from a DB query, then you're going to need to build a query with a few joins to put it all together.

If you're only looking for the field names then it's much earlier to use the entity field manager to pull the base & custom fields:

```
\Drupal::service('entity_field.manager')->getFieldDefinitions('user', 'user')

```
> 0 votes

---
Tags: 8, entities
---


# Question
Title: How to customize the default search block form template?
How can I customize the default search block form template, I now use below template to display a search form block, but this code doesn't allow me to edit and customize each part of this form separately and doesn't have any flexibility.

**form--search-block-form.html.twig**

```
<form{{ attributes.addClass('search-form', 'search-block-form') }}>
  {{ children }}
</form>

```

and then print in my theme by below code:

```
{{ page.search_box }}

```

Is there any better template name suggestion with more variables and flexibility in customization?

# Answer
If you want to use Twig, you can do it by creating a template file, like this:

/themes/your\_theme/templates/**form--search-block-form.html.twig**

```
{% set form = element %}

hello {{ form.keys }} world {{ form.actions }}

```

---

# Result:

In Bartik theme:
> 5 votes

# Answer
The search block is provided by the core module Search. If you install this module the block will be available in the block layout, when you place a block.

Probably you have already done this by installing the standard profile.

To customize the search form you can use a form alter hook.

For example put this function in `mytheme.theme` to change the search button:

```
function mytheme_form_alter(&$form, $form_state) {
  if ( $form['#form_id'] == 'search_block_form' ) {
    $form['actions']['submit']['#value'] = t('Search my Website');
  }
}

```
> 5 votes

# Answer
I have gone a 2 days journey now inspecting `container.html.twig` and extra suggestions for it and lots of other dead end solutions.

I finaly came back here and got a result i want to keep here for reference:

i developed and tested this code with Drupal 9.0.1

myTheme.theme:

```
/**
 * Implements hook_theme_suggestions_HOOK_alter() for form templates.
 *
 * @hook: form
 * @suggestion: search_block_form
 * @result: loads template form--search_block_form.html.twig
 */
function myTheme_theme_suggestions_form_alter(array &$suggestions, array $variables) {
  if ($variables['element']['#form_id'] == 'search_block_form') {
    $suggestions[] = 'form__search_block_form';
  }
}

```

form--search-block-form.html.twig:

```
{#
/**
 * @file
 * Custom Search form template
 *
 * Available variables:
 * - attributes: A list of HTML attributes for the wrapper element.
 * - children: The child elements of the form.
 * - element: Not documented but exits, need to find out more
 *
 * @see template_preprocess_form()
 * @why the default call of `{{ children }}` calls a "container.twig.html"
 *      instead of the form elements itself "input.twig.html"
 *      its technically not necessary to have container markup arround
 *      label, text input and submit button and its a drawback for
 *      extended CSS layouts that get way more complex on such markup
 */
#}
{# extend element attributes (taken from bartik) #}
{%
  set attributes = attributes.addClass('search-form', 'search-block-form')
%}
{# create attributes for the search input field by system variable #}
{%
  set input_attributes = create_attribute(element.keys['#attributes'])
%}
{# extend attributes for the search input field #}
{%
  set input_attributes = input_attributes.setAttribute('placeholder', element.keys['#title'])
%}
{# create attributes for the search submit button by system variable #}
{%
  set submit_attributes = create_attribute(element.actions['submit']['#attributes'])
%}
<form{{ attributes }}>
  <label for="{{ input_attributes.id }}">{{ element.keys['#title'] }}</label>
  <input{{ input_attributes }} />
  <button{{ submit_attributes }}><span class="visually-hidden">{{  element.actions['submit']['#value'] }}</span></button>
</form>

```

also possible variants for submit:

```
<input{{ submit_attributes }} />
<button{{ submit_attributes }}>{{  element.actions['submit']['#value'] }}</button>

```
> 1 votes

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


# Question
Title: Show content whose "team" field matches the user "team" field
The users on my site all have a field named "team" and my content types also have the same field.

I want to create a views page that shows all nodes where that "team" field equals the same field on the user node.

Example:

**USERS:**

```
user1, team: team1
user2, team: team1
user3, team: team2

```

**NODES:**

```
node1, team: team2
node2, team: team1
node3, team: team1

```

When I'm logged in as user 3, I want my view to show node 1.

I know that I have to work with the contextual filters and context but I'm unable to get the output I need.

# Answer
The easiest way to set this up is through the **Content: Has taxonomy term ID** Contextual filter.

1. In Content Views listing your nodes add that Contextual filter and set it up:
`When the filter value is NOT available`
**Provide default value**
**Taxonomy term ID from URL**
**Load default filter from node page, that's good for related taxonomy blocks**
**Filter to items that share any term**
`When the filter value IS available or a default is provided`
**Specify validation criteria**
**Taxonomy term**
**\[your vocabulary\]**
**Term ID**
Adjust the other option as necessary.

Now if you enter some taxonomy term ID into the Views Preview field, it will be picked up by the Contextual filter and show only nodes that have been tagged with that term.
2. Create a block Display and place your block in a region shown on entities that have the taxonomy term ID chosen. The block will show all nodes that share the term.

In your case if you place that block on User Profile pages, it will show the nodes related through the same Taxonomy term.

---

If you want to show that Block anywhere on the site, and have it take the Context of the currently logged in user you have to approach it a bit differently.

There may be more ways on how to achieve this, here's one:

1. In the original Views where you show a list of nodes add a Relationship for the Taxonomy term field (**Field: Team**).
2. Then add another Relationship that is reverse, going from Taxonomy term to the field on Users (**Taxonomy term: User using …**). This is where the term matching is done, the second Relationship will use the first one. This introduces the User info into your content Views.
3. Then add the Contextual filter for User ID (**User Uid**), it will use the second Relationship. Set up the Contextual to use the logged in user context: `When the filter value is NOT available`
**Provide default value**
**User ID from logged in user**
`When the filter value IS available or a default is provided`
**Specify validation criteria**
**User ID**
**Single ID**
4. Place the Block anywhere on the site and it will only show nodes related to the user that is currently logged in, even if you place it on user profiles and view other users profiles!
> 2 votes

---
Tags: 7, views
---


title: Adding a link to an image

text:
# Question
Title: Adding a link to an image
Is there a module or a way in core to have an Image field be a clickable link to a URL that is either entered as an additional setting for the Image field or can be pulled from another field that stores that URL.

This https://www.drupal.org/project/linked\_field looks like what I want, but there doesn't seem to be a token that I can use that will do what I want.

This also looks exactly like I want but it's for D7. https://www.drupal.org/project/linkimagefield

I'm using this for a Custom Field Type

# Answer
> 0 votes
Now (perhaps it was not the case back in the days...) https://www.drupal.org/project/linked\_field allows you to link your image directly to the content links fields without using tokens

# Answer
> 2 votes
If you are already building a custom field type, you could add properties for the link to your field:

```
class MyLinkField extends FieldItemBase {

  public static function propertyDefinitions(StorageDefinition $storage) {
    ...
    $properties['title'] = DataDefinition::create('string')
      ->setLabel(t('Title'));
    $properties['url'] = DataDefinition::create('string')
      ->setLabel(t('URL'));
  }

```

and use it in the field formatter:

```
class MyLinkFieldFormatter extends FormatterBase {

  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];
    foreach ($items as $delta => $item) {
      $elements[$delta] = [
        '#type' => 'link',
        '#title' => $item->title,
        '#url' => Url::fromUri($item->url),
      ];
    }
  return $elements;
  }

```

# Answer
> 0 votes
You could create a template file for your content type.

**node--\[type-name\].html.twig**

`<a href="{{ content.field_url }}"> {{ content.field_image }} </a>`

---
Tags: 8, navigation, media
---


# Question
Title: How can I create an alias to point to an uploaded file?
Users uploading a file within content create a name like my\_site.com/sites/default/files/import/CrazyLongNamefile.pdf They would like to alias it for referencing in other media (print) like my\_site.com/GoodName.pdf

URL alias works fine for other things, but not files (that I can determine)

The File (Field) module looks like it would probably do what I want, but it hasn't been touched for Drupal 8 in a while.

Is there a way (module, custom code) to provide an alternative path to a file that I can make available to content creators?

# Answer
> 1 votes
I agree with Clive and base oh his comment, to redirect all files to another route you can use `.htaccess` route direction. So,

**first solution:** add to following line in your `.htaccess` file.

```
RewriteRule ^sites/default/files/(.*)$ /files/$1 [L,NC]

```

**note:** you can use whatever you want instead of `files`, like `assets` etc.

**PS:** if your files are Media types, with `pathauto` module you can create a pattern to redirect them additionally you can let the user override them the what path he wants.

**second solution:** install https://www.drupal.org/project/file\_entity module and then with `pathauto` module you can create an alias for files. like `files/file-title`.

**third-solution**: use https://www.drupal.org/project/path\_file module

> The Path File module allows content editors to upload files and specify the url at which they will be available. Normally, when uploading a file to Drupal with the same name as an existing file, it is given a new name instead of overwriting the existing file. This can problematic when file urls are referenced in content, menus, etc but may need to be updated in the future. The Path File module allows you to mitigate the impact of those changes by setting up a canonical url alias which will always point to the most up-to-date file

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


# Question
Title: Why am I not seeing CKEditor buttons on prod?
Okay, so I configured the Full HTML text format and added some buttons to CKEditor locally in a Lando environment. Then I exported the configuration with `drush cex`, committed it, pulled and imported on production with `drush cim`. However, even though changes can be seen in `admin/config/content/formats/full_html`, buttons aren't there when creating content. Any ideas? I also cleared caches. I even changed permissions on `sites/default`recursively to 777 before clearing caches through the UI.

# Answer
Which version of Drupal are you running?

Since the new button appears in `admin/config/content/formats/full_html` I guess the Config Import/Export worked but the connection between the new config and the CKEditor in the content didn't update?

I will try that on my setup since im working with drush cex and drush cim regularly.
> 0 votes

---
Tags: 8, wysiwyg
---


# Question
Title: Display an image from an external database
I created new image database on localhost (other than Drupal original database) that has images in one column. Then I installed the *Views Database Connector* module; I could integrate it with Drupal to display the content of the new image database. I can easily see columns like name, email, phone number stored in this new image database as string of characters, which are all text columns. When it comes to display an image from the external database, I am stuck.

I tried saving images in two formats.

* As URL linked to the path of the image file
* As a BLOB

In the first case, I see the URL; in the second case, I see a string of characters.

How do I make the Views module understand that this field is an image it should display as image and not as text?

# Answer
> 1 votes
Views fields have an option to overwrite the output of the field. You can use this to add any html you want, using twig. You'll have all fields rendered before your field available as twig variables.

In your case, since you know that you're getting an image url from your external database, you can rewrite the output of your field using twig. For example:

```
<img src='{{ my_image_url }}' alt='{{ "Alt text for my image"|t }}'>

```

To access the *Rewrite Results* option, click Edit on your field in the Views UI. Near the bottom of the dialog, you'll see several collapsed fieldsets. Open the *Rewrite Results* fieldset and check the box for *Override the output of this field with custom text*. You'll get a text area and another fieldset, *Replacement Patterns*, below it that lists all variables available for your rewrite. Find your field name for your image url and write your output similar to the snippet above.

---
Tags: views
---


# Question
Title: How do I display an array of entities from a controller?
I am new on Drupal 8 , so i have created a service class which return a list of data, 'articles' (node entities), and I call this service class inside a controller, but no data showing up :

**My *getArticles()* method inside my service:**

```
  public function getArticles(){
    $storage = \Drupal::service('entity_type.manager')->getStorage('node');
    $my_entity_ids = $storage->getQuery()
      ->condition('type', 'article')
      ->condition('status', 1)
      ->execute();
    $my_entities = $storage->loadMultiple($my_entity_ids);
    return $my_entities;
  }

```

**My controller:**

```
public function myPage() {
    $data = \Drupal::service('mymodule.service');
    $dataService = $data->getArticles();
    return $dataService;
  }

```

My result is a blank white page when I view the path routed to my controller, but I see the following message in my error log:

> Recoverable fatal error : Object of class Drupal\node\Entity\Node could not be converted to string dans Drupal\Component\Utility\Xss::filter()'' -----"Warning : strlen() expects parameter 1 to be string, array given dans Drupal\Component\Utility\Unicode::validateUtf8()

Can anyone tell me please why i can't get the articles?

# Answer
Controllers need to return a render array. Let's imagine you process your articles for render in a new method *renderMyPage()* which you call from *myPage()* and pass your array of article objects.

If you're displaying multiple fields from the articles, you're best off building and configuring a view mode and then getting the view mode render array as described in this answer.

```
function renderMyPage($articleObjects) {
  $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');

  $articles = [];
  foreach ($articleObjects as $article) {
    $articles[] = $view_builder->view($article, 'my_view_mode_machine_name');
  }

  return $articles;
}

```

If you want to render a single field from your article, you can get the render array for a field as described in this answer.

```
function renderMyPage($articleObjects) {
  $articles = [];
  foreach ($articleObjects as $article) {
    // You can pass a view_mode machine name or
    // an array of field configurations to view().
    $articles[] = $article->title->view();
  }

  return $articles;
}

```

Alternatively you can build your own render array, say to render the title as an h2.

```
function renderMyPage($articleObjects) {
  $articles = [];
  foreach ($articleObjects as $article) {
    $articles[] = [
      '#type' => 'html_tag',
      '#html_tag' => 'h2',
      '#value' => $article->title->value,
      // The other methods add cache tags automatically, but we need to add
      // cache tags manually here since we're building the array from scratch.
      '#cache' => [
        'tags' => $article->getCacheTags(),
      ],
    ];
  }

  return $articles;
}

```

Each of these examples returns an `$articles` array of renderable contents suitable as a return value from your *myPage()* method.
> 3 votes

---
Tags: 8, entities
---


title: Custom POST request

text:
# Question
Title: Custom POST request
I am very new to Drupal. My project requires me to create a custom module. I am working with Headless Drupal and I want to make a POST request. I cannot pass the POSTMAN Body to my Request argument in my custom POST request.

This is my routing.yml file

```
dashboardmodule.post:
 path: '/dashboardmodule/post'
 defaults: { _controller: '\Drupal\dashboardmodule\Controller\ApiController::post' }
 methods:  'POST'
 requirements:
  _access: 'TRUE'

```

This is what I have tried in my Controller -

```
  public function post(Request $request) {
   if ( strpos( $request->headers->get( 'Content-Type' ), 'application/json' )  ===  0) {
    $data = json_decode( $request->getContent(), TRUE );
    $request->request->replace( is_array( $data ) ? $data : [] );
   }

  $response['message'] = 'Post request successful';
  $response['body'] = $request;
  return new JsonResponse( $response );
 }

```

In POSTMAN, I have Content-Type and X-CSRF-Token Header and I have a request body. How to successfully pass that data into my post method? Am I missing something? Any help would be appreciated!

# Answer
> 1 votes
you can get all the posted variables by

```
\Drupal::request()->request->all()

```

and additional you can get single value by

```
$name = \Drupal::request()->request->get('name'); // form param

```

and if you send `Content-Type: application/json` you can get them by

```
$post_data = json_decode( $this->request->getContent(),TRUE);

```

**Note:** if you have a headless Drupal , you can implement your custom REST or JsonApi plugin that naturally created for this. take a look at Building REST Endpoints with Drupal 8

a simple sample of REST plugin resources to encourage you to use them later.

```
<?php

namespace Drupal\my_module\Plugin\rest\resource;

use Drupal\rest\ModifiedResourceResponse;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\user\Entity\User;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * Provides a resource to get view modes by entity and bundle.
 *
 * @RestResource(
 *   id = "user_reset_password_resource",
 *   label = @Translation("User reset password resource"),
 *   uri_paths = {
 *     "create" = "/api/v1/user/reset-password"
 *   }
 * )
 */
class UserResetPasswordResource extends ResourceBase
{

  /**
   * A current user instance.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
  {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    $instance->currentUser = $container->get('current_user');
    return $instance;
  }

  /**
   * Responds to POST requests.
   *
   * @param mixed $data
   *
   * @return \Drupal\rest\ModifiedResourceResponse
   *   The HTTP response object.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   *   Throws exception expected.
   */
  public function post($data)
  {

    if ($this->currentUser->isAnonymous()) {
      throw new AccessDeniedHttpException("you're not logged in!");
    }
    // Load user by their user ID.
    $user = User::load($this->currentUser->id());
    // Set the new password.
    $user->setPassword($data['password']);
    // Save the user.
    $user->save();

    return new ModifiedResourceResponse(['Success!'], 200);
  }
}

```

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


# Question
Title: Is there a way to create a list of Vocabulary (Replicate this page: /admin/structure/taxonomy)
I have created a custom layout and in that i want to show the content of this page -\> `/admin/structure/taxonomy`.

Please suggest if there is any way out.

Thanks

# Answer
> 1 votes
See the docs on how to Create a custom page which calls a controller.

In the callback method put `$vocabularies = $this->entityTypeManager()->getStorage('taxonomy_vocabulary')->loadMultiple();` to get all vocabularies.

Then use a `foreach` construct to add all vocabulary labels to a render array, for example an item list.

```
$items = [];
/** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
$vocabularies = $this->entityTypeManager()->getStorage('taxonomy_vocabulary')->loadMultiple();
foreach ($vocabularies as $vocabulary) {
  $items[] = $vocabulary->label();
}
$content = [
  '#theme' => 'item_list',
  '#list_type' => 'ul',
  '#title' => 'My List',
  '#items' => $items,
  '#attributes' => ['class' => 'mylist'],
  '#wrapper_attributes' => ['class' => 'container'],
];

```

---
Tags: taxonomy-terms
---


# Question
Title: How to ensure successful update after system failure during updb causing the site to remain in maintenance mode?
Running drush updb to upgrade drupal core or other modules, puts the site in maintenance mode. I recently faced an issue (probably an edge case) where the site was stuck in maintenance mode after running updb in a pipeline of a containerized infrastructure. Here is the sequence of events:

1. Run drush updb -y
2. Container terminated (system failure or unknown reason)
3. Re-attempt at drush updb
4. drupal returns "no updates were required" (this tells me that the step 1 may have completed the update in the background?"
5. Site remains in maintenance mode.
6. I manually bring the site back online.

After all this it looked like the update was successful.

How do I ensure the integrity of the system when this happens without restoring a backup and running the updates again? When running subsequent drush updb that says "no updates required" does this guarantee the previous updates were successful.

# Answer
> When running subsequent drush updb that says "no updates required" does this guarantee the previous updates were successful.

When Drush queues up batch items to be processed for `drush updb`, it adds these operations:

* Any module schema updates
* Any entity definition updates (off by default, not supported after 8.7)
* A cache clear & post hook update functions (on by default)
* Toggle off maintenance mode (if it not already enabled)

If the only updates were module schema updates then you ***might*** be in a scenario where things are ok; there are no post-update hooks needed (e.g. some batch data ops following a schema change) and only the last step of toggling off maintenance mode didn't complete.

> How do I ensure the integrity of the system when this happens without restoring a backup and running the updates again?

You'd have to audit the list of updated modules to double-check each schema update was applied and there were no post-update hooks missed in the update.

Depending on your update scenario this may or may not be easy, hence the best practice is doing a DB rollback and re-applying updates to ensure data integrity when uncertain.
> 0 votes

---
Tags: 8, drush, updating
---


# Question
Title: How can I render more than one field value in the controller?
in my case i have a controller that it send for me the title , to the view , but i want to send the tittle and the body of the article both , i have tried to send them from the controller but it doesn't work for me

how can i send them both from the controller (title and body) ?

> here is tmy controller

```
 public function myPage() {
    $data = \Drupal::service('myservice.ran');
    $dataService = $data->getArticles();
    return $this->renderMyPage($dataService);
  }
  function renderMyPage($articleObjects) {
    $articles = [];
    foreach ($articleObjects as $article) {
      $articles[] = [
        '#type' => 'html_tag',
        '#html_tag' => 'h2',
        '#value' => [$article->title->value,$article->body->value],
        '#cache' => [
          'tags' => $article->getCacheTags(),
        ],
      ];
    }
    return $articles;
  }

```

# Answer
What I suggest is the this solution, create a custom template, for your page, in controller pass the data to the twig template.

```
public function myPage() {

    $data = \Drupal::service('myservice.ran');
    $dataService = $data->getArticles();
    $articles = [];
    foreach ($dataService as $article) {
      $articles[] = [
        'title' => $article->title->value,
        'body' => $article->body->value,
      ];
    }
    $build = [
      '#theme' => 'my_template',
      '#data' => [
        'articles' => $articles,
        'whatelse' => "what esle I want"
      ],
      '#cache' => ['max-age' => 0],
    ];
    $output = \Drupal::service('renderer')->renderRoot($build);
    $response = new Response();
    $response->setContent($output);
    return $response;
  }

```

then all the data will be available on `data` in your custom twig template. ( you can change its name to whatever you want).

just be sure you clear the cache when you create your custom template.

A helper article
> 2 votes

---
Tags: page-controller
---


# Question
Title: How do I fix these requirement conflicts?
While updating through composer, I am getting an error from the Webform module. Drupal version 8.9.1 updated. How do I resolve this error?

```
Problem 1
    - drupal/webform_node 5.15.0 requires drupal/webform 5.15.0 -> satisfiable by drupal/webform[5.15.0] but these conflict with your requirements or minimum-stability.
    - drupal/webform_node 5.15.0 requires drupal/webform 5.15.0 -> satisfiable by drupal/webform[5.15.0] but these conflict with your requirements or minimum-stability.
    - drupal/webform_node 5.15.0 requires drupal/webform 5.15.0 -> satisfiable by drupal/webform[5.15.0] but these conflict with your requirements or minimum-stability.
    - Installation request for drupal/webform_node (locked at 5.15.0) -> satisfiable by drupal/webform_node[5.15.0].

```

# Answer
`drupal/webform 5.15.0` seems to be locked below the `v5.15.0` and thus blocking the `drupal\webform_node` update.

* check if you have an explicit version number in your `composer.json` that conflicts with the desired version
* On several occasions, I unblocked such situation by removing the `docroot/vendor` directory followed by a `composer install` command (and removing the `composer.lock` file if a new conflict arised)

`composer.json` is a list of modules with version constraints that is user-defined. `composer.lock` is the list of currently installed modules generated by `composer install`. If `composer.lock` is present, the list of resolved dependencies will be installed if you do `composer install`. This allow to define and deploy a set of resolved dependencies. `composer update` will resolve the dependencies again and update `composer.lock` (thus the update). From my experience, it could happen that you have unresolved conflict between explicit version definition in `composer.json` and the `composer.lock`. So you could get rid of it, and also the whole vendor directory, and do a composer install from scratch again. If the installation fails again, it must be from a human-generated `composer.json` conflict.
> 1 votes

# Answer
This conflict has beeen resolved using the following command.

```
composer update --with-dependencies

```
> 1 votes

---
Tags: 8, webforms, composer
---


# Question
Title: how to configure drupal settings to be available to visualize the available variables?
how must drupal local settings be configured to display available variables using IDEs or other tools ?

I guess this is xdebug and phpstorm but i don't know how to configure it if i don't have full admin access to the server.

# Answer
You can use kint which will print you all the variables

https://www.webwash.net/how-to-print-variables-using-kint-in-drupal-8/

or dpm (in devel module)

https://www.drupal.org/docs/contributed-modules/devel/dpm-and-other-devel-functions
> 0 votes

---
Tags: configuration
---


# Question
Title: How to add a translation to an existing node/entity using REST?
I have a headless Drupal 8 and want to create a translation for an existing NODE using a POST request but cannot figure how to.

I know how to create, edit and delete a node but am unsure on how to add a translation to an existing node. If I add the langcode it creates a new node in that specified language but I want a translation for an existing node ID.

Please advise.

# Answer
> 0 votes
You have to load the node first and than addTranslation. You can check if exists or not. This way I was able to do it.

```
    $transNode = Node::load($nid);
    $transNode = $transNode->addTranslation("en");
    $transNode->title = $title_EN;
    $transNode->body= $body_EN;
    $transNode->field_1 = $field_1_EN;
    $transNode->save();

```

---
Tags: 8
---


title: Translate path controller

text:
# Question
Title: Translate path controller
I have the following path defined in my routing.yml:

```
path: '/department/{department_node}/qualifications/{qualification_id}'

```

I need to translate that route into other languages, for example into Spanish:

```
path: '/departamento/{department_node}/titulaciones/{qualification_id}'

```

**department\_node** would be a "department" node

**qualification\_id** would be a dynamic id from a web service

So the result should be:

```
en: /department/department-title/qualifications/99
es: /departamento/department-title/titulaciones/99

```

As the qualification\_id is a dynamic value, I can't create an alias, as I would have many after a while and they would be out of date. Does anyone know any method of translating the routes in this case?

# Answer
Routes != URLs, you can't translate a route, you only can translate URL aliases.

One route has only one path, which - through optional wildcards - could match more than one URL. Because no single part in your desired URLs is stable, you can't do this with one route. (And AFAIK the first `/part/` of a route path must be constant too in Drupal, it cannot start with a wildcard.)

An URL alias is an optional, separate entity that matches an arbitrary URL to an existing route.

You either have to dynamically create/update URL aliases, or add new route only for the spanish translation. But it is allowed to reuse the same controller for multiple routes, so overhead would only be a single entry in a `routing.yml` file.
> 2 votes

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


# Question
Title: Kernel tests: Url toString with language option
In a Kernel test I need to test the result of an url object per language. But the test doesn't consider the language settings.

Example:

```
public function register(ContainerBuilder $container) {
    parent::register($container);

    $language = Language::$defaultValues;
    $language['id'] = 'de';
    $language['name'] = 'German';
    $container->setParameter('language.default_values', $language);
}

protected function setUp() {
    parent::setUp();

    ConfigurableLanguage::createFromLangcode('fr')->save();
    ConfigurableLanguage::createFromLangcode('it')->save();
}

public function testUrls() {
    $languageManager = $this->container->get('language_manager');
    print_r($languageManager->getLanguages());

    $url = Url::fromRoute('<front>');
    $url->setOption('language', $languageManager->getLanguage('fr'));
    print_r($url->toString());
}

```

Output:

```
Array
(
    [de]
    [fr]
    [it]
)

# Output of toString()
/

```

The output of toString should be `/fr` instead of `/`

Addendum: I discovered that the `\Drupal\language\HttpKernel\PathProcessorLanguage` outbound processor is missing, when `UrlGenerator::processPath()` is called from the Kernel test. Therefore, I registered it in the Kernel test's register method, but that doesn't solve the problem.

# Answer
> 0 votes
## Solution

I could solve it by register the `PathProcessorLanguage` class and add the `language.types` and `language.negotiation` config.

```
public function register(ContainerBuilder $container) {
  parent::register($container);

  // Define the default language.
  $language = Language::$defaultValues;
  $language['id'] = 'de';
  $language['name'] = 'German';
  $container->setParameter('language.default_values', $language);

  // Register PathProcessorLanguage.
  $container->register('path_processor_language', PathProcessorLanguage::class)
    ->addTag('path_processor_outbound', ['priority' => 100])
    ->addArgument(new Reference('config.factory'))
    ->addArgument(new Reference('language_manager'))
    ->addArgument(new Reference('language_negotiator'))
    ->addArgument(new Reference('current_user'))
    ->addArgument(new Reference('language.config_subscriber'));
}

protected function setUp() {
  parent::setUp();

  // Add additional languages.
  ConfigurableLanguage::createFromLangcode('fr')->save();
  ConfigurableLanguage::createFromLangcode('it')->save();

  // Define language settings.
  $this->config('language.types')->setData([
    'configurable' => ['language_interface'],
    'negotiation' => [
      'language_interface' => [
        'enabled' => [
          LanguageNegotiationUrl::METHOD_ID => 0,
        ],
      ],
    ],
  ])->save();

  $languageKeys = array_keys($this->container->get('language_manager')->getLanguages());
  $this->config('language.negotiation')->setData([
    'url' => [
      'source' => LanguageNegotiationUrl::CONFIG_PATH_PREFIX,
      'prefixes' => array_combine($languageKeys, $languageKeys),
    ],
  ])->save();
}

```

## Addition

If you want to use/test path alias configs too, just register the `AliasPathProcessor` class...

```
public function register(ContainerBuilder $container) {
  parent::register($container);

  // ...

  $container->register('path_alias.path_processor', AliasPathProcessor::class)
      ->addTag('path_processor_outbound', ['priority' => 300])
      ->addArgument(new Reference('path_alias.manager'));

  //...
}

```

... and add the path alias entry for the specific language.

```
protected function setUp() {
  parent::setUp();

  // ...

  $pathAlias = PathAlias::create([
      'path' => '/foo',
      'alias' => '/bar',
      'langcode' => 'it',
    ]);
    $pathAlias->save();

  // ...
}

```

---
Tags: testing
---


# Question
Title: LogicException : The controller must return a response (success ! given)
i have a service that return for me true in the node (article) successfully create and false if something wrong , but in the controller i am getting this error **'LogicException : The controller must return a response (success ! given). dans Symfony\Component\HttpKernel\HttpKernel-\>handleRaw() (ligne 169 de /var/www/html/vendor/symfony/http-kernel/HttpKernel.php).'**

can anyone tell me where is the problem in the controller return of my code please ?

> service

```
 public function createArticle()
  {
    $node = Node::create(array(
      'type' => 'article custom',
      'title' => 'article custom',
      'langcode' => 'fr',
      'uid' => '1',
      'status' => 1,
      'field_fields' => array(),
    ));
    $node->save();
    if($node)
      return true;
    else
      return false;
  }

```

> the controller methode

```
 public function myPageCreate()
  {
    $service = \Drupal::service('mymodule.ran');
    $createnode = $service->createArticle();
    if($createnode)
      return 'success !';
    else
      return 'somthing wrong !';
  }

```

# Answer
> 0 votes
A controller must provide a response, but drupal has extended the response handling to look for render arrays, that are then used the generate a response with the rendered html. If you don't provide a render array, then there is no response and then this error message will come up.

---
Tags: page-controller
---


# Question
Title: SMTP Error: Could not connect to SMTP host
We have a new Drupal 8 site and are having issues with the SMTP module. The account we are using to send email works successfully on our Drupal 7 sites and in other cases, but we cannot get it to work successfully on Drupal 8. I have also tried another Non-SSL account and am getting the same two messages over and over in the error log.

> Error sending e-mail from smtp@website.com to email@email.com: SMTP Error: Could not connect to SMTP host.
>
> Error sending email (from smtp@website.com to email@email.com with reply-to not set).

I have found many similar questions, but not a working solution yet. Any help would be greatly appreciated, thank you in advance!

# Answer
> 1 votes
Doh! It turns out this was not a Drupal issue, but a Centos issue with SELinux. I was able to check SELinx settings by running the following commands

> getsebool httpd\_can\_sendmail

which returned

> httpd\_can\_sendmail --\> off

and

> getsebool httpd\_can\_network\_connect

returned

> httpd\_can\_network\_connect --\> off

I enabled them by running this

> setsebool -P httpd\_can\_sendmail 1
>
> setsebool -P httpd\_can\_network\_connect 1

And the Drupal SMTP module worked beautifully after that. Hopefully this helps someone else as well.

# Answer
> 0 votes
For Drupal 8 Install PHPMailer and SMTP: Go to the root of your Drupal 8 project and execute below to install and enable smtp module from Admin interface or via drush

```
composer require phpmailer/phpmailer
composer require drupal/smtp

```

Configure SMTP at: /admin/config/system/smtp

INSTALL OPTIONS

```
Set SMTP as the default mailsystem

On
When on, all mail is passed through the SMTP module.

```

SMTP SERVER SETTINGS

SMTP server

```
smtp.host.name
The address of your outgoing SMTP server.

```

SMTP backup server

The address of your outgoing SMTP backup server. If the primary server can't be found this one will be tried. This is optional.

SMTP port

```
25
The default SMTP port is 25, if that is being blocked try 80. Gmail uses 465. See
http://gmail.google.com/support/bin/answer.py?answer=13287 for more information on
configuring for use with Gmail.

```

Use encrypted protocol

```
No
This allows connection to an SMTP server that requires SSL encryption such as Gmail.

```

Enable TLS encryption automatically

```
On
Whether to enable TLS encryption automatically if a server supports it, even if the
protocol is not set to "tls".

```

Timeout

```
60
Amount of seconds for the SMTP commands to timeout.

Turn on the SMTP keep alive feature
Enabling this option will keep the SMTP connection open instead of it being openned
and then closed for each mail

```

SMTP AUTHENTICATION

Leave blank if your SMTP server does not require authentication.

Username

SMTP Username.

Password

SMTP password.

If you have already entered your password before, you should leave this field blank, unless you want to change the stored password. Please note that this password will be stored as plain-text inside Drupal's core configuration variables.

E-MAIL OPTIONS

```
E-mail from address
The e-mail address that all e-mails will be from.

E-mail from name
The name that all e-mails will be from. If left blank will use a default of: Portal
Name . Some providers (such as Office365) may ignore this field. For more
information, please check SMTP module documentation and your email provider
documentation.

```

Allow to send e-mails formatted as HTML

```
Checking this box will allow HTML formatted e-mails to be sent with the SMTP protocol.

```

SMTP CLIENT SETTINGS

Hostname

```
noreply@domain.com
The hostname to use in the Message-Id and Received headers, and as the default HELO
string. Leave blank for using _.

```

HELO

```
Test
The SMTP HELO/EHLO of the message. Defaults to hostname (see above).

```

SEND TEST E-MAIL

```
E-mail address to send a test e-mail to
Type in an address to have a test e-mail sent there.

```

Enable debugging

Checking this box will print SMTP message

Enabling Debugging will help know the SMTP isssues, check the project page for other error refrences: https://www.drupal.org/project/smtp

---
Tags: 8, emails
---


# Question
Title: Dynamically add destination fields to migration - importing data when fields on destination entity are not know
I am trying to import content from JSON from an API call. This API call has different source data depending on what the call is.

For my migration from this JSON, there are set fields that I have coded into the YAML migration file under the process section. The issue I am running into is, some of the fields change, so I need a way to dynamically add these fields to the process section if they exists. Is this possible with Migration?

I think there must be some way to do if with derivers, but I am struggling at how to implement this.

Any insight would be greatly appreciated!

# Answer
> 0 votes
I think you could try to implement something similar https://www.webomelette.com/dynamic-migrations-using-templates-drupal-8. This is a good example of dynamic migration.

---
Tags: entities, migrations, importing-exporting, 8
---


# Question
Title: In the settings for payments, what is the meaning of "Test transactions in a live account"?
What actually happens if I complete a transaction with the payments setting on "Test transactions in a live account"?

The only documentation I see is language like "Under Transaction mode, make sure 'Test transactions in a live account' is selected for testing purposes."

However, I can find no description anywhere of how the software behaves differently in this "Test transactions in a live account" mode compared with the two other modes available.

Also, what is required to submit the checkout form for a "test transaction in a live account"? Does it have to be a real credit card number?

# Answer
The language used varies by payment gateway, but they almost all include some sort of development environment that is completely separate from the production environment. Some will also permit test transactions in the production environment itself by letting you turn on test mode and use a test credit card number that passes the "Luhn algorithm" used to validate card numbers but is not a real number.

As this varies by payment gateway, you're going to have to consult the payment gateway's documentation. In Drupal Commerce itself, how you configure this differs between Commerce 1.x and Commerce 2.x. Make sure you're viewing module documentation that matches the version of Commerce you're running.
> 1 votes

---
Tags: commerce
---


# Question
Title: entityCondition check if a field is not empty
My user table has an init field in it, it maybe empty or not. I want to find all rows that are not empty I tried

```
  $query = new EntityFieldQuery();
  $query
    ->entityCondition('entity_type', 'user')
    ->addTag('role_filter');

function mymodule_role_filter_alter(QueryAlterableInterface $query) {
  $query->innerJoin('users_roles', 'ur', 'users.uid = ur.uid');
  $query->innerJoin('role', 'r', 'r.rid = ur.rid');
  $query->condition('r.name', ['administrator', 'contributor', 'publisher'], 'IN');
  $query-> isNotNull(ur.init); // I ALSO TRIED a != '' condition
}

```

What I am doing now that works is:

```
  $results = $query->execute();

  $users_node_list = entity_load('user', array_keys($results['user']));

  $return_results = array();

  foreach ($users_node_list as $key => $value) {
        if ($value->init != ''){

```

but that is post query.

and read https://www.drupal.org/node/1157006

but this is not working (I don't get any results when I add this)

Ideas?

# Answer
You can do this by

```
$query->condition('field', '', '<>');

```

See: https://api.drupal.org/api/drupal/includes%21database%21select.inc/function/SelectQuery%3A%3Acondition/7.x

If this doesn't answer your question you need to. Be more specific.
> 13 votes

# Answer
In drupal 8, you can use the exists function like so :

```
$query = \Drupal::entityQuery('node');
$query->exists('field_x');
$results = $query->execute;

```
> 6 votes

---
Tags: database
---


title: Placing a programatically created menu

text:
# Question
Title: Placing a programatically created menu
I'm creating a menu programatically using this code

```
$this->menu = $this->entityTypeManager->getStorage('menu')->create(
    [
      'id' => $properties['id'],
      'label' => $properties['label'],
      'langcode' => $properties['language'],
      'status' => TRUE,
    ]
  );
  // Save the menu.
  $this->menu->save();

```

When visiting the block ui I see the block is already created. It appears that I do not have responsibility for creating this block, although I don't seem to be able to load the block straight after creation of the menu. I need to place this block in a specific region programatically. What would be the preferred method of doing this be?

# Answer
> 1 votes
After an intensive debug session I discovered the block is actually created when you place blocks and select the menu you have just created through the Block UI. That didn't fit with my requirements to place the block programatically so I took a look at the structure of an existing menu block and replicated that.

```
$this->block = $this->entityTypeManager->getStorage('block')->create(
    [
      'id' => $this->getBid($form_state->getValue('language')),
      'region' => 'header',
      'plugin' => 'system_menu_block:' . $this->menu->id(),
      'settings' => [
        'id' => 'system_menu_block:' . $this->menu->id(),
        'label' => $this->menu->label(),
        'provider' => 'system',
        'level' => 1,
        'depth' => 0,
        'expand_all_items' => FALSE,
      ],
      'theme' => 'mytheme_base_theme',
      'visibility' => [
        'language' => [
          'id' => 'language',
          'langcodes' => [
            $form_state->getValue('language') => $form_state->getValue('language'),
          ],
          'negate' => FALSE,
          'context_mapping' => [
            'language' => '@language.current_language_context:language_interface',
          ],
        ],
      ],
      'weight' => 100,
    ]
  );
  // Save the block.
  $this->block->save();

```

This achieved the result I was looking for. So far so good. I can now create menus and place them immediately after the menu is created.

---
Tags: blocks
---


# Question
Title: "recommended-project" installs drupal into the /web subdirectory, but hosting solution directs traffic to webroot
Per https://www.drupal.org/node/3082474 the preferred document template, drupal/recommended-project, uses a "relocated document root" for security purposes. HOWEVER, many cPanel driven hosting services mandate that the website user lands in the hosting site's public\_html web root directory. I can't make it work for a website vistor.

I have researched many ways to accommodate through the use of .htaccess files and settings.php; however, nothing I've tried actually works. For example, I can land on the page, but if I try to log-in, then it gets lost. Or /web shows up in the address bar. Or people write about security concerns that are worse than not doing the relocated document root in the first place. Or...

This solution is "STANDARD", so there must be a well-researched standard way for a web user to land on the public\_html, but be redirected SECURELY to the /web subdirectory.

UPDATE: this is the best solution that I have found and it seems to work safely, per https://www.drupal.org/project/drupal/issues/2612160#comment-11767977. I inserted this snippet at the bottom of /web/sites/default/settings.php file:

```
if (isset($GLOBALS['request']) and
'/web/index.php' === $GLOBALS['request']->server->get('SCRIPT_NAME')) {
$GLOBALS['request']->server->set('SCRIPT_NAME', '/index.php');
}

```

(with /web/ being the name of the subdirectory below the web root).

I also had to add this to my .htaccess file at the webroot, public\_html:

```
# https://www.inmotionhosting.com/support/domain-names/how-to-redirect-your-primary-domain-to-a-subdirectory/

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?domain_name.com$
RewriteCond %{REQUEST_URI} !^/web/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /web/$1
RewriteCond %{HTTP_HOST} ^(www.)?domain_name.com$
RewriteRule ^(/)?$ web/index.html [L]

```

(with /web/ being the name of the subdirectory below the web root). Substitute your domain\_name in the two places above).

# Answer
When you use the *drupal/recommended-project* template to create a Drupal project via Composer, you can use a different directory for the server document root.

Instead of running `composer create-project drupal/recommended-project my-project`, assuming that the document root directory is *public\_html*, you can:

* Run `composer create-project drupal/recommended-project my-project --no-installation`
* Edit the *composer.json* file found in the *my-project* directory to replace any occurrence of *web/* with *public\_html/*
* Inside the *my-project* directory run `composer install`
* Copy the content of the *my-project* directory (including any subdirectory) into the directory containing the server document root directory

This is described in Using Composer to Install Drupal and Manage Dependencies.

> If you want to modify some of the properties of the downloaded composer.json before `composer install` is executed, use the `--no-install` flag when running `composer create-project`. For example, it is possible that you want to rename the subdirectory 'web' to something else.
>
> To do that:
>
> 1. Run `composer create-project --no-install drupal/recommended-project my_site_name_dir`
> 2. Change directories to my\_site\_name\_dir and edit the composer.json file to suit your needs. For example, to change the sub-directory from 'web' to something else, the keys to modify are the 'extra' sub-keys 'webroot' and 'installer-paths'.
> 3. Run `composer install` to download Drupal 8 and all its dependencies.
> 2 votes

---
Tags: 8, installation
---


# Question
Title: Change sort order for view when exposed filter text field submitted
I have a view that by default is ordered by date. It has several exposed filters one of which is for filtering by text (we use it as a search field). I'd like the view sort to change to Relevance when a user submits a search but I also want to set it so it only does this once in case the user changes the sort order and then modified their search string. Is this possible? I'm using Better Exposed Filters, fwiw.

The view content source is "content datasource" from the drupal search api.

# Answer
> 0 votes
If you order your view by relevance first, then date, when there is no text entered all articles will be given the same relevance score, so this will achieve what you are after.

---
Tags: 8, views, search
---


# Question
Title: How can I export and then import taxonomy terms?
So I built my own custom entity type (we'll call it notes). And on my notes I have fields that use taxonomy terms, however when it comes to exporting the data out on individual fields, it shows the data, but when I restart the site and re-import everything, the taxonomy terms don't get imported with it.

Taxonomy terms is pretty important and a core with Drupal, so I don't understand why we can't export and import them easily like with the other data.

So I end up with fields that do not have taxonomy terms or is reported as missing.

Is there a way I can do this so when I import, the taxonomy terms get imported too?

# Answer
The line between config/content can be blurry since there are many use scenarios. Drupal assumes a default scenario where terms are user-edited content that's not part of the CMS configuration.

Taxonomy terms are content entities, unlike taxonomy vocabularies, which are config entities. Hence, the D8 configuration export/import will not work for taxonomy terms.

There are various modules that will let you import content (and thus taxonomy terms). Some are more general-purpose (e.g. the migration framework, the content sync module), others are specific to taxonomy (e.g. taxonomy import module). Research solutions and figure out what works best for your scenario.
> 2 votes

# Answer
Have a look at the YAML Content. Even if it is not covered by the Drupal Security, it may cover your current needs as it will help you exporting and importing your terms.
> 0 votes

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


# Question
Title: How can I theme the outgoing contact mail?
I want to theme the outgoing mail from the contact module, because the standard output looks horrible. Where can I do this? It's the one starting with admin (http://example.com/user/1) sent a message using the contact form at http://example.com/contact.

# Answer
I was able to get Berdir's answer working in Drupal 8.1.0. But I had to do a number of things to get it going.

1. Install mailsystem, swiftmailer, contact\_storage, and contact (core) modules
2. Setup a custom contact form, configure it and add fields as needed.
3. Configure swiftmailer message settings (`/admin/config/swiftmailer/messages`) to use HTML.
4. Configure swiftmailer transport settings (`/admin/config/swiftmailer/transport`) to preferred transport type
5. Configure mailsystem default mail system settings to use swiftmailer for both formatter and sender plugins. I assume you could also configure per module in the later section if you like, however I did not try it.
6. Under `/admin/structure/display-modes/view` add a new view mode for Contact message, setting it's namespace to `mail`. This is the view mode that will be used when sending the email (somewhere this is hardcoded from what I can tell).
7. If you want a pretty display of the Contact message nodes on the site then you will also want to create a `full` view mode and configure that too.
8. Configure your view modes under the custom contact form you created. The Display Suite module really allowed for customizing the markup with it's field templates made available in display suite extras.

***Note, I also have Berdir's MessageViewBuilder override in a custom module but I am unsure it is any longer necessary. I have not attempted to remove it yet.***
> 5 votes

# Answer
I'd recommend Swiftmailer to send HTML mails in 8.x.

But for contact forms, a number of core issues/limitations currently prevent that from working nicely. See https://www.drupal.org/node/2666160 (patch needed, or use of D8 core 8.1.0+) and https://www.drupal.org/node/2223967 (workaround needed/possibly by replacing the contact message view builder and setting the content type of contact mails to HTML), something like this:

```
/**
 * Implements hook_entity_type_alter().
 * @param \Drupal\Core\Entity\EntityTypeInterface[] $entity_types
 */
function yourmodule_entity_type_alter(array &$entity_types) {
  $entity_types['contact_message']->setViewBuilderClass('Drupal\yourmoule\ContactMessageViewBuilder');
}

/**
 * Implements hook_mail_alter().
 */
function yourmodule_mail_alter(&$message) {
  if ($message['module'] == 'contact' && isset($message['params']['contact_message'])) {
    // Enforce that we are sending mails as HTML.
    $message['headers']['Content-Type'] = 'text/html';
  }
}

namespace Drupal\yourmodule;

use Drupal\contact\MessageViewBuilder;
use Drupal\Core\Entity\EntityInterface;

/**
 * Customized contact message view that does not do HTML to plain conversion.
 */
class ContactMessageViewBuilder extends MessageViewBuilder {

  /**
   * {@inheritdoc}
   */
  public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
    $build = parent::view($entity, $view_mode, $langcode);
    // Remove the post render callback that converts the HTML to plain text.
    unset($build['#post_render']);
    return $build;
  }
}

```
> 2 votes

# Answer
For theming the outgoing contact mail you can get a node and its body. After that you can set it as mail body. Use `hook_mail_alter()`. This requires the Swift Mailer module.

```
use Drupal\Core\Render\Markup;

function hook_mail_alter(&$message) {

  if ($message['id'] == 'contact_page_mail') {

    $contact_message = $message['params']['contact_message'];

    //load the node that has html body
    $node   = \Drupal\node\Entity\Node::load(155);
    $record = $node->body->value;

    //replace the params as per you requirement
    $record = str_replace("@name", $contact_message->get('field_name')->getValue()[0]['value'], $record);

    $message['body'][1] = $record;
    $message['body'][1] = Markup::create($message['body'][1]);
  }
}

```
> 2 votes

# Answer
Sounds like you need the Mime Mail module first. It will allow your website to send HTML emails, and give you a way to change the template.
> 0 votes

# Answer
Just want to add to @nicholas.alipaz answer.
If you followed until point #8 and used dispaly-suit module.
Go to admin/structure/contact/manage/**YOURCONTACTFORM**/display/mail

scroll down to: 'Layout for **YOURCONTACTFORM** in mail'.
Under 'Select a layout' choose 'one column layout' you should be presented by tempalte suggestions.
Choose one of them. I chose ds-1col--contact-message.html.twig
I copied modules/contrib/ds/templates/ds-1col.html.twig in my theme's tempalte folder, renamed it ds-1col--contact-message.html.twig and editted it to my likings.
It's a bit simple email temaplate but it worked nicely for my simple contact form.
> 0 votes

# Answer
Drupal 8 with mailsystem, swiftmailer will not use the `swiftmailer.html.twig` for your outgoing contact mails. Resulting mail message is not easy to reade (nor theme )

You can get rid of the default message and send a brand new one via `\Drupal::service('plugin.manager.mail')`

This will let you send HTML formatted email as per your swiftmailer.html.twig

@TODO: give HTML to the actual message

Sample code

```
/**
 * implements hook_mail_alter()
 */
function YOUR_MODULE_mail_alter(&$message) {

  if (!empty($message['id']) ) {

    switch ($message['id']) {
      case 'contact_user_mail':

      // thanks to https://www.zyxware.com/articles/5504/drupal-8-how-to-send-a-mail-programmatically-in-drupal-8
      $options = Array();
      send_a_brand_new_mail($message, $options);

      // Instead of forwarding to dustbinm, how to destroy default contact message?
      $message['to'] = "somewhere@dustbin";
      break;
    }
  }
}

/**
 * Implements hook_mail().
 */
function YOUR_MODULE_mail($key, &$message, $params) {
  $options = array('langcode' => $message['langcode']);
  switch ($key) {
    case 'YOUR_KEY':
      $messaggio = $message['params']['contact_message']->get('message')->getValue(0);

      //re-use from contact.module
      $contact_message = $params['contact_message'];

      /** @var $sender \Drupal\user\UserInterface */
      $sender = $params['sender'];
      $language = \Drupal::languageManager()->getLanguage($message['langcode']);

      $variables = [
        '@site-name' => \Drupal::config('system.site')->get('name'),
        '@subject' => $contact_message->getSubject(),
        '@form-url' => Url::fromRoute('<current>', [], ['absolute' => TRUE, 'language' => $language])->toString(),
        '@sender-name' => $sender->getDisplayName(),
      ];

      $variables += [
        '@recipient-name' => $params['recipient']->getDisplayName(),
        '@recipient-edit-url' => $params['recipient']->toUrl('edit-form', ['absolute' => TRUE, 'language' => $language])->toString(),
      ];

      if ($sender->isAuthenticated()) {
        $variables['@sender-url'] = $sender->toUrl('canonical', ['absolute' => TRUE, 'language' => $language])->toString();
      }
      else {
        $variables['@sender-url'] = $params['sender']->getEmail();
      }
      $options = ['langcode' => $language->getId()];
      $message['subject'] .= $message['params']['title'] ;
      $message['body'][] = t('Hello @recipient-name,', $variables, $options) . "\r\n\r\n";
      $message['body'][] = t("@sender-name (@sender-url) sent a message using the contact form at @form-url.", $variables, $options);

      // you can at least add some blank rows here
      $message['body'][] = "\r\n\r\n";
      $message['body'][] = ">>>\r\n\r\n";
      $message['body'][] = Html::escape($messaggio[0]['value']);
      $message['body'][] = "<<<"."\r\n\r\n";
      break;
  }
}

function send_a_brand_new_mail($message, $options) {

  $mailManager = \Drupal::service('plugin.manager.mail');
  $module = 'YOUR_MODULE';
  $key = 'YOUR_KEY'; // Replace with Your key
  $to = \Drupal::currentUser()->getEmail();

  $params = $message['params'];
  $params['message'] = $params['contact_message'];
  $params['title']   = $message['subject'];
  $langcode = \Drupal::currentUser()->getPreferredLangcode();
  $send = true;
  $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
  if ($result['result'] != true) {
    $message = t('There was a problem sending your email notification to @email.', array('@email' => $to));
    drupal_set_message($message, 'error');
    \Drupal::logger('mail-log')->error($message);
    return;
  }

  $message = t('Your message was emailed to @email ', array('@email' => $to));
  drupal_set_message($message);
  \Drupal::logger('mail-log')->notice($message);
}

```
> 0 votes

---
Tags: 8, emails
---


# Question
Title: How to determine the route for the add node page of a custom entity type?
I have a node type **question** that I want users to be able to create rapidly. So, after adding a question, I want them to be redirected to `/node/add/question` to immediately do it again.

This is my code so far:

```
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case 'node_question_form':
      foreach (array_keys($form['actions']) as $action) {
        if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
          $form['actions'][$action]['#submit'][] = 'MYMODULE_node_form_submit';
        }
      }
      break;
  }
}

function MYMODULE_node_form_submit(array &$form, FormStateInterface &$form_state) {
  // https://drupal.stackexchange.com/a/250474/5147
  \Drupal::request()->query->remove('destination');
  $form_state->setRedirect('node.add_page');
}

```

This redirects to `/node/add`, but I want to redirect to `/node/add/question`. I tried digging through the route options in PHPStorm but I couldn't find anything that gets to the create page for a custom content type.

# Answer
You're looking for the `node.add` route, which has a `node_type` parameter.

```
$form_state->setRedirect('node.add', ['node_type' => 'question']);

```
> 1 votes

# Answer
You have to redirect to the "add page" of type question,replace

```
$form_state->setRedirect('node.add_page');

```

by

```
$form_state->setRedirect('node.add', ['node_type' => 'question']);

```
> 2 votes

---
Tags: routes
---


# Question
Title: Command to install Drupal 9 with Composer
The latest version of Drupal 8 can be installed via Composer with the following command:

```
composer create-project drupal/recommended-project mynewproject

```

What is the equivalent command to install the latest version of Drupal 9 (beta1)?

# Answer
`create-project` can take a version number, and recommended-project has some tags in for 9.x, so for example:

```
composer create-project drupal/recommended-project mynewproject "9.0-beta1"

```

Or if you just want the bleeding edge to play with:

```
composer create-project drupal/recommended-project mynewproject "^9.0" --stability=dev --prefer-dist

```
> 12 votes

# Answer
If you use `composer create-project drupal/recommended-project` it will now install D9
> 1 votes

---
Tags: composer, 9
---