# Question
Title: Use node edit form layout for other entity types
The node edit form got a nice overhaul for Drupal 8's default admin theme, whereby a lot of the metadata fields like Revisions, Meta Tags, URL Aliases, Publish status, Promote status, etc are moved into a sidebar.

I'm using the Group module, and have enabled metatag integration and revisions via patch from #2829966.

Currently however the meta tags and revisions appear in a vertical tabs block at the bottom of the edit form, making the page extra long.

How can I get those items into a sidebar like the Node edit form does?

# Answer
`Drupal\node\NodeForm` provides it own `build()` method that puts the meta items into an `advanced` group, and then the `classy` template `node-edit-form.html.twig` renders that group in a sidebar. The form builder also attaches the `node/drupal.node` library, which provides the layout CSS.

To copy this layout and style for another entity, you could implement `hook_form_alter` in a custom module and move the metadata form items into an `advanced` group like `NodeForm` does. You also need to theme the form with the `node_edit_form` template and attach the `node/drupal.node` library.

```
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  // Select the group add/edit form.
  if (in_array('group_form', $form['#theme'])) {
    // Use the node edit form template.
    $form['#theme'][] = 'node_edit_form';

    // Use the node form layout library.
    $form['#attached']['library'] = ['node/drupal.node'];

    // Create the advanced element if it doesn't exist.
    if (!isset($form['advanced'])) {
      $form['advanced'] = [
        '#type' => 'container',
        '#weight' => 99,
      ];
    }
    else {
      // Make 'advanced' a container instead of vertical_tabs.
      $form['advanced']['#type'] = 'container';
    }

    // Add the style class to tell the admin theme how to style it.
    $form['advanced']['#attributes']['class'][] = 'entity-meta';

    // Move detail elements into 'advanced'.
    $form['detail_element_you_want_to_move']['#group'] = 'advanced';
  }
}

```

Alternatively, you could create your own Twig template and library and use those instead of borrowing from `node`.
> 2 votes

---
Tags: 8, theming, group
---


# Question
Title: How to add attachment in views slideshow
Goal: Putting text as an attachment on views slideshow

Theme: Bootstrap

Drupal: 8

Content type: Slideshow which has two fields: image and text

Added two nodes of the content type.

Created a slideshow block using views and bootstrap carousel. Slideshow is working just fine. Slideshow just displays the image/slide field.

Below shows just the views block for slideshow.

Now, I like to put the text field as an attachment (putting the text on top of image in the slideshow) to the views block.

Views \> Add \> attachment \> after that I am lost. I am not sure what setting to use to put the corresponding text field on each image slide.

Below shows I added the attachment in view but when I visit my site, I only see image slideshow and I do not see the text (slide-img) on the slideshow as an attachment.

Please advise.

# Answer
> 2 votes
All you need to do is to add your text field to the "Fields" section of this view. Not as an attachment. As a field.

---
Tags: views
---


# Question
Title: Save contact form data in the database instead of transferring it to an email account
So far I had to set up email DNS records and an email server or, alternatively, an email proxy by an email account to transfer emails from a CMS to my email account.

1. Email DNS records and email server
Contact form inquiry → PHP `mail()` function → Postfix → SMTP → My email account
2. Email proxy
Contact form inquiry → PHP `mail()` function → Mail Transfer Agent (like `sSMTP`) → SMTP → Email proxy account → My email account

All I want to is to get leads (contact form inquiries) directly into Drupal in a secured way and to manage them from Drupal (in a rather simple way of *keep or delete*).

The advantages (mainly for freelance, single-administrator applications) are

1. Easier server and credentials management (No need to worry about securing credentials for an email proxy account.)
2. Fast email reply (by clicking on the email address of the inquirer from browser or from smartphone) and sending an email directly from your preferred email application in regular PC or smartphone

How could I "instruct" the core *Contact* module to save leads in Drupal itself and not transferring them to any email account? (I might need a third-party module for that, if it's not possible without customizing its PHP code.)

# Answer
> 3 votes
What you are asking for is the purpose of the Contact Storage module.

If you need further form elements, consider using the Webform module. It surely adds a whole lot of overhead, but gives you a wide variety of form elements and stores it's results in the database as well.

---
Tags: 8, emails
---


# Question
Title: Override twig template file from classy theme
I want to override `file-upload-help.html.twig` located in `core\themes\classy\templates\content-edit`. This template displays help text for file upload fields on node edit pages.

If I inspect the file upload help text on a page, above it I see (in debug mode):

`BEGIN OUTPUT from 'core/themes/classy/templates/content-edit/file-upload-help.html.twig'`

There is no `FILE NAME SUGGESTIONS` line before or after this line.

My site sub-themes the `bootstrap` theme.

I tried simply putting a `file-upload-help.html.twig` file in my sub-theme's `templates` folder, but it was ignored. Not surprising since I'm sub-theming bootstrap, not classy.

Is there a way to add more information to the `theme.info.yml` file to override classy templates as well? Or some other way to override the template? If I simply edit the `file-upload-help.html.twig` file within the classy theme folder, it works, but of course that's bad behavior.

# Answer
> 3 votes
As discovered through the comments discussion the answer in this case is to place the template into the admin subtheme (not the default theme).

When adding new templates to your subtheme it's important to be aware of the fact that there are usually two active themes in any Drupal site: the default one for "front-end" and an admin one for the "back-end" side.

There is also a part of the site that is ambiguous about whether it falls under "front-" or "back-end", and that is Editing content pages.

There is a setting under `Appearance` that controls which theme should be used for editing content. When adding a template for content-editing pages it's important to double-check which theme is chosen there to know which theme to add the template to.

As always, don't modify the contributed themes, instead add a subtheme that extends them and add the template there. Then adjust the `Appearance` settings to use the subtheme.

---
Tags: 8, theming
---


# Question
Title: Uploading file, parsing and displaying data
For a site i am building right now, there is one component that I would want the user to upload a file, where it will be parsed (currently a python script, but can be ported to something else). The data from the parser will then be used populate a node.

what will be the best way to go around doing this? rules to start the parsing and feeds to import the data? a custom php page? or a custom mod to generate the display i want from the file uploaded in the same node?

need some guidance \>,\<

# Answer
> 0 votes
I would create a new url where files can be uploaded. This is done with a implementation of hook\_menu.

If you want to use Feeds you first need to upload the file and have it converted to rss/csv/opml etc and then use Feeds to map against a node. I would go with a custom module instead so that you can create nodes straight away instead of a "two step operation".

You can find out how to create a form that handles file uploads here. In the submit function for your form you would need to programatically create nodes from the file upload. This can be done in several ways but one is by using Entity metadata wrappers, which I find easy to work with. You can find out more about that here.

This all might sound like a lot of work and I didn't suggest a contributed module but I think in your case it would be more work to first convert the data to something readable by Feeds for example.

# Answer
> 0 votes
What format is your uploaded file in? If it's something standard like csv, xml etc then I'd look at the feeds module https://www.drupal.org/project/feeds that's exactly what it's for, less chance of bugs/errors and less maintenance than building your own.

You should be able to parse non standard file types with it too, but as Pontus said you're adding an extra step.

# Answer
> 0 votes
Here is a custom rules action module that i use in a a site, it loads a XML file (mexican invoice file), parsers it and saves some data from file in a node, and returns a variable knowing if node data was saved or not in node. Take a close look how file and node are loaded in rules action, and how file is opened by uri and access it's content. Note: file was previously loaded by user and saved in a node, i'm affecting same node.

```
      <?php
  /**
   * Implement hook_rules_action_info()
   * Declare any meta data about actions for Rules
   */

  function procesarfactura_rules_action_info() {
    $actions = array(
      'procesar_factura_xml' => array(
          'label' => t('Procesar factura'),
          'group' => t('factura'),
          'parameter' => array(
              'file' => array(
                      'type' => 'file',
                      'label' => t('Archivo a procesar'),
                      ),
              'node' => array(
                  'type' => 'node',
                  'label' => t('Nodo a procesar'),
                  ),
          ),

          'provides' => array(
            'procesada' => array(
              'type' => 'integer',
              'label' => '1=procesada, 0=no procesada',
            ),
          ),
        ),
      );
        return $actions;
  } // fin de actions_info

  // rules function procesar factura
  function procesar_factura_xml($file, $node) {
    $procesada = array();
    $procesada = 0;

    $node = node_load($node->nid);
    $nidflagged = $node->nid;
    //dpm($node);
    //dpm($file);

    // get $url path to load $file
    $uri = $node->field_factura_xml['und'][0]['uri'];
    // Take a look at: file.inc::file_load_multiple
    $files = file_load_multiple(array(), array('uri' => $uri));
    $file = reset($files); // If empty, $file will be false, otherwise will contain the required file

     //unset($xml);
     $xml = null;
     $xml = simplexml_load_file($uri);

     //si no pudo subir la factura, mostrar error, unflag node
  if(!$xml) {
    drupal_set_message('Su archivo XML no fue cargado correctamante, favor de intentar nuevamente.', 'status', FALSE);
    drupal_set_message('Nota: despues de subir el archivo al servidor, haga clic en el nombre de su archivo,
    si se muestra en pantalla, ya esta cargado correctamente, navege hacia atras su navegador y procese su factura.', 'status', FALSE);

    $flag = flag_get_flag('flag_nodo_factura_cliente');
      if ($flag) {
        // Unflag node
        $flag->flag('unflag', $nidflagged);
      }
  }
  else {

    //var_dump($xml);
    $ns = $xml->getNamespaces(true);
    $xml->registerXPathNamespace('c', $ns['cfdi']);
    $xml->registerXPathNamespace('t', $ns['tfd']);

    //EMPIEZO A LEER LA INFORMACION DEL CFDI E IMPRIMIRLA
    foreach ($xml->xpath('//cfdi:Comprobante') as $cfdiComprobante){

       $version =  $cfdiComprobante['Version'];
       $fechaemision =  $cfdiComprobante['Fecha'];
       $total =  $cfdiComprobante['Total'];
       $subtotal =  $cfdiComprobante['SubTotal'];
       $formadepago =  $cfdiComprobante['FormaPago'];
       $tipocomprobante =  $cfdiComprobante['TipoDeComprobante'];
       $numerocertificado = $cfdiComprobante['NoCertificado'];
       $metododepago =  $cfdiComprobante['MetodoPago'];

       //set $node field COMROBANTE values
       $node->field_factura_version['und'][0]['value'] = $version;
       $node->field_factura_fecha_de_emision['und'][0]['value'] = $fechaemision;
       $node->field_factura_total['und'][0]['value'] = $total;
       $node->field_factura_subtotal['und'][0]['value'] = $subtotal;
       $node->field_factura_forma_de_pago['und'][0]['value'] = $formadepago;
       $node->field_factura_metodo_de_pago['und'][0]['value'] = $metododepago;
       $node->field_fact_tipo_de_comprobante['und'][0]['value'] = $tipocomprobante;
       $node->field_factu_num_de_certificado['und'][0]['value'] = $numerocertificado;

       // calculo de impuestos trasladados
       $impuestostrasladados = $node->field_factura_total['und'][0]['value'] - $node->field_factura_subtotal['und'][0]['value'];
       $node->field_factura_impuestos_traslada['und'][0]['value'] = $impuestostrasladados;

      }

      foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Emisor') as $Emisor){

        $emisorrfc = $Emisor['Rfc'];
        $emisornombre =  $Emisor['Nombre'];
        //$usocfdi = $Emisor['UsoCFDI'];
        $regimenfiscal = $Emisor['RegimenFiscal'];

        $node->field_factura_rfc_emisor['und'][0]['value'] = $emisorrfc;
        $node->field_factura_emisor_nombre['und'][0]['value'] = $emisornombre;
        //$node->field_factura_uso_cfdi['und'][0]['value'] = $usocfdi;
        $node->field_fact_emisor_regimen_fiscal['und'][0]['value'] = $regimenfiscal;
      }

      foreach ($xml->xpath('//cfdi:Comprobante//cfdi:Receptor') as $Receptor){
      $receptorrfc = $Receptor['Rfc'];
      $receptornombre =  $Receptor['Nombre'];
      $usocfdi = $Receptor['UsoCFDI'];

        $node->field_factura_receptor_rfc['und'][0]['value'] = $receptorrfc;
        $node->field_factura_receptor_nombre['und'][0]['value'] = $receptornombre;
        $node->field_factura_uso_cfdi['und'][0]['value'] = $usocfdi;
      }

        if ($tipocomprobante == 'E' || $tipocomprobante == 'T' || $tipocomprobante == 'N') {
          # code...
          $procesada = 0;
          drupal_set_message('El documento que intenta procesar es invalido', 'error', FALSE);
          //drupal_set_message('tipo :' . $tipocomprobante .'procesada: ' .$procesada, 'warning', FALSE);
          unset($xml);
          unset($node);
          unset($file);

        } else {
        $procesada = 1;
        node_save($node);
        unset($xml);
        unset($node);
        unset($file);
        //$xml->close();
      }

      } // fin del else tipo de comprobante
      return array(
        'procesada' => $procesada,
      );

  } // fin de funcion rules procesar_factura_xml

```

---
Tags: rules, files
---


# Question
Title: How do I get the server time using REST GET HTTP?
Is it possible to get the time from Drupal 8 with GET HTTP and REST?

I get the date format from /entity/date\_format/long, which returns a value similar to the following one.

```
{
"uuid": "76e070cb-a783-47bf-89cc-db9f393a7d59",
"langcode": "en",
"status": true,
"dependencies": [],
"id": "long",
"label": "Default long date",
"locked": false,
"pattern": "l, F j, Y - H:i"

```

}

It is not what I need. I need to get the server time, so I can after synchronize some dates.

# Answer
`/entity/date_format/long` is just giving information on the date format

The easiest and cleanest way to do this is probably to create a simple custom REST resource in a custom module and within the resource you can return the server time using php functions

```
$message = [
    'time' => date("Y-m-d H:i:s"),
    'timezone' => date_default_timezone_get(),
];

```

You also have to implement `CacheableResponseInterface` in order to get the current time on every call to the service otherwise you are going to get a cached response.

Here is a working REST API time service module for this which I did just for the sake of this exercise
> 4 votes

# Answer
The Rest module in Drupal 8 defines some routes that allow to view/modify some entities a Drupal site has. Since the current server time is not an entity, the module doesn't define a route to expose that value.

You can implement a route that exposes that value, in a custom module, for example defining a route like the following one.

```
mymodule.server_time.http:
  path: '/mymodule/server_time'
  defaults:
    _controller: \Drupal\mymodule\Controller\RestController::serverTime
  methods: [GET]
  requirements:
    _access: 'TRUE'
    _format: 'json'

```

`RestController::serverTime()` would then use code similar to the following one, to return the server time and the timezone.

```
public function serverTime() {
  return new JsonResponse([
    'timezone' => $this->timeSettings->get('timezone.default') ?: @date_default_timezone_get(),
    'time' => $this->time->getCurrentTime(),
  ]);
}

```

The necessary services would be injected from the following code.

```
public function __construct(Config $time_settings, TimeInterface $time) {
  $this->timeSettings = $time_settings;
  $this->time = $time;
}

public static function create(ContainerInterface $container) {
  return new static($container->get('config.factory')->get('system.date'), $container->get('datetime.time'));
}

```

Using the *datetime.time* service is important when creating tests, which require predictable timestamps. It is preferable to using PHP functions to get the current time.

The controller class should extend the `ControllerBase` class. Remember to add the appropriate `use` statements at the beginning of the file containing the controller class.
> 2 votes

---
Tags: 8
---


# Question
Title: Give permission to non-admin user to view and edit list of orders
I am trying to create a role and assign it to a user who can view the admin orders list page and also edit the orders.

After adding all the permissions under the order sections in the permissions page, I was not able to access the list of the orders but was able to see the orders separately and edit them using the order number.

`admin/commerce/orders` page was accessible but the list was not showing.

Why is this happening? Is there any way fix this? From the screenshot, you can see that I have given all the required permissions with respect to orders.

Any help is much appreciated.

# Answer
> 0 votes
After comparing the query being executed for the admin user and the non-admin user I found that `1=0` is being added to the `commerce_orders` view's query.

Further checking out the code, it seems that in the `commerce.module` file, the code expects either shipping or billing permission being granted to the user.

After adding one of them, the list was visible. I don't know why it's like this, List of orders must not expect that permission right?

**TLDR;** Adding the billing/shipping permission fixed the issue.

---
Tags: 7, commerce
---


title: Disable RSS feed

text:
# Question
Title: Disable RSS feed
Is it possible to disable the RSS feed? I have a site that it isn't relevant for and just don't want it.

If it is not possible, how can I restrict what appears? How does Drupal choose what content appears in the feed?

# Answer
> 7 votes
### Drupal 7

For D7 simply use Disable RSS.

> This module will disable the core RSS feed at http://example.com/rss.xml, and remove any reference to it in the html header.

---

### Drupal 8

In D8 the feed is provided by a view. Disabling it will disable the feed. Go to http://example.com/admin/structure/views/view/frontpage/edit/feed\_1 and disable this display:

# Answer
> 1 votes
Just disable the feeds' view on default taxonomy term view.

# Answer
> 1 votes
You disable in views {example.com}/admin/structure/views/view/frontpage/edit/feed\_1 {example.com}/admin/structure/views/view/taxonomy\_term/edit/feed\_1

Choices menu Disable Feed

# Answer
> 0 votes
**Drupal 7**

Just unset the menu entries related to RSS. This allows to disable not only the main rss.xml but also blog and taxonomy feeds.

In a module add a hook to alter the menu:

```
function yourmodule_menu_alter(&$items) {
  unset($items['rss.xml']);
  unset($items['blog/%user/feed']);
  unset($items['taxonomy/term/%taxonomy_term/feed']);
}

```

Remember to clear the caches after adding this code (e.g. `drush cc all`).

# Answer
> -1 votes
You need to edit your `page.tpl.php` file and comment out or delete:

```
<?php print $feed_icons; ?>

```

*Note:* This will work only if no one has subscribed to the feed yet.

# Answer
> -2 votes
In Drupal 8 the printing of feeds is called from the theme.
The core base theme "Stable" inserts a line at the bottom of the template core/themes/stable/templates/views/views-view.html.twig that looks like {{ feed\_icons }}. Just delete it. I'm trying out the basetheme "fortytwo" which has its own template views-view.html.twig and the relevant section is also at the bottom but looks like

```
{% if feed_icons %}
   <div class="feed-icons">
    {{ feed_icons }}
   </div>
{% endif %}

```

so the section to delete may vary.

---
Tags: feeds
---


# Question
Title: I want to send emails from a custom module
I created a module to send emails, but I don't now how to send emails.

# Answer
Implement `hook_mail` in your custom `MODULENAME.module` file similar to the following

```
function MODULENAME_mail($key, &$message, $params) {
 $options = array(
   'langcode' => $message['langcode'],
 );
 switch ($key) {
   case 'general_mail':
     $message['from'] = \Drupal::config('system.site')->get('mail');
     $message['subject'] = t('General mail: @subject', ['@subject' => $params['subject']], $options);
     $message['body'][] = $params['message'];
     break;
 }
}

```

And than to send email anywhere in your code using something like this

```
$mailManager = \Drupal::service('plugin.manager.mail');
$module = 'MODULENAME';
$key = 'general_mail';
$to = "mail@mail.com";
$params['message'] = "This is the message";
$params['subject'] = "Mail subject";
$langcode = \Drupal::currentUser()->getPreferredLangcode();
$send = true;
$result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
if ($result['result'] !== true) {
  drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
}
else {
  drupal_set_message(t('Your message has been sent.'));
}

```
> 3 votes

---
Tags: 8, emails
---


# Question
Title: Use another field value as condition in Entity Query
I'm performing in Drupal 8 an **entity query** that searches for nodes that have not been changed since x days, where x is a numeric node field (node.field\_days). So I would like to perform a query like:

```
$query = \Drupal::entityQuery("node")
  ->condition('changed', strtotime('-node.field_days days'), '<=');

```

I know that condition takes as value a string and not a db column, but is it possible to use entity query with a dynamic value?

# Answer
The entity query is a powerful and convenient tool to query for content and config entities that have certain properties/field values/field references.

Yet, it has its limitations. Comparing two fields is not possible using the generic entity query and its condition method.

For such a task, you may need to use the more low level dynamic (select) queries and its where method. An example for your use case:

```
$connection = \Drupal::database();
// Query node base field table.
$query = $connection->select('node_field_data', 'n');
// Join with the `field_days` field table.
$query->leftjoin('node__field_days', 'd', 'd.entity_id = n.nid');
// Query for the node ID.
$query->fields('n', ['nid']);
// Your condition (a day has 86400 seconds; we multiply them with
// the value of the field_days field, add them to the changed
// timestamp of the node and compare it against the current time).
$query->where('n.changed + (d.field_days_value * 86400) <= :now', [
  ':now' => \Drupal::time()->getCurrentTime(),
]);
// Optional sorting.
$query->orderBy('n.changed', 'DESC');
// Fetch results.
$result = $query->execute()->fetchAllKeyed(0, 0);

```

Above example assumes:

1. that you used a numeric field type for `field_days`, so its database stored value can be multiplied with seconds without any casting,
2. that the `field_days` field allows one value only, so we can safely ignore field deltas when joining,
3. that `field_days` is present on all nodes/bundles and has a valid value,
4. that you use one language only in your site/the `field_days` value is not translatable, so we can also ignore langcodes.

You may have to alter the query accordingly, if any of these assumptions is not true.
> 6 votes

---
Tags: 8, database
---


# Question
Title: Custom Body of Webform email handler missing text area
When selecting default, I have the html appearing. Selecting twig will work as well. Selecting Custom Body changes to a blank area with no way to enter code. This happens on both lamp and live site. see image

# Answer
> 0 votes
At jrockowitz suggestion I found the issue, in case someone else has same issue, ckeditor could not find the plugin.js file and related files. I moved them as below and it works. was: ckeditor.link/ with a folder called link and plugin.js now: ckeditor.link/ with folders dialogs, icons, images, lang and plugin.js file

---
Tags: 8, webforms
---


# Question
Title: How do I validate a number against a list of valid numbers?
I want to validate a license number against a list of license numbers stored in vocabulary as taxonomy terms. The returned boolean value should then activate other form fields which are disabled by default.

# Answer
> 2 votes
You can create a custom webform validation.

In a custom module you will need to implement `CUSTOM_MODULE_webform_element_alter` in which you will define a new validation method.

You have to implement the callback method `validate()` as it is described in the documentation above.

In your `validate` method you have to compare the submitted value with your vocabulary terms using something similar to the following code

```
// ...
$vid = 'vocabularyname';
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
foreach ($terms as $term) {
    if($value == $term->name){
        // ... found
    }
}

```

**About the 2nd part of you question / conditional enabling of fields**

Webform built-in conditional logic probably cannot handle it as it only depends on values and NOT validation state of another field. Perhaps it can be done using conditional\_fields but I have not personally tried it.

---
Tags: webforms
---


title: Applying image style breaks image src

text:
# Question
Title: Applying image style breaks image src
I have added simple blogging functionality to my Drupal Site using a custom content type named Blog that I created.

One of the fields in Blog content type is a image field.

Inorder to display a list of teaser blog posts, I created a view with a page named Blog List.

This view displays a list of Blogs using the Teaser view mode.

This works fine until I try change the image style associated to the Teaser view mode for the Blog content type.

When the Image Style is set to None(Origional Image), all the images are visible for the teasers on my Blog List view page.

When I change the image style to anything else like "Medium 220x220" for example, the images for the Blog teasers do not display on my Blog List views page and it appears if their links are broken. I have also noticed that when I apply a Image style the Blogs teaser display image field, the image src is appended with something like "?itok=R1dYIZFH", when I temporarily remove this param, the image is displayed.

I am trying to do all of this through the UI.

Any help and suggestions would be greatly appreciated \<3

# Answer
The ?itok='xxxxxx' is normal. This is to prevent possible DDoS attacks.

This problem can be broken down to a couple of things to check.

First, you need to check if the image is actually being created properly. You can do this by looking in your public files directory under styles/\[image style\]/public/\[path to original\] (e.g. does public:/resources/foo.png exist in the directory sites/default/files/styles/medium/public/resources/. You should see the new image there.

If not, then there is a problem generating the image. Check the status report to verify that a graphics tool exists. Also check the logs for errors.

Common problems here are that the directory rights are not set correctly and the system can not create the file.

If the image file exists, you may be having a browser cache issue. Most browsers will latch onto a 404 and not try to reload it. You will need to force a full page reload (Shift F5 in most browsers) or clear cache / view from an incognito to see the image. Only on your test browser. Once it is created, others will not have this problem.

Another possiblity is that your site is using an upstream caching service, e.g. CloudFlare, Varnish, etc. This service may be caching the initial 404 and not letting people see the image.

If there are still problems, please update with more information, including a URL.
> 1 votes

---
Tags: media
---


title: Help with user interface translation

text:
# Question
Title: Help with user interface translation
Our portals are using User Interface Translation to do the translations. These copies/texts are located in the front-end as part of the content, or sometimes are pop ups.

This tool is not translating. That has to be done manually and the tool only provides a box where to input the translation.

Questions:

1. Does Drupal allow to automatically translate interface strings by just selecting the desired target language?
2. Is it possible to mass-upload translations in Drupal? How would we achieve it?

# Answer
This tool used to be called "Translate interface" in Drupal 7, and it seems they should have stuck to the name.

1. No, this tool doesn't actually translate the interface, it only stores the translations you enter there yourself, it allows you to search through existing strings and enter new translations.

As suggested in the comment you may find outside services that do translations for you.
2. This tool has Export and Import options (you can see them as tabs in your screenshot), you can use them to export into the usual .pot file format (common in translating) and use an application to translate through there, then import the edited file into Drupal.

There are tools you can use to convert the .pot files into CSV for example, although it's better to keep to the standards. PO and POT files

**Drupal Localization project** is where anyone can contribute translations for Drupal core and contributed projects. You can do your translations there and let the whole community benefit: Translate to Thai

If you have any custom modules on your site you'll have to translate yourself through that tool, Export/Import or some third party service as mentioned.
> 2 votes

---
Tags: i18n-l10n
---


title: Calendar From Multiple Content Types

text:
# Question
Title: Calendar From Multiple Content Types
I have a 4 seperate calendars created on drupal; each with their own content type. Each of these need to be able to be viewed on their own but I'd also like to be able to combine all of these calendars into one master view and can't seem to figure it out.

ie. Meetings calendar, Holidays calendar, Staff Events calendar.

Any help would be greatly appreciated. I'm new to Drupal so please be gentle.

Thanks

# Answer
If you've got the calendar views setup already, there's a few ways to show them all together

1. Views attachment displays ( maybe )
2. views\_embed\_view in a template ( ok, if comfortable with PHP )
3. Panels ( recommended )

For example, using Panels, you can create a page with a particular layout and simply embed the View displays into the Panel page via the user interface.
> 0 votes

# Answer
all content types MUST use same date field, then make 5 calenadar views, 1-4 on filter cryteria do choose only one content type, there you have a calendar view for each content type, on 5th view (your 'master' view) in filter cryteria do choose all 4 content types. Now in a single calendar view you will have all 4 content types mixed toghether. Example filtering by content type:
> 0 votes

---
Tags: views, nodes, datetime
---


# Question
Title: How do I show a list of nodes referenced by a field?
I created two content types: *News Agency* and *News*. The *News* content type has the *Headline*, *Title*, *Body*, and *News agency name* (a reference to a *News Agency* node) fields. The *News agency* content type has the *News agency name* and *Publisher* fields.

I need to show the news related to particular news agency. I am trying to set a relationship, but it still doesn't show result.

# Answer
The "Entity reference" field has a few options about how to display the referenced entities (Label, entire node, Node ID).

But you're referencing News agencies from News nodes, not the other way around. So you're able to choose how News agencies are listed on News pages through the "Manage display" settings in Content type.

If you want to list nodes on the News agency pages you need to use Views to create "backwards" Relationship:

1. Create Views listing News, Block display
2. Add a Contextual filter for the Entity reference field relating to the News agency and configure it `When the filter value is NOT available`
**Provide default value**
**Content ID from URL**
`When the filter value IS available or a default is provided`
**Specify validation criteria**
**Content** **Related? News agency**

Test the configuration by entering one of your News Agency NIDs into the Views Preview field. You should see News nodes that relate to that agency in the view results.
3. If everything is working as expected place the Block into a region in your theme and configure it to only appear on the News Agency pages, and configure the filter option for the reference.

Now when you visit News Agency pages you'll see a list of all News that relate to that agency.
> 0 votes

---
Tags: views, nodes
---


# Question
Title: is getString() returning translated content?
```
$links['node']['#links']['node-readmore']['attributes']['title'] =

$entity->field_anc_label->getString();

```

I am using getString() value , need to know whether its translated or we need to call it under t() to get it translated ?

# Answer
> 1 votes
you can check translation with something like

```
if ($entity->get('field_anc_label')->getFieldDefinition()->isTranslatable()) {
  // The field translation is enabled.
$links['node']['#links']['node-readmore']['attributes']['title'] = $entity->field_anc_label->getString();
}else{
$links['node']['#links']['node-readmore']['attributes']['title'] =
t($entity->field_anc_label->getString());
}

```

# Answer
> 0 votes
t() is for translation of string literals in UI. To translate content you have to use Entity Translation.

In this case for example:

```
$translated_entity = \Drupal::service('entity.repository')
  ->getTranslationFromContext($entity);

$links['node']['#links']['node-readmore']['attributes']['title'] =
  $translated_entity->field_anc_label->value;

```

---
Tags: 8
---


title: How to create a redirect form?

text:
# Question
Title: How to create a redirect form?
I have a very important tag list (over 100k) (drupal 8).

I'm using the default view of taxonomy.

I need a form in my navbar that allows me to redirect to the different lists related to my tags generated with taxonomy view.

For example:

1. I type in the form "term 1",
2. then appears the list of all the contents tagged with the "term 1", **with for url mysite/term-1** (**important**).

I tried to modify the taxonomy view with an exposed form but it does not work, because it is necessary that the form allows to search in all the site and not to filter the list displayed.

I tried to create a content view with an exposed form to sort by terms of taxonomy, it works but I have url problems not optimal for SEO (ex: mysite/myview?tid=taxonomy+term+(3)).

I thought of an element of type select with autocomplete (as chosen) but considering the number of tags I do not think it is recommended. Creating a menu seems to me also not recommended.

In short, I do not find the solution!

Does somebody have an idea ?

# Answer
> 0 votes
To get the form with a suggestions list like that you need to create an exposed filter in your content Views and use `Exposed form in block` option. Place the block in a region of your theme.

To get the autocomplete suggestions list for taxonomy terms use the `Has taxonomy terms` filter and set it to Autocomplete.

The Global filter doesn't seem to work with taxonomy fields, I'm not sure if there are combinations you can try to make it work and have all the vocabularies terms searchable in one field.

The default Taxonomy term Views contextual filter needs to be removed since it won't work with only exposed filter output unless you use Views Filter Harmonizer.

Query Parameters To URL can help with the SEO side of things.

To get the Term name into your content Views instead of the TID you have to add a Relationship to the related Taxonomy term field. Then you'll be able to add Fields, Filters and Contextual filters based on the "Name", but the widgets might not offer autocomplete or other options you have under "Has taxonomy term".

Alternatively you can create a "Taxonomy term" TYPE of views where you can get the Name filter for all vocabularies, but no autocomplete.

(Add Relationship to content so you can show nodes in the results.)

Search Autocomplete might help partially, maybe you can get it to direct to a specific views page with the result as argument.

Using a more powerful Search API or other search features related to Views might allow you to achieve everything you're asking about.

---
Tags: views, 8
---


title: Display file size next to file link

text:
# Question
Title: Display file size next to file link
I'm trying to override the file-link.html.twig to display the size next to the file link (also the file MIME type, but I think I can figure that out once I figure out how to display the size) but so far I've been failing spectacularly. I assume this must be super simple and I'm missing something obvious.

Using kint($variables) in the function themename\_preprocess\_file\_link(&$variables) I see the filesize:

```
$args array (1)
array (15
'file' => Drupal\file\Entity\File(27)
"contents" tab:
    protected values -> array(13)
    'filesize' => array(1)
    'x-default' => string(7) "2245389"

```

But I can't figure out how to turn this into a variable I can use in a template file.

I tried following How can I override template\_preprocess\_file\_link function? but then I couldn't figure out what was suppose to be the variable to use in the template file. Also, his "code" just seems to be same as what is on https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/template\_preprocess\_file\_link/8.6.x.

# Answer
> 3 votes
Using `HOOK_preprocess_field(&$variables)`:

```
/**
 * Implements HOOK_preprocess_field().
 *
 * @inheritdoc
 */
function HOOK_preprocess_field(&$variables) {
  $element = $variables['element'];
  // Check that field_name is set.
  if (isset($element['#field_name'])) {
    // Checking for field_name, but could check for field_type.
    if ($element['#field_name'] == 'field_name') {
      // Set our file size to a variable.
      $fileSize = $element[0]['#file']->filesize->value;
      // Edit our title for the field display.
      $element[0]['#file']->filename->value = $element[0]['#file']->filename->value . ' ' . $fileSize;
    }
  }
}

```

---

Using `HOOK_preprocess_file_link(&$variables)`:

```
/**
 * Add the "file-link.html.twig" template to your theme and adjust as needed.
 *
 * Twig variables:
 * - {{ fileLinkDisplay.fileBundle }}
 * - {{ fileLinkDisplay.fileCreatedTime }}
 * - {{ fileLinkDisplay.fileChangedTime }}
 * - {{ fileLinkDisplay.fileFid }}
 * - {{ fileLinkDisplay.fileLangcode }}
 * - {{ fileLinkDisplay.fileMime }}
 * - {{ fileLinkDisplay.fileName }}
 * - {{ fileLinkDisplay.fileOwnerId }}
 * - {{ fileLinkDisplay.fileOwnerName }}
 * - {{ fileLinkDisplay.fileOwnerUserPictureUrl }}
 * - {{ fileLinkDisplay.fileSize }}
 * - {{ fileLinkDisplay.fileSizeFormatted }}
 * - {{ fileLinkDisplay.fileStatus }}
 * - {{ fileLinkDisplay.fileUrl }}
 * - {{ fileLinkDisplay.fileUuid }}
 */

function HOOK_preprocess_file_link(&$variables) {
  if (isset($variables['file'])) {
    $variables['fileLinkDisplay'] = [
      'fileBundle' => $variables['file']
        ->bundle(),
      'fileCreatedTime' => $variables['file']
        ->getCreatedTime(),
      'fileChangedTime' => $variables['file']
        ->getChangedTime(),
      'fileFid' => $variables['file']
        ->fid->value,
      'fileLangcode' => $variables['file']
        ->langcode->value,
      'fileMime' => $variables['file']
        ->getMimeType(),
      'fileName' => $variables['file']
        ->getFilename(),
      'fileOwnerId' => $variables['file']
        ->getOwnerId(),
      'fileOwnerName' => $variables['file']
        ->getOwner()->name->value,
      'fileOwnerUserPictureUrl' => file_create_url($variables['file']
        ->getOwner()->user_picture->entity->uri->value),
      'fileSize' => $variables['file']
        ->getSize(),
      'fileSizeFormatted' => format_size($variables['file']
        ->getSize()),
      'fileStatus' => $variables['file']
        ->status->value,
      'fileUrl' => file_create_url($variables['file']
        ->getFileUri()),
      'fileUuid' => $variables['file']
        ->uuid->value,
    ];
  }
}

```

See https://gitlab.com/prestosaurus/file-link-display/blob/master/file\_link\_display.module

Then your `file-link.html.twig` might look like:

```
{#
/**
 * @file
 * Theme override for a link to a file.
 *
 * @see template_preprocess_file_link()
 */
#}
{{ attach_library('classy/file') }}
<span{{ attributes }}>{{ icon }} {{ link }} {{ fileLinkDisplay.fileSize }} {{ fileLinkDisplay.fileMime }}</span>

```

---
Tags: 8, theming
---


title: D8 Webforms Predefined Options

text:
# Question
Title: D8 Webforms Predefined Options
How would you use/access D8 Webforms Predefined Options (such as days,months,gender, marital status,country etc,etc) in code, say in MYMODULE\_form\_alter(&$form, FormStateInterface $form\_state, $form\_id). Where is the predefined options data stored ?

For example, for country codes options \["AF"=\>"Afghanistan","AL"=\>"Albania",....,"US"=\>"United States",..\] how would you get country name from country code.

Your aasistance will be greatly appreciated.

# Answer
You can alter the options in this hook:

```
/**
 * Alter form options by id.
 *
 * @param array $options
 *   An associative array of options.
 * @param array $element
 *   The form element that the options is for.
 * @param string $options_id
 *   The form options id. Set to NULL if the options are custom.
 */
function hook_webform_options_alter(array &$options, array &$element, $options_id = NULL) {

```

See http://cgit.drupalcode.org/webform/tree/webform.api.php

The options are stored in the config entity `webform_options`, see http://cgit.drupalcode.org/webform/tree/src/Entity/WebformOptions.php
> 0 votes

# Answer
`use use Drupal\webform\Entity\WebformOptions;
// **ID of option = country_code or gender**
 $webform_test_options = WebformOptions::load('ID of option');
 $options = $webform_test_options->getOptions();
/* Update predefind options --- */
$webform_test_options->set('options', Yaml::encode($data));
/* $data will be array ["AF"=>"Afghanistan","AL"=>"Albania",....,"US"=>"United States",..]*/ $webform_test_options->save();`

Hope this help.
> -1 votes

---
Tags: webforms
---


# Question
Title: How to reference external JS callback in custom module
So I apologize if I mess the terms here up, I'm relatively new to using jQuery in Drupal. I'm trying to implement a custom Google Map application with the V3 API. When I started mocking the module up I had no problem invoking the google maps function callback without my JS being wrapped in a closure. However, needing to use jQuery functions pointed me to wrapping my JS in a closure and referencing jquery, as well as attaching my js to the Drupal.behaviors object. The problem that I have is that now it seems that the callback on my Google Maps script tag is out of scope. I'm not sure if this is due to the closure, due to how I'm loading the script, or something else that I haven't come across yet. The specific JS error I get is

```
Uncaught (in promise) message: "initMap is not a function"

```

My module JS is

```
(function ($) {
Drupal.behaviors.gmap_json = {
attach : function (context, settings){
var map, alumLayer, chapterLayer, assocLayer, userLayer;
  function initMap() {
    map = new google.maps.Map(document.getElementById('json-map'), {
      zoom: 4,
      center: {lat: 38.43, lng: -90}
    });
  alumLayer.setStyle({
    icon: 'purple.png',

  });
}
}
};
      alert('it works');
}(jQuery));

```

And my module php is

```
function gmap_json_block_info() {
    $blocks = array();

    $blocks['gmap_json'] = array(
      'info' => t('Google Maps with GeoJSON'),
    );

    return $blocks;
  }

  function gmap_json_block_view($delta = '') {
    $block = array();
    if ($delta == 'gmap_json') {
      $block['subject'] = '';
      $block['content'] = '<div id="json-map" style="width:1100px; height:500px; margin:auto;"></div>';
    }
    $path = drupal_get_path('module', 'gmap_json');
    drupal_add_js('https://maps.googleapis.com/maps/api/js?key=mykey&callback=initMap', 'external');
    drupal_add_js($path. '/gmap_json.js', 'file');

    return $block;
  }

```

So, what am I doing wrong and how can I either bring my callback into scope? Or what's the right way to set this up.

EDIT: I have attempted to implement both the answer as well as one of the comments.

```
drupal_add_js('https://maps.googleapis.com/maps/api/js?key=mykey&callback=initMap', array('type' => 'external', 'defer' => 'defer'));

```

Adding a "defer" via array doesn't produce any changes, and changing the order of my calls to the js only changes where the error gets called.

# Answer
You could/should add the defer tag to your maps drupal\_add\_js as recommended by google (https://developers.google.com/maps/documentation/javascript/tutorial)

You'll get abit better page performance and should get rid of your issue you're facing as the google maps code will always be loaded after your scripts

Here's how you can add the defer tag: How to drupal\_add\_js an external and defer script
> 0 votes

---
Tags: 7, javascript
---


# Question
Title: Template suggestion doesn't work with a custom menu link (custom route)
In a module I have created a custom link by creating a custom route inside the mymodule.routing.file.yml and the mymodule.links.menu.yml file. In my theme.theme file I have defined a hook\_page\_alter to add a template suggestion. With the debug mode and in the html code of the custom page, I see the proposed template suggestions.

```
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'page' -->
<!-- FILE NAME SUGGESTIONS:
* page--mycustomtemplate.html.twig
x page.html.twig

```

I have build a new template with this name 'page--mycustomtemplate.html.twig'. After clearing the cache, the new template isn't called, and the default page template is always actived.

Did I forget something?

# Answer
I'm guessing you put the template in your module folder and not in a theme?

You need to register the template with something like this in your .module file:

```
/**
 * Implements hook_theme().
 */
function mymodule_theme() {
  $theme['page__mycustomtemplate'] = [
    'template' => 'page--mycustomtemplate',
  ];

    return $theme;
}

```
> 0 votes

---
Tags: theming, hooks, routes
---


# Question
Title: drush cim creates and immediately deletes field
Importing the following yml fails. With UUID it wants to be deleted. After removing the UUID it fails with field type doesn't exist. Any ideas? Is there some kind of order that might make the import fail.

```
uuid: null
langcode: de
status: true
dependencies:
  config:
    - field.storage.node.comment_forum
    - node.type.forum
  module:
    - comment
_core:
  default_config_hash: Tqw7kBEqm9_VZSK9bsNBAgJqAmJGP6cKEzXtf_KlqBo
id: node.forum.comment_forum
field_name: comment_forum
entity_type: node
bundle: forum
label: Comments
description: ''
required: true
translatable: true
default_value:
  -
    status: 2
    cid: 0
    last_comment_name: null
    last_comment_timestamp: 0
    last_comment_uid: 0
    comment_count: 0
default_value_callback: ''
settings:
  default_mode: 1
  per_page: 30
  form_location: true
  anonymous: 0
  preview: 1
field_type: comment

```

After doing a drush cex and reverting the affected file I now only have left those two lines when doing a drush cim. So the field seems to be created and deleted again. I can't find any config that is triggering that delete. Any clue?

# Answer
Okay, there was a second field.field.node.forum.comment\_forum.yml in the code of a custom module. It was just a simple setting which sould rewrite the code above but lead into a conflicting import. It looks like the second yml file gets imported first. So far **deleting the second yml file fixed the problem**.

P.S. We will now try to find out why the rewrite doesn't work in the correct order.
> 0 votes

---
Tags: 8, configuration
---


title: Problem with Mail System/SwiftMailer

text:
# Question
Title: Problem with Mail System/SwiftMailer
In the submitForm of some form of my custom module, an email is sent this way:

```
$sTo = 'eric.falzon@free.fr';
$sBcc = _setListOfRecipients();
$aParams = array($sBcc, $rpYear);
\Drupal::service('plugin.manager.mail')->mail('association', 'renewmembershipfirst', $sTo, 'fr', $aParams);

```

In my custom module, there is

```
function association_mail($key, &$message, $aParams)
{
    $sFrom = \Drupal::config('system.site')->get('mail');
    $message['from'] = $sFrom;
    $message['headers'] = array(
        'Content-Type' => 'text/html',
        'bcc' => $aParams[0],
        'From' => $sFrom,
        'Sender' => $sFrom,
        'Return-Path' => $sFrom,
    );
    switch ($key) {
        case 'renewmembershipfirst':
            $message['subject'] = '[le Jardin de Poissy] Renouvellement d\'adhésion';
            $sBody = "<b>" . $aParams[1] . "</b>";
            $message['body'][] = check_markup(nl2br($sBody), 'full_html');
            break;
    }
}

```

The settings of mailsystem are these:

And in my theme templates folder (mysite/web/themes/contrib/mayo/templates/), there is my email template swiftmailer--association--renewmembershipfirst.html.twig:

```
<html>
<head>
    <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
    <style type="text/css"> body {
            font-family: 'Montserrat', sans-serif;
            font-size: 14px;
        }
    </style>
</head>
<body>
<div>
    <table width="800px" cellpadding="0" cellspacing="0">
        <tr>
            <td>
                <div style="padding: 0px 0px 0px 0px;">
                    <p>
                        Chers adhérents du <strong>Jardin de Poissy</strong>,<br>
                        <br>
                        La période de renouvellement des adhésions pour {{ body }} est ouverte !<br>
                        <br>
                        Pour nous signaler votre décision :
                    <ul>
                        <li>vous suivez ce <a href="{{ url('association.renew_membership') }}">{{ 'lien'|t }}</a>,</li>
                        <li>vous indiquez votre choix (Non, Oui),</li>
                        <li>vous soumettez.</li>
                    </ul>
                    En cas de réponse positive, la soumission déclenche le téléchargement de votre bulletin
                    d'adhésion.<br>
                    Vous l'imprimez et vous nous l'envoyez accompagné de votre règlement.<br>
                    <br>
                    Merci d'avance,<br>
                    <strong>Le Jardin de Poissy</strong><br><br>
                    P.-S. Ce courriel a été envoyé automatiquement. Merci de ne pas y répondre.
                    </p>
                </div>
            </td>
        </tr>
    </table>
</div>
</body>
</html>

```

The email is sent (and received). Everything is OK (From, To, Bcc, Subject, Body).
But (there is a but), I get this notice message

```
Notice: Undefined index: filter_format in Drupal\swiftmailer\Plugin\Mail\SwiftMailer->massageMessageBody() (line 630 of modules/contrib/swiftmailer/src/Plugin/Mail/SwiftMailer.php).
Drupal\swiftmailer\Plugin\Mail\SwiftMailer->massageMessageBody(Array) (Line: 107)
Drupal\swiftmailer\Plugin\Mail\SwiftMailer->format(Array) (Line: 43)
Drupal\mailsystem\Adapter->format(Array) (Line: 287)
Drupal\Core\Mail\MailManager->doMail('association', 'renewmembershipfirst', 'eric.falzon@free.fr', 'fr', Array, NULL, 1) (Line: 179)
Drupal\Core\Mail\MailManager->Drupal\Core\Mail\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 180)
Drupal\Core\Mail\MailManager->mail('association', 'renewmembershipfirst', 'eric.falzon@free.fr', 'fr', Array, NULL, 1) (Line: 73)
Drupal\mailsystem\MailsystemManager->mail('association', 'renewmembershipfirst', 'eric.falzon@free.fr', 'fr', Array) (Line: 301)
Drupal\association\Form\RenewMembership->executeActions(Array, Object)
call_user_func_array(Array, Array) (Line: 111)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 51)
Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 589)
Drupal\Core\Form\FormBuilder->processForm('renew_membership', Array, Object) (Line: 318)
Drupal\Core\Form\FormBuilder->buildForm('renew_membership', Object) (Line: 93)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

```

Any idea what I am doing wrong?

# Answer
> 0 votes
I digged a litte bit in /swiftmailer/src/Plugin/Mail/SwiftMailer.php:

```
public function massageMessageBody(array $message) {
    // Get default mail line endings and merge all lines in the e-mail body
    // separated by the mail line endings. Keep Markup objects and escape others
    // and then treat the result as safe markup.
    $line_endings = Settings::get('mail_line_endings', PHP_EOL);
    $applicable_format = $this->getApplicableFormat($message);
    $filter_format = $this->config['message']['filter_format'];
    $message['body'] = Markup::create(implode($line_endings, array_map(function ($body) use ($applicable_format, $filter_format) {

```

I went to $this-\>config\['message'\] with Devel' config editor:

```
format: text/html
respect_format: true
convert_mode: true
character_set: UTF-8

```

which stands probably for
But no trace of 'filter\_format'.
Comparing with another D8 site I have with similar configuration, I found that what was missing is this entry in swiftmailer config: `filter_format: plain_text`.
I added it with Devel and now everything is OK: no more `Notice: Undefined index: filter_format in Drupal\swiftmailer\Plugin\Mail\SwiftMailer`.

But i have no clue of where this setting can be done thru UI.
Any idea?

---
Tags: 8, emails
---


title: Proper way to define a Migration yaml?

text:
# Question
Title: Proper way to define a Migration yaml?
I am trying to do a POC using Migrate, Migrate Plus, and Migrate Tools to define migrations and having trouble getting my migration to register and appear in the list of migrations for the migration group I created (in the UI).

In my yaml file, I put in the basics just to try and get it to appear in the UI:

```
id: remote_entity
label: TESTING
migration_group: mygroup

```

I named the file `remote_entity.yml` in a folder called `migrations` (I got this from the example in the Migrate Plus) module. Yet, it does not appear.

I see other modules have theirs in the `config/install` directory with a naming pattern assigned. Where is this file supposed to really be? What should it be named to get picked up? If it is in the `config/install` directory, do I have to uninstall/install the module numerous times as I iterate over a POC and make changes to the migration definition?

# Answer
> 4 votes
> Where is this file supposed to really be?

It's config, so config/install is fine

> What should it be named to get picked up?

Like other config it's module\_name.type.machine\_name.yml, so (e.g.) migrate\_plus.migration.id.yml

> do I have to uninstall/install the module numerous times as I iterate over a POC and make changes to the migration definition?

No, just like a normal config import you can do it partially:

```
drush cim --partial --source=/path/to/your/module/config/install

```

---

I did exactly what you did when I first played with Migrate Plus - tried to put the config in a `migrations` folder, like the example, but it didn't work for me either.

As migrations are config, this does make sense looking back - otherwise Migrate Plus would need to do something non-standard when discovering/importing migration configurations.

---
Tags: 8, migrations
---


# Question
Title: Drupal 8, entityQuery with operand "AND" for a multiple values field
I have 2 contents who contains a field 'field-test'. The 'field-test' contains an array of taxonomies (its a simple multiple values taxonomy field) :

Node A :

> field\_test : '1','2','3,'4' // where 1,2,3 and 4 are tids

Node B :

> field\_test : '4','5','6,'7'

With the entityQuery api, I can get nodes who contains the taxonomy '4' OR '5' with :

```
$test = \Drupal::entityQuery('node')
  ->condition('field_test', array('4','5'),'IN')
  ->execute();
// get nodes A and B in an array

```

But I want get only the node B (only the node who contains taxonomies 4 AND 5) How can I do that ?

Thank you :)

# Answer
> 3 votes
I'm not sure if you can do that using an entity query.

You could specify the delta explicitly:

```
\Drupal::entityQuery('node')
  ->condition('field_tags.0.target_id', 1)
  ->condition('field_tags.1.target_id', 2)
  ->execute();

```

But of course that would only match if the ids are used in those specific deltas.

You probably need to use raw SQL for this, see https://stackoverflow.com/questions/3918351/sql-query-ensure-a-row-exists-for-each-value-in for the basic approach on how to do this.

# Answer
> 3 votes
I had the same problem, and I found a way to do it with `entityQuery` and an `andConditionGroup()`. Try this out:

```
$tags = ['5', '6'];
$query = \Drupal::entityQuery('node');

foreach ($tags as $id) {
  $query->condition($query->andConditionGroup()
    ->condition('field_tags', $id));
  }

$query->execute();

```

This should loop over each id, and add it individually to the `andConditionGroup()`.

See this page for more details, including a comment with a very similar example from another user.

---
Tags: 8, database
---


# Question
Title: How to change fieldset which is made via #theme_wrapper Drupal 7
I want to change fieldset settings on some form, I want to make it collapsed by default. The problem is this fieldset isn't made via usually form API. Its made via `#theme_wrappers` param. The question is how to alter #theme\_wrappers output so it affect only certain form. Thanks!.

```
[#theme_wrappers] => Array(
  [0] => fieldset
)

```

# Answer
> 3 votes
I had to do this today on a Backdrop CMS site, but the problem and solution are exactly the same:

The problem is that most theme wrappers only add markup around the outside of something else. But a fieldset also has a process function, and process functions are not automatically added for `#theme_wrappers`.

The process function needs to run on the fieldset in order to take the `#collapsible` and `#collapsed` settings you add in the Form API to turn into the addition of the necessary CSS classes and JS library.

That means that not only do you need to set the values for `#collapsible` and `#collapsed`, but you also need to add the `#process` function. See below for an example.

```
/**
 * Implementation of hook_form_BASE_FORM_alter().
 * - Limits access to legacy fields.
 * - Collapses legacy fieldset.
 */
function mymodule_form_node_form_alter(&$form, &$form_state) {
  if (isset($form['field_images_inline'])) {
    $form['field_images_inline']['#access'] = user_access('administer nodes');

    // Add the collapsible and collapsed attributes.
    $lang = $form['langcode']['#value'];
    $form['field_images_inline'][$lang]['#collapsible'] = TRUE;
    $form['field_images_inline'][$lang]['#collapsed'] = TRUE;

    // Add the fieldset process function.
    $form['field_images_inline'][$lang]['#process'] = array('form_process_fieldset');
  }
}

```

---
Tags: theming, forms
---


# Question
Title: Best way to place hard coded link in template in multi lingual drupal 8
My website (drupal 8) was first in one language. Now I switched to multi langual.

Most of the settings i did find (translate content, webforms, strings,...).

But at the moment stuck on the hard coded links I use in the template (theming).

So I'm looking for the best way to let my hard coded links work for more languages.

At this moment this is what i got (and ofcourse this is not working well):

```
<h4><a href="/node/100">{{ 'DIENSTEN ON SITE'|t }}</a></h4>

```

This link doesn't bring the visitor to the correct link (en/ or fr/ is missing). Translate on the string works already :).

My current settings for detections are visible in the image:

Thanks for reading!

Kristof

# Answer
> 1 votes
For translated links you can use the path function

```
<a href="{{ path('entity.node.canonical', {'node': '100'}) }}"> {{ 'DIENSTEN ON SITE'|t }}</a>

```

# Answer
> 0 votes
Use a route name and parameters to generate the url. In Twig for example with path():

```
{# Link to node page. #}
<a href="{{ path('entity.node.canonical', {'node': node.id}) }}">{{ 'View node page'|t }}</a>

```

Then outbound path processing can apply the configured language detection methods.

---
Tags: theming, i18n-l10n
---


# Question
Title: Hook_views_query_alter: adding condition with entity reference value
I need to filter a table result based the current user.

I added this condition in my hook\_views\_query\_alter

```
function my_module_views_query_alter(&$view, &$query) {
  global $user;
  if ($view->name == 'preventivi' && $view->current_display == 'page_3')
  {
    // $view->query->add_where(1, $user->uid, 33, '=');
    $view->query->add_where(1, "field_data_field_installatori_reference.field_installatori_reference_target_id", $user->uid, '!=');

    // dpm($view);
    //dpm($query);
  }
}

```

but I can't find the correct value of `target_id` to insert in the condition. Any suggestion?

# Answer
This comment save my life! https://api.drupal.org/comment/49458#comment-49458

> Be careful to add the table, even if You added the field in the view UI :

I added

```
$view->query->add_table("field_data_field_installatori_reference");

```

and then I could access to my field:

```
$view->query->add_where(1, "field_data_field_installatori_reference.field_installatori_reference_target_id", $user->uid, '!=');

```
> 0 votes

---
Tags: views, hooks
---


title: Front Blank Webpage

text:
# Question
Title: Front Blank Webpage
Hi I am working on moving my website from local to development, but get this error:

**Uncaught PHP Exception InvalidArgumentException: "Class "Drupal\entity\QueryAccess\ViewsQueryAlter" does not exist." at /var/www/website/core/lib/Drupal/Core/DependencyInjection/ClassResolver.php line 24**

When I try to render the front page it is blank, but when I target internal webpages, some of them work. I tried googling what this error meant to no avail. Any tips on how to debug this error would be of great help! Thank you!

# Answer
> 1 votes
You must install and enable the same plugins from your local as on your development if you are using things dependent on them. If your site was built with composer make sure you run 'composer update' or 'composer install'.

---
Tags: views, dependency-injection
---


# Question
Title: How to resolve error Unable to install the responsive_tables_filter module since it does not exist
I am getting an error when importing the configuration from our development branch. When running. `drush cim staging`.
The error is.

> The import failed due to the following reasons: Unable to install the responsive\_tables\_filter module since it does not exist. We installed this module a long time ago but then unistalled it, disabled it, then deleted it.

There were settings for `responsive_tables_filter` in these 2 config files.
`/config/core.extension.yml`
`/config/lightning_core.versions.yml`

I removed both settings. Then ran `drush export` then pulled from development again and ran `drush import` and the error was gone.
Is it safe to manually edit these files?

# Answer
> 1 votes
If the module was never installed in the target environment, it is safe to do so.

If the module was installed before however, and it features uninstall hooks for cleaning up possibly installed database tables, key/value pairs (State API), and the like, then your approach may leave data behind.

The more appropriate way would have been to uninstall the module after you restored its module files, then export the configuration again in development, push it to production and do the import there.

Afterwards you can safely delete the module files from your environments.

The error you've seen indicates, that your code base was not in sync with your configuration. You possibly tested modules and removed its files before uninstalling them.

---
Tags: 8, configuration
---


title: Migrating fails without any error

text:
# Question
Title: Migrating fails without any error
I'm trying to run a migration D7 to D8 which I've coded. This is the command:

```
drush migrate-manifest manifest.yml --legacy-db-url=mysql://User:PASSW@localhost/drupal7ddbb --verbose

```

but basically no response, just something like done... but there is no nodes in the list of content.

Anyone knows how to make a deeper debug in Drupal8 migrations?

Thanks in advance.

# Answer
> 1 votes
Just to clarify 4 years later. At that point, migrate in core was not very stable. All those issues I was facing have gone away now, and migrate works really nice when moving from D7 or D6 to Drupal 8.

# Answer
> 0 votes
A few things I see. `const JOIN = 'n.vid = nr.vid';` this is dead code. Not sure where it comes from but as far as I am aware there's nothing in `DrupalSqlBase` or `SqlBase` that uses the constant `JOIN`. I am not sure what this even wants to be.

Your process copies the `type` and then in the `destination` I think you try to set the type/bundle to article but that's simply not how this works. Everything under the destination key is passed to the destination plugin as configuration and the way we designed and implemented this system the destination plugins do not change a thing, they just import.

So:

```
source:
  plugin: progweb_custom_blog
  constants:
    type: article
process:
    type: constants/type

```

In your particular case, you could use a map similar to `und: en` to map blog to article but if you want article nodes then you must use either the constants or the map.

---
Tags: migrations, 8
---


# Question
Title: How do I relocate the "Reset password" form?
Is there a way to hide and relocate the *Reset password* form from standard location? The login form needs to be shown as is.

I wasn't able to do what the answer on How to print the local task bar different places depending on the base route? says to do.

---

I found the No Request New Password module. However, I'd like to still access this form on a special link.

# Answer
> 2 votes
How do I print the local task bar in different places depending on the base route? is about changing where the tabs for local tasks are rendered in the page. It's different from what you want to achieve.

The module you found (*No Request New Password*) is for removing the *Request new password* link from block and user page. This is probably part of the task you want to achieve, but you cannot use that module because it has not been completely ported to Drupal 8, and it would not work. If you look at the content of the noreqnewpass.module file, you will notice it is using functions that don't exist anymore in Drupal 8, as in the following hook implementation.

```
function noreqnewpass_form_alter(&$form, $form_state, $form_id) {
  if (($form_id == 'user_login_block' || $form_id == 'user_login') && variable_get('noreqnewpass_disabled', true)) {
    $key = array_search('user_login_final_validate', $form['#validate']);
    $form['#validate'][$key] = 'noreqnewpass_user_login_final_validate';
  }
}

```

The task you want to achieve requires to:

* Remove the *Reset your password* local task from the /user/login page
* Change the path associated with the *user.pass* route
* (Eventually) remove the *Reset your password* link that appears in the login block

The fist step requires a module implementing the following hook.

```
function custom_menu_local_tasks_alter(&$data, $route_name) {
  // Remove the "Reset your password" tab only from the login page.
  if ($route_name == 'user.login') {
    unset($data['tabs']['0']['user.pass']);
  }
}

```

The second step requires altering a route another module defines. There isn't any hook to do the task, which requires writing code for an event subscriber. Fortunately, Drupal 8 has a class that can be extended to do the task.

```
class CustomSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Change path '/user/password' to '/hidden/user/reset'.
    if ($route = $collection->get('user.pass')) {
      $route->setPath('/hidden/user/reset');
    }
  }

}

```

An event subscriber is a service using the *event\_subscriber* tag. This means it needs to be defined in the .services.yml file of the module.

For the last step, it's sufficient to alter the login block.

```
function custom_block_view_user_login_block_alter(array &$build, BlockPluginInterface $block) {
 unset($build['user_links']['#items']['request_password']);
}

```

# Answer
> 1 votes
Yes, the module removes the local task by denying access to the route. To only hide the tab unset it in a hook\_menu\_local\_tasks\_alter():

```
/**
 * Implements hook_menu_local_tasks_alter().
 */
function mymodule_menu_local_tasks_alter(&$data, $route_name) {
  if ($route_name == 'user.login') {
    unset($data['tabs']['0']['user.pass']);
  }
}

```

Then you can still access `/user/password`. If you want to change this path as well you have to alter the route, see https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones

---
Tags: 8, forms
---


# Question
Title: Fields pending deletion error when disabling comment module
I tried to disable the comment module but got the following error `comment: Fields pending deletion`. I deleted all my comment content and fields, but the error keeps appearing and I can't disable the module. Can anyone tell me what's happening?

# Answer
> 0 votes
You probably did some batch operations or import. Running cron could solve the issue, or run the following command in drush:

```
drush php-eval 'field_purge_batch(1000);'

```

Change the '1000' value to larger numbers if you did for example an import of more nodes.

---
Tags: 8
---


title: getting individual field values

text:
# Question
Title: getting individual field values
I'm trying to fetch each individual field of an items array. here is the image of the kint result

here is what i have tried.

1. `{{items[0].content}}` -- this one prints the whole thing in the items array.
2. `{{items[0].content['#context'].value}}` ---- does nothing
3. `{{items[0].content['#markup'].getValue()}}` --- does nothing

Have looked for documentation, couldn't find one. Any explanation or url to documentation or example will be appreciated.

# Answer
> 0 votes
Try with `items[0]['content']` or if its field of type text you will find the value of the text with `items[0]['content']['#text']` or `items[0]['content']['#value']`

---
Tags: 8
---


# Question
Title: How to show in a view the total number of paragraphs for a node?
I have a content type with a field of type paragraphs, with possible unlimited values. I need to show the total number of paragraphs for every node, in a column, in a views (table of fields). It seems to be only possible to render a preview of the paragraph. I tried to use "rewrite result" with "replacement patterns" but the only token available are the following:

```
{{ field_hours }} == Hours
{{ field_hours__target_id }} == Raw target_id
{{ field_hours__target_revision_id }} == Raw target_revision_id

```

How I can proceed?

# Answer
> 1 votes
I managed to achieve this doing the following:

* Create a View to show Content of Type All. Add a page as well if you wish.
* Format the style to be a Table.
* Go to Advanced and turn on "Use aggregation".
* Go to aggregation settings for the field "Content:Title" and set the aggregation type to "Count".
* Change the label of this field to something like "Number of paragraphs in the node:".(\*optional)
* In Fields add field "Content:Title", aggregation type should be Group results together.
* Add Filter Criteria "Hours (field\_hours:target\_id)", aggregation type should be Group results together, and set the operator to "is not empty(NOT NULL)".

This is how the Display settings should look at the end:

And here are the desired results in the preview:

I hope this helps.

---
Tags: views, 8, nodes, paragraphs
---


# Question
Title: How to print Blocks in commerce-product.html.twig?
I am looking at building a Drupal 8 Commerce 2 product display through twig but I am having issues with how to print custom blocks in this template file. (And also testing these in normal `page.html.twig` as well)

Looking at the Custom Block Library (`/admin/structure/block/block-content`) I can see that the ID is '4', as the ID from the Edit URL is 4. (`http://www.example.com/block/4`)

I have installed the module Twig Tweak and tried all the combinations below in the commerce-product.html.twig, and each time I get a WSOD

> The website encountered an unexpected error. Please try again later.

`{{ drupal_entity('block_content', 4) }}`

`{{ drupal_entity('block_content', '4') }}`

`{{ drupal_block('block_content:4') }}`

`{{ drupal_entity('block', 4) }}`

`{{ drupal_entity('block', '4') }}`

I have also tried in my example.theme file:

```
function theme_preprocess_page(&$variables) {
  $block = \Drupal\block\Entity\Block::load('4');
  $block_content = \Drupal::entityTypeManager()
    ->getViewBuilder('block')
    ->view($block);
 $variables['productinfo'] = $block_content;
}

```

Then in \*.html.twig with lots of cache flushing before and after:

`{{ productinfo }}`

I also seam to be not even able to use any of the examples from the Twig Tweak Cheat Sheet, as each one of these I add to my any `*.html.twig` I get the WSOD.

`{{ drupal_view('who_s_new', 'block_1') }}`

or

`{{ drupal_region('sidebar_first') }}`

How do I print custom blocks into a `commerce-product.html.twig` template?

# Answer
You can use `hook_preprocess_commerce_product` to load the block and pass the variable to your twig file.

```
function YOURTHEME_preprocess_commerce_product(array &$variables) {
  $block = \Drupal\block_content\Entity\BlockContent::load(4);
  $variables['custom_block'] = \Drupal::entityTypeManager()->
    getViewBuilder('block_content')->view($block);
}

```

and then in your twig file you will have the `{{ custom_block }}` variable set.

On a sidenote, this answer helps a lot when trying to programatically load blocks.
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: How do I unfollow an issue on drupal.org?
How can I unfollow (i.e. unsubscribe from email notifications) an issue on Drupal.org that I automatically followed when I commented on the issue?

# Answer
> 1 votes
To unsubscribe to the issues for a project, for example the "Drupal.org web masters" project, you need to:

Unable to unsubscribe to drupal.org issues is an old issue that has been opened in 2006, and it has been marked as fixed. I can confirm that unsubscribing from an issue queue works, as I have done it many times in the last years.

# Answer
> 0 votes
To unfollow an issue on drupal.org, find the "Following" link. (If you are using a mouse then hovering over the link will change it to say "Unfollow".) Click on that link to unfollow.

The link should now say "Follow".

---
Tags: community-official-site
---


title: Custom form from scratch in template

text:
# Question
Title: Custom form from scratch in template
I have a paragraph that I fully themed into a contact form with the necessary tags etc... Now my question is: How do I add the actual functionality to this? Because right now it's just plain html in a template without any logic handling the form submit.

# Answer
You can use Drupal's default contact form and customize the fields as per your need which will have all the required logic for form handling. Then you can check and apply the theme as per your need to it.
> -1 votes

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


title: Create custom module but page not found

text:
# Question
Title: Create custom module but page not found
I'm new on Drupal. I try to follow a tuto in order to build my own module.

Drupal 8 (latest version) is installed on MacOS. For example, I use it through URL : http://localhost/drupal/admin/content

My module is defined like this :

* Drupal
    + code
    + modules
        - hello\_world
            * hello\_world.info.yml
            * hello\_world.links.menu.yml
            * hello\_world.routing.yml
                + src
                    - Controller
                        * HelloController.php
    + ...

File content : `hello_world.info.yml`

```
name: Hello World Module
description: Creates a page showing "Hello World".
package: Custom
type: module
version: 1.0
core: 8.x

```

File content : `hello_world.routing.yml`

```
hello_world.hello_world:
  path: '/hello'
  defaults:
    _controller: '\Drupal\hello_world\Controller\HelloController::helloWorld'
    _title: 'Hello World'
  requirements:
    _permission: 'access content'

```

File content : `hello_world.links.menu.yml`

```
hello_world.admin:
  title: 'Hello module settings'
  description: 'example of how to make an admin settings page link'
  parent: system.admin_config_development
  route_name: hello_world.hello_world
  weight: 100

```

File content : `HelloController.php`

```
<?php
/**
 * @file
 * Contains \Drupal\hello_world\Controller\HelloController.
 */

namespace Drupal\hello_world\Controller;
use Drupal\Core\Controller\ControllerBase;

/**
 * Defines HelloController class.
 */
class HelloController extends ControllerBase {

  /**
   * Display the markup.
   *
   * @return array
   *   Return markup array.
   */
  public function helloWorld() {
  $output = array();

  $output['hello_world'] = array(
    '#markup' => $this->t('Hello World!'),
  );
  return $output;

  }

}

```

Regardless "clear cache", I have a page not found !

I try the urls :

But results are the same. What should be the right url ? And why I'm getting "page not found", where is the issue ?

# Answer
> 1 votes
Creating a module does not automatically enable it.

I tried your code in a clean Drupal 8 installation and `/hello` show the page as expected.

Try running `drush en hello_world` to enable you module and you should be ok.

If that is not the case, then you can use `drupal route:debug` to see a complete list of your site routes, so you can know if your route is registered.

# Answer
> 0 votes
Since it looks like you're just starting out D8 development, additionally to drupal route:debug command I would install devel and admin toolbar modules that help out a lot in dev. Once devel is installed you could checkout the routing information at the taskbar and see all available paths to be sure your new module path is registered.

Another thing you might wanna take a look at is turning cache of completely on your local to see your changes immediately. Take a look at this guide for that.

---
Tags: 8
---


# Question
Title: Add parameter to the URL based on a field value
Is it possible to append a campaign tracking code to the requested URL basing on a specific field value on the linked node? I'm trying to use a *path\_processor\_outbound* service, but it doesn't work quite as expected and it works rather randomly.

This is the code I am using.

```
function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {if(isset($options['entity']) && $options['entity'] instanceof \Drupal\node\NodeInterface ) {
      $node = $options['entity'];

      if($node->bundle() == 'article') {
        $channel = $node->get('field_channel')->getValue();
        $promotions = array(10);
        $channel_value = reset($channel);
        $channel_id = $channel_value['target_id'];

        if(in_array($channel_id, $promotions)) {
          $options['query']['foo'] = 'bar';
        }
      }
    }
    return $path;
  }

```

I have a feeling this is correct approach for links to nodes generated on site (teasers on front page), but it doesn't append parameters on page request.

I also considered adding parameters to the path alias, but that doesn't seem to be right and JavaScript code would be added too late.

# Answer
> 0 votes
Don't know if it fits for your use case, but I wanted all outgoing links from a specific node type to have the ID appended, e.g. on every product page all outgoing "Call to action" links should appent something like `?from_product_id=1234`. My module name was 'wt\_ctalinks\`

`wt_ctalinks.services.yml`

```
services:
  cache_context.wt_ctalinks:
    class: Drupal\wt_ctalinks\CtaLinksCacheContext
    arguments: ['@request_stack']
    tags:
      - { name: cache.context }
  wt_ctalinks.ctalinks_pathmodifier_service:
    class: Drupal\wt_ctalinks\CtaLinksPathModifierService
    arguments: ['@request_stack']
    tags:
      - { name: path_processor_outbound, priority: 3000 }

```

`src/CtaLinksCacheContext.php`

```
<?php

namespace Drupal\wt_ctalinks;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CacheContextInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;

class CtaLinksCacheContext implements CacheContextInterface {

  /**
   * @var Symfony\Component\HttpFoundation\RequestStack;
   */
  protected $requestStack;

  public function __construct(RequestStack $request_stack) {
    $this->requestStack = $request_stack;
  }

  /**
  * {@inheritdoc}
  */
  public static function getLabel() {
    drupal_set_message('Modify CTA links based on current node type');
  }

  /**
  * {@inheritdoc}
  */
  public function getContext() {
    $nid = 0;
    $request = $this->requestStack->getCurrentRequest();
    $node = $request->attributes->get('node');
    if (is_numeric($node)) {
      $node = Node::load($node);
    }
    if ($node instanceof NodeInterface && $node->bundle() === 'article') {
      $nid = $node->id();
    }
    return $nid;
  }

  /**
  * {@inheritdoc}
  */
  public function getCacheableMetadata() {
    return new CacheableMetadata();
  }
}

```

`src/CtaLinksPathModifierService.php`

```
<?php

namespace Drupal\wt_ctalinks;
use Drupal\node\NodeInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\config_pages\Entity\ConfigPages;
use Drupal\node\Entity\Node;

/**
 * Class DefaultService.
 */
class CtaLinksPathModifierService implements OutboundPathProcessorInterface {

  /**
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  protected $bookingPath;
  protected $enquirePath;

  /**
   * Constructs a new DefaultService object.
   */
  public function __construct(RequestStack $request_stack) {
    $this->requestStack = $request_stack;
  }

  /**
   * {@inheritdoc}
   */
  public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
    if (empty($request)) {
      $request = $this->requestStack->getCurrentRequest();
    }

    $node = $request->attributes->get('node');

    if (is_numeric($node)) {
      // missing upcasting in revision view, have to load manually there
      $node = Node::load($node);
    }

    if ($node instanceof NodeInterface && $node->getType() === 'article') {
      // your logic here
    }

    if ($bubbleable_metadata) {
      $bubbleable_metadata
        ->addCacheContexts([
          'wt_ctalinks',
        ]);
    }
    return $path;
  }
}

```

# Answer
> 0 votes
`$options['entity']` is set only for links rendered by Views and getting the node id from the route match works only if the node is the main page content. So both solutions are not working for all outbound node links.

Another idea might be to use the route pattern `/node/{node}` to get the node id from `$path`, before it is aliased by PathProcessorAlias::processOutbound. Set a priority \>300 in the service tag to make sure your code runs first:

```
  tags:
    - { name: path_processor_outbound, priority: 500 }

```

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


# Question
Title: Core request handler documentation maybe has conflicting information?
I wanted to confirm with the community and maybe get some clarity about D8 Documentation:

On the Core request handling system ported to Symfony2 framework page it states:

> The PHP superglobals for $\_GET, $\_POST, and $\_SERVER are deprecated and should not be used, ever.

However, I can't seem to locate this information on php.net. PHP setting register\_globals is deprecated. Is this what they are refering to or did I miss something huge in recent news? No longer able to use $\_GET in our custom modules for D8?

# Answer
> 2 votes
I'm pretty sure the advice stems from this issue: Replace almost all remaining superglobals ($\_GET, $\_POST, etc.) with Symfony Request object. The opening gambit from that post is:

> In order to depend on using the Request object to determine caching, we need to ensure that everything uses it, rather than raw PHP variables for $\_SERVER, $\_REQUEST, $\_GET, $\_POST.

I don't the quoted comment is suggesting they're deprecated in PHP as such, just that using them in Drupal isn't going to be reliable.

---
Tags: 8
---


# Question
Title: Add class to checkout button on cart page
I'm trying to add classes to the Checkout button by HOOK\_form\_FORM\_ID\_alter, but the checkout button is not there.

```
 $form['actions']['checkout']['#attributes']['class'][] = 'pull-right';

```

If this is not possible, what is another way to add classes?

```
function adpomail_form_views_form_commerce_cart_form_default_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

$form['actions']['continue_shopping'] = array(
  '#type' => 'button',
  '#value' => t('Continue Shopping'),
  '#weight' => -999,
  '#attributes' => [
    'class' => ['purple'],
  ],
);
$form['actions']['submit']['#value'] = t('Update cart');
$form['actions']['checkout']['#attributes']['class'][] = 'test';}

```

# Answer
> 0 votes
There are probably many way to do this - the one I see suggested most often and that I've used is to modify or create a custom twig template. To do that;

1. Turn on debug. (see https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates)
    2. Find the appropriate template from the suggestions.
    3. Use HOOK\_preprocess\_hook to either add a class, or add a variable that you pick up in your template.

You can skip #3 if you want to simply override the output of the twig template. However, that means that EVERY form will then have that added class unless a: you can make template very specific, or two build in logic. However, logic is best left to the PHP site of things (your module that you run hook\_preprocess\_hook in.

The output from debug will help immensely. For example, I ran it on the login form and it returned this:

```
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'region' -->
<!-- FILE NAME SUGGESTIONS:
   x region--nowrap.html.twig
   * region--content.html.twig
   * region.html.twig
-->
<!-- BEGIN OUTPUT from 'themes/contrib/bootstrap_barrio/templates/layout/region--nowrap.html.twig' -->

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'form' -->
<!-- BEGIN OUTPUT from 'themes/contrib/bootstrap_barrio/templates/form/form.html.twig' -->

<form class="user-login-form" data-drupal-selector="user-login-form" action="/user/login" method="post" id="user-login-form" accept-charset="UTF-8">

```

Hope this helps.

---
Tags: 8, commerce
---


# Question
Title: Injecting configuration into mock config object
I'm trying to set up a unit test based on UnitTestCase in Drupal 8 that uses some config variables. Unfortunately I was not able to find a way to insert those config variables into the system in the setup (searched Drupal documentation and any Drupal unit test example involving config), so the function being tested always works with null config and fails. I am trying to test individual functions in isolation, so a browser test is not really appropriate for this.

I have simplified the problem to the minimum code necessary to explain/reproduce the issue. Here are the three components. Where in the mock/setup do I insert the `array('bucketName' => 'test_bucket')` and other properties so that it can be read from the tested function?

Function:

```
public function example() {
    return \Drupal::config('my_module.job')->get('my_module.bucketName');
}

```

Test function:

```
public function testExample() {
    $myModuleHelper = new MyModuleHelper();
        $expected_config = array(
            'bucketName' => 'test_bucket',
        );

    $this->assertEquals($expected_config, $myModuleHelper->example());
}

```

Test setup:

```
public function setUp() {
    $this->config = $this->getMockBuilder('\Drupal\Core\Config\ImmutableConfig')
        ->disableOriginalConstructor()
        ->getMock();

    $this->configFactory = $this->getMockBuilder('\Drupal\Core\Config\ConfigFactory')
        ->disableOriginalConstructor()
        ->getMock();
    $this->configFactory->expects($this->any())
        ->method('get')
        ->with('my_module.job')
        ->willReturn($this->config);

    $this->container = new ContainerBuilder();
    $this->container->set('config.factory', $this->configFactory);
    \Drupal::setContainer($this->container);
}

```

Test response:

> null does not match expected type "array".

# Answer
Your mock of the Config object needs to also have a `::get` method and return the appropriate value using your array. The core UnitTestCase class provides `::getConfigFactoryStub(array $configs)`, which does all of this automatically.

In your setup, create the config factory like this:

```
$this->configFactory = $this->getConfigFactoryStub([
  'mymodule.job' => ['bucketName' => 'test_bucket'],
]);

```

Unfortunately, the mocked config does not quite work like a real config object; namely, it doesn't accept dotted keys but only top-level keys. The following will not work:

```
$this->configFactory = $this->getConfigFactoryStub([
  'mymodule.settings' => [
    'key' => [
      'subkey' => [
        'subsubkey' => 'value',
      ],
    ],
  ],
]);
$this->container = new ContainerBuilder();
$this->container->set('config.factory', $this->configFactory);
\Drupal::setContainer($this->container);

\Drupal::config('mymodule.settings')->get('key.subkey.subsubkey');

```

This bug report shows a workaround: https://www.drupal.org/node/2862248

Update: The above problem was fixed in Drupal 8.5.0, so the workaround is no longer needed.
> 6 votes

# Answer
If you are using `KernelTestBase` (for "functional" tests that run on a bootstrapped Drupal and can use services), then see this answer for details on how to use `KernelTestBase::config()` to set configuration values that are accessible via the injected `config.factory` service.

Note that this won't work for tests extending `UnitTestCase` as Drupal isn't fully set up.
> 1 votes

---
Tags: 8, testing
---


title: Upload custom font files

text:
# Question
Title: Upload custom font files
I've been given a directory full of font files (woff2, svg, ttf file types). Is there a way to get these fonts to load when a page is rendered in Drupal? Is there a specific directory I have to put them in or a module that handles custom fonts?

I took a look at the contrib fontyourface module, but it seems to require using external providers instead of being able to upload your own font files.

# Answer
Do you have a custom theme? If so, you can implement it like this:

Place your fonts in your custom theme, following something similar to this folder structure:

```
themes
  custom
    my_custom_theme
      fonts
        my_font.woff2
        my_font.ttf
        my_font.svg

```

And then in your CSS file (it might be in `themes/custom/my_custom_theme/css/style.css` for example) add the following:

```
@font-face {
  font-family: "my_font;
  src: url('/fonts/my_font.woff');
  src: url('/fonts/my_font.ttf');
  src: url('/fonts/my_font.svg');
}

```
> 8 votes

---
Tags: 8, css-js-aggregation
---


title: Print a View Field in Twig

text:
# Question
Title: Print a View Field in Twig
I have to convert the following D7 to D8 in my view twig file. I tried the following but its not working.

**D7 Code :**

```
<?php print $view->result[$id]->field_field_document_upload[0]["rendered"]["#file"]->filesize; ?>

```

**D8 code in Twig :**

```
   {{ view.result[id].field_field_document_upload[0]["rendered"]["#file"].filesize }}

```

What's the issue

# Answer
> 0 votes
It's impossible to say without knowing what exact template you are overriding, but you can't really convert your old PHP print statements to twig just like that.

What you can do however is put `{{ dump() }}` into your twig file, which is the twig equivalent to `var_dump()` in PHP. This will output all your available variables.

More info on `{{ dump() }}` here.

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


# Question
Title: When translating a node, can I avoid copying the default value from the original language
Just a little background: I've got a set of paragraphs fields that I need to be able to translate, and given the limitations on translation with paragraphs, I've come up with the idea, that it may just be best to create a new node of a new content type (for holding the paragraphs fields) for each language of the main node. I would then use Inline Entity Form to bring those fields into my main node.

The problem I run into is that translation copies the value from the original language when I create a translation. Most of the time this is desirable, but in this case, it means that all languages get the same referenced node, when I specifically want them all to have their own new node.

Is there any way to suppress the value copy functionality for a specific field when translating?

# Answer
> 4 votes
Unset the field values in a hook\_ENTITY\_TYPE\_translation\_create:

```
use Drupal\node\NodeInterface;

/**
 * Implements hook_ENTITY_TYPE_translation_create().
 */
function mymodule_node_translation_create(Nodeinterface $translation) {
  if ($translation->getType() == 'product') {
    unset($translation->body);
  }
}

```

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


# Question
Title: How to use HTML in a webform component's title?
We have a checkbox which's title should have HTML (`<sup></sup>`) but its rendered as text rather than HTML.

How to use HTML in a webform component's title?

# Answer
> 0 votes
At first, I misread your question and created Issue #3036393: Allow basic HTML markup in element titles.

Checkboxes do support HTML markup.

The below YAML…

```
checkbox:
  '#type': checkbox
  '#title': checkbox<sup>sup</sup>
checkboxes:
  '#type': checkboxes
  '#title': checkboxes
  '#options':
    one: one<sup>sup</sup>
    two: two<sup>sup</sup>

```

…renders via Bartik as…

If you can replicate and document this issue, please create a ticket on Drupal.org.

---
Tags: 8, theming, webforms
---


# Question
Title: How to sort two colums in a view based on one column?
I have two columns in table header and I have to sort them based on one.

# Answer
> 0 votes
Have you tried using the Sort Criteria?

For example sorting the results based on column Title:

---
Tags: views, 8
---


# Question
Title: How do I disable Drupal 7 Theme Debug? "drush vset theme_debug 0" NOT WORKING
I enabled theme debug on my drupal 7 installation using `drush vset theme_debug 1`, But Now I can't disable theme debug using `drush vset theme_debug 0`, What the wrong, Is there any wrong or mistakes in the drush command above?

I also tried to comment out `$conf['theme_debug'] = TRUE;` in the settings.php and then replaced with `$conf['theme_debug'] = FALSE;` but none works.

Any help and suggestions on this issue?

Thanks

# Answer
> 1 votes
If using `drush vset theme_debug 0` doesn't work. Try disabling the theme debugging on your `settings.php` file, adding the below line of code:

```
$conf['theme_debug'] = FALSE;

```

Don't forget clear the cache.

---
Tags: 7
---