# Question
Title: How to load and render a webform with Ajax
I'm new on Drupal 8, and I want to make a custom module to load any webform of (webform module) on other pages of the website.

The idea is to load the webform when the page load. All webform has configured with ajax submission.

I don't know how I can do that. I someone can help me. I'm on Drupal 8

---

I've create a custom module with a custom path in `routing.yml`:

```
path: '/webform-data/{webformid}'

```

In my controller I've created a public function to retrieve the webform by id.

I want for example create a link, like:

```
<a href="/webform-data/{webformid}">Click</a>

```

When I click on the link, the webform load in a wrapper, but when I submit the webform, I have a redirection to the path of webform and I don't want the redirection. I just want the inline confirm message without reloading the page.

I have this in my controller :

```
// Controller
namespace Drupal\ajax_webform\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Ajax\AjaxResponse;
use \Symfony\Component\HttpFoundation\Response;

class AjaxWebformController extends ControllerBase {

    public function getWebform($webformid) {

        $build['webform'] = [
            '#type' => 'webform',
            '#webform' => $webformid
        ];

        $renderer = \Drupal::service('renderer');
        $rendered = $renderer->renderRoot($build);

        $response = new Response();
        $response->setContent($rendered);
        return $response;
    }

}

```

# Answer
> 1 votes
I think this is the basic code of a controller which loads and renders a webform with ajax:

```
  public function getWebform($webformid) {

    $build['webform'] = [
      '#type' => 'webform',
      '#webform' => $webformid,
    ];

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#webform-wrapper', $build));

    return $response;
  }

```

The link ajaxified by adding the class `use-ajax`:

```
<a href="/webform-data/{webformid}" class="use-ajax">Click</a>

```

You need the library `core/drupal.ajax` for the page containing this link and a `<div id="webform-wrapper"></div>` as target.

# Answer
> 0 votes
You might want to look into the Ajax links API. Sadly, there is an issue with the Webform module and BigPipe that needs to be fixed.

---
Tags: 8, webforms
---


title: create new image style using javascript

text:
# Question
Title: create new image style using javascript
I am using fancybox JS library for creating a slideshow from a custom bloc with a multivalue image field.

it works but the images on the slideshow are small because a style have been applied to the images.

I then get the original size image using a substring JS function but it is not entirely satisfying

```
(function ($, Drupal) {

  $('.bloc-image-gallery img').each(function (){
    var currentImage = $(this);
    var path=currentImage.attr("src");
    var StyleCutPath = path.substring(
      path.lastIndexOf("/") -7,
      path.lastIndexOf("?")
    );
    currentImage.wrap('<a class="fancybox" data-fancybox="gallery" href="/sites/my_site/files/' + StyleCutPath + '"></a>'); });

  Drupal.behaviors.fancyBoxInit = {
    attach: function (context, settings) {
      $('[data-fancybox="gallery"]', context).once('fancyBoxInit').fancybox({
        buttons: [
          'close'
        ]
      });
    }
  }
})(jQuery, Drupal);

```

I wonder how i could get the href with an new style applied to it ( bigger image but not original size )

The src takes this form

> /sites/my\_site/files/styles/directory\_user\_photo/public/2018-09/seminary.png?itok=5597asHF

i made it to

> /sites/my\_site/files/2018-09/seminary.png

but i would rather have smthg as

> /sites/my\_site/files/styles/my\_new\_style\_adapted\_to\_full\_screen\_visio/public/2018-09/seminary.png?itok=5597asHF

# Answer
clive would suggest to create a new Formatter for image type fields that would allow in the render display to select a image style for the image link.

At least i could do "In the field formatter settings you can tell the image to render in one style, but link through to the full image" and clean the code to:

```
(function ($, Drupal) {

  Drupal.behaviors.fancyBoxInit = {
    attach: function (context, settings) {
      $('[data-fancybox="gallery"]', context).once('fancyBoxInit').fancybox({
        buttons: [
          'close'
        ]
      });
    }
  }
})(jQuery, Drupal);

```

with in image-formatter--media--image--field-media-image.html.twig

```
   {% if url %}
      <a data-fancybox="group" href="{{ url }}">{{ image }}</a>
    {% else %}
      {{ image }}
    {% endif %}

```
> 0 votes

---
Tags: javascript, media
---


# Question
Title: Automatically importing module-provided translations during installation
I have a custom module whose interface strings have all been written in English. This module is not (and will not be) hosted on drupal.org, so I'd like to pack the translations for those texts directly with the module, and for those translations to be automatically imported by Drupal when the module is installed (provided the corresponding language is activated in Drupal, of course).

I've translated those texts in French and exported all those translations in a `my_module-fr.po` file. I've put this file in the "translations" folder inside my module folder.

As suggested in this answer, I used the interface translation properties in the `my_module.info.yml`, as follows:

```
'interface translation project': my_module
'interface translation server pattern': modules/custom/my_module/translations/my_module-%language.po

```

But when I install my module from scratch, those translations are not automatically imported.

In `admin/reports/translations`, it says *"Missing translations for one project - my\_module (1). File not found at modules/custom/my\_module/translations/my\_module-fr.po"*.

I've tried several variations for the `interface translation server pattern` value in the info.yml file, among them:

* path relative to the module folder (`translations/my_module-%language.po`) instead of the Drupal folder
* full path to the drupal install folder (since I'm on localhost and Drupal is in a subfolder) (`_tests/drupal8/www/modules/custom/my_module/translations/my_module-%language.po`)

But I always get the same "file not found" message in the admin report page, and nothing is imported.

**What am I missing?**

---

**Side question**: in the YML declaration above, is it allowed to use a path pattern *relative to the module folder*, as listed above? This would make a lot more sense to me, as I cannot predict whether the people will install my module in the "modules/contrib" folder, or in another subfolder, or directly in the "modules" folder (and if they install it from the Drupal UI, they may not even know it themselves).

# Answer
> 1 votes
Per the documentation: https://api.drupal.org/api/drupal/core%21modules%21locale%21locale.api.php/group/interface\_translation\_properties/8.4.x

> Streamwrappers can be used in the server pattern definition. The interface translations directory (Configuration \> Media \> File system) can be addressed using the "translations://" streamwrapper. But also other streamwrappers can be used.

There are several examples given for valid server pattern definitions using different stream wrappers.

**EDIT**

I see what you mean about not wanting to use the `translations://` stream wrapper.

Have you tried using the pattern definition exactly as given in the answer you cited?

`modules/custom/example_module/translations/%language.po`

If you do that, you should also take the name of your module out and just name the file `fr.po`.

Then make sure that you update translations with Drush:

`drush locale-check && drush locale-update && drush cr`

If that doesn't work, hopefully someone else can help, because I'm stumped.

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


title: Exposed filter cleaner URL

text:
# Question
Title: Exposed filter cleaner URL
I have created a custom content type called building which I have added a entity reference field called category which is the vocabulary and added building type terms. I created a view called buildings and added an exposed filter that is listing the building types. I get the listing of the categories by exposing the filter Has Taxonomy Term and then using BEF to list the categories as links rather than a dropdown or autocomplete. Whenever I click each category link for the exposed filter I get the url www.example.com/building?category=1 is there a way to make it use the term name rather than the term id. Also further, is there a way to have it make the url a little cleaner like www.example.com/building/category/buldingtype

# Answer
> 1 votes
You need to set your Exposed filter `Selection type` settings to **Autocomplete** instead of "Dropdown" you will get term names instead of TIDs.

Read more in part of this answer: How to use URL query parameter on a View Exposed Filter?

There is another way to do it: introduce the term information into the view through a Relationship so you can use the term Name. Read the steps in this answer: Get taxonomy name instead of id

That answer also mentions how you can "prettify" the URL: use the Query Parameters To URL module, it's being ported to D8.

---
Tags: views, 8
---


# Question
Title: How to add title of the image in manage display section or display it in node view page
I want to display title property of an image in node view page. How can I display title of an image along with image in node page?

# Answer
> 0 votes
## Custom Formatters

Try the Custom Formatters module to create a custom formatter, Tokens may help. There are some examples for inspiration: Custom Formatter Examples.

Or implement through your own custom solution in a module or a theme: Create a custom field formatter.

## Views Block

Another way of doing it is hiding the Image field on Manage Display, and creating a Views Block instead with a contextual node ID filter that outputs that image field along with the title. If you don't see the title available as a field in content views out of the box you can add a Relationship to that field to get it.

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


# Question
Title: Change shown fields in a grouped view depending on group
I have a view that shows nodes and groups them by their taxonomy term. Is it possible to show less fields for a specific term? For example there are user profiles with names and pictures that are listed, but if they have a specific taxonomy term the picture field shall not be shown.

# Answer
These types of problems are often solved by creating another Views display.

1. Add a Filter to your original Views to only show the results with the terms where you want to show the additional fields.
2. Then Duplicate this display as Attachment, attach it to the original views display.
3. Override the Attachment Filters and change the one for the terms - reverse the choices to filter out only the terms where you *don't* want additional fields
4. Override the Attachment Fields, remove the ones you don't want.

The Attachment results will display below or above the original results, depending on whether you choose to attach it After or Before.
> 1 votes

# Answer
Try preprocessing the views field.

Something like this is a good starting place: https://drupal.stackexchange.com/a/36712/80164

Note that if you only need to preprocess a certain field, the function to use is `template_preprocess_views_view_field(&$vars)`:

https://api.drupal.org/api/drupal/core%21modules%21views%21views.theme.inc/function/template\_preprocess\_views\_view\_field/8.6.x
> 0 votes

---
Tags: views, 8
---


# Question
Title: Why doesn't drupal.org/download give a link to the Drupal 7 version?
Friend asked how to get the latest d7 version. I said go to the Download link, eg under Build \> Download and Extend, or under Try Drupal \> Download.

He pointed out that it only has a button for d8 download at https://www.drupal.org/download.

Why?

# Answer
> 3 votes
Most likely because they don't want people to be confused by the two different versions and want to simply funnel folks to the latest D8 version.

Here's likely the easiest download link to share for D7 enthusiasts: https://www.drupal.org/project/drupal

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


title: HTML in table cell being escaped

text:
# Question
Title: HTML in table cell being escaped
I'm programmatically creating a table in Drupal 8, using #type =\> 'table'. I'm adding some HTML to a table cell, however the output is being escaped so that the HTML is rendered as plain text, rather than as HTML.

From everything I read, it sounds like all output in twig templates are escaped by default.

I'm guessing I can override table.html.twig, but I'm guessing (hoping) there is a way to do it when defining the table, rather than overriding the template each time I want to create a new table that has HTML.

Does anyone know how to use HTML in a table cell in D8?

# Answer
The answer (that worked for me) is to use FormattableMarkup:

use Drupal\Component\Render\FormattableMarkup;

```
$row[] = new FormattableMarkup('<span>@somevalue</span>', ['@somevalue' => 'some value']);

```
> 5 votes

# Answer
You can use inline\_template while creating Table. `inline_template` description as per documentation page:

> Provides a render element where the user supplies an in-line Twig template.

Here is example from Drupal 8 user permission page. The row cell `type` is defined as `inline_template` and HTML Markup and dynamic variables are passed to it:

```
  $form['permissions'][$perm]['description'] = array(
    '#type' => 'inline_template',
    '#template' => '<div class="permission"><span class="title">{{ title }}</span>{% if description or warning %}<div class="description">{% if warning %}<em class="permission-warning">{{ warning }}</em> {% endif %}{{ description }}</div>{% endif %}</div>',
    '#context' => array(
      'title' => $perm_item['title'],
    ),
  );

```
> 2 votes

# Answer
Works for me using '#markup'.

```
$html= ['#markup' => '<div class="any_class">HTML</div>'];

$results = [
  '#type' => 'table',
  '#header' => [t('Column 1')],
  '#rows' => [
    [render($html)]
  ]
];

```
> 2 votes

# Answer
use Drupal\Component\Render\FormattableMarkup; is a great anwser however you can also do:

```
$row['myrow']['data'] = [
  '#markup' => '<h2>HELLO</h2>',
];

```

or for links you can just

```
 $row['myrow']['data']['#links'] = [
   $operations['edit'] = [
      'weight' => -5,
      'title' => $this->t('Edit Me'),
      'url' => Url::fromRoute('entity.someroute.edit', $route_parameters),
    ];
 ];

```

Do a search in your Site for all uses of "\['data'\]\["

also you can set some classes like

```
 $row['myrow']['data']['#attributes']['class'] = ['button', 'button-action', 'button--primary', 'button--small'];

```
> 2 votes

# Answer
This worked for me:

```
  // Build row
  $rows[ $one_nid ] = array(
    'title' => array(
      'data' => $one_node->getTitle(),
      'class' => 'donkey',
    ),
    'price_change_today' => array(
      'data' => array(
        '#markup' => $price_change.'<span class="price-change-icon"></span>'.$price_percent_change,
      ),
      'class' => 'burro',
    ),
  );

// Return render array for table
return array(
  '#theme' => 'table',
  '#header' => $headers,
  '#rows' => $rows,
);

```

Thanks everyone for the code samples that helped me figure this out!
> 1 votes

---
Tags: theming
---


title: Defining a sitemap variant

text:
# Question
Title: Defining a sitemap variant
I'm trying to add a new sitemap variant using Simple XML Sitemap referenced here.

For the most part I understand it but I'm not sure where to actually place my definition and use the simple\_sitemap.generator service to add it.

If I place it inside of an alter hook it never gets recognized by the site. I'm not sure how/where to add this new variant.

Thank you for your help.

# Answer
I would have caught this question if you posted a support request ticket it in the module's issue queue.

The information in the post you are referring to is outdated. When using the newest version of the 3.x branch, you can define variants easily in the UI accessible under `admin/config/search/simplesitemap/variants`.

A variant is a sitemap instance of a particular sitemap type. When creating a variant, you can reference existing sitemap types or write your own by adding a sitemap type plugin which references URL and sitemap generator plugins.

Simple XML sitemap is heavily relying on the plugin architecture as opposed to hook architecture. Hence most of the time you would use the module's API service methods or write plugins inside of a custom module. There is still a couple of alter hooks remaining for convenience.

The 3.x branch has a release candidate which is very stable. You can read all about it in this blog post.
> 0 votes

---
Tags: 8, xml-sitemap
---


# Question
Title: How to programmatically add custom markup to every displayed user name
Drupal 8.x

I am currently using hook\_preprocess\_user().

I would like to alter the username to add some custom markup to every username.

**MYMODULE.module:**

```
function MYMODULE_preprocess_user(&$variables) {
  $variables['elements']['#user']->name->value = t('Name @newMarkup', ['@newMarkup' => ' Hello']);
}

```

This returns `Name Hello Hello`. Concatenation adds 'Hello' twice so this approach is not working.

I've also worked with user\_format\_name\_alter(&$name, $account), however, this does not seem to fit my use case.

How can I alter the username text? Not looking for a "currentUser" solution, but every user so names are changed everywhere. Reference, Views, etc.

# Answer
> 3 votes
Seems `hook_user_format_name_alter()` is your best bet. But same as in the other answer markup doesn't seem to be allowed everywhere. Normally the user name is only allowed to be a string.

The following won't work for Views for example. It will print just a string.

```
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * Implements hook_user_format_name_alter().
 */
function MYMODULE_user_format_name_alter(&$name, $account) {

  $name = new TranslatableMarkup('@name <span class="foo-bar">Foo Bar</span>', ['@name' => $name]);
}

/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_page_title(&$variables) {

  if (\Drupal::routeMatch()->getRouteName() == 'entity.user.canonical') {

    $name = $variables['title']['#markup']->__toString();
    $variables['title'] = new TranslatableMarkup('@name <span class="foo-bar">Foo Bar</span>', ['@name' => $name]);
  }
}

```

So, what I'd recommend now is, you maybe take the `*_preprocess_page_title` hook – as this is working just fine on user pages – and for all other places (references, Views etc.) you maybe create a new custom formatter or pseudo field to do the job.

# Answer
> 0 votes
```
<?php
use Drupal\user\Entity\User;

// Updating a user is a three step process:
// 1) load the user object to change
// 2) set property/field to new value
// 3) Save the user object.

// This example updates the user name.

// $uid is the user id of the user user update
$user = \Drupal\user\Entity\User::load($uid);

// Don't forget to save the user, we'll do that at the very end of code.

// Modify username
$username = $user->getUsername();
$username .= " Hello";
$user->setUsername($username); // string $username: The new user name.

// The crucial part! Save the $user object, else changes won't persist.
$user->save();

// Congratulations, you have updated a user!

```

I based this on the examples in this Github gist:

https://gist.github.com/dreambubbler/671afd7f962ae46687e41340b396d266

---
Tags: 8, theming, users
---


title: How to customize the page /node/add?

text:
# Question
Title: How to customize the page /node/add?
On Drupal 8, there is a page on /node/add. I want to customize this page by replacing the links with buttons, but I have not found a template to do that.

I have also enabled the debug mode, but there is no template suggestion.

How do I customize the page?

```
<div role="main" class="main-container container js-quickedit-main-content">
    <div class="row">

        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12" role="heading">
            <div class="region region-header">
            </div>
        </div>

        <section class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
            <a id="main-content"></a>
            <div class="region region-content">
                <h1 class="page-header">Ajouter du contenu</h1>
                <dl>
                    <dt><a href="/node/add/annonce">Annonce</a></dt>
                    <dd></dd>
                    <dt><a href="/node/add/article">Article</a></dt>
                    <dd></dd>
                    <dt><a href="/node/add/discussion">Discussion</a></dt>
                    <dd></dd>
                    <dt><a href="/node/add/recette">Recette</a></dt>
                    <dd></dd>
                </dl>
            </div>
        </section>

    </div>
</div>

```

# Answer
As very first step try the Adminimal - Responsive Administration Theme. Maybe this does already what you want. If no, then I see two options:

1. Create a sub-theme of your current back-end theme to add custom CSS.
2. Create a custom module to add your CSS to just that page.

I normally choose option 2.

The following snippet adds a custom library to the `node/add` page. And the rest is just CSS. To make certain links look like buttons.

### MYMODULE.module

```
/**
 * Implements hook_page_attachments().
 */
function MYMODULE_page_attachments(array &$attachments) {

  $route_name = \Drupal::routeMatch()->getRouteName();

  if ($route_name == 'node.add_page') {
    $attachments['#attached']['library'][] = 'MYMODULE/foobar';
  }
}

```

### MYMODULE.libraries.yml

```
foobar:
  css:
    theme:
      css/foobar.css: {}

```

### css/foobar.css

```
a.some-link {
  background-color: crimson;
  border-radius: 5px;
  color: white;
  padding: .5em;
  text-decoration: none;
}

a.some-link:focus,
a.some-link:hover {
  background-color: firebrick;
  color: white;
}

```

---

After you've updated your question it seems you want completely customized markup. Which would make your question too broad. But there are two things you need to accomplish for that. From your new custom module at best.

1. Create a new custom form with your buttons.
2. Create a new custom route to place your form.
3. Attach your CSS to your form or your route.
> 3 votes

# Answer
Forms are manipulated in Drupal 8 predominantly by using services, twig templates and yaml files, rather than hooks. Hooks are still used, but the code in the hooks is limited in comparison with Drupal 7.

On the other hand, new D8 concepts such as Services and Event Subscribers have become much more important.

Here's a good tutorial showing how to alter the Drupal 8 login form:

https://www.foreach.be/blog/how-manipulate-forms-drupal-8

Follow the steps in the tutorial to create a simple `form_overwrite` module.

When you get to the step where you create the `src/Routing/RouteSubscriber.php` file, you'll diverge slightly from the tutorial.

Instead of altering the routeSubscriber for `user.login`, you'll want to alter the one for `node.add`:

```
<?php

/**
 * @file
 * Contains \Drupal\form_overwrite\Routing\RouteSubscriber.
 */

namespace Drupal\form_overwrite\Routing;

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

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {
  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // This is the one from the linked article
    if ($route = $collection->get('user.login')) {
      $route->setDefault('_form', '\Drupal\form_overwrite\Form\NewUserLoginForm');
    }
    // This is the one you want to write
    if ($route = $collection->get('node.add')) {
      $route->setDefault('_form', '\Drupal\form_overwrite\Form\NewNodeAddForm');
    }
  }
}

```

Armed with this knowledge, you should be able to adapt the linked tutorial to suit your needs. Good luck!
> 3 votes

---
Tags: 8, theming
---


title: HTML in data of theme_table()

text:
# Question
Title: HTML in data of theme_table()
I created a table in my custom page using the following code.

```
$build = [
  'table' => [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
  ],
];

```

The first row is the following one.

```
$row = [
  'billing' => [
  'data' => $invoice . '<small>' . $label . '</small>',
];

```

In the page, the `<small>` tag is displayed as plain text. I tried to add `attributes => ['html']`, but it doesn't work.

How can I render HTML markup in a table row?

# Answer
You can use FormattableMarkup to insert variables into html markup:

```
use Drupal\Component\Render\FormattableMarkup;

  'data' => new FormattableMarkup('<b>@bar</b>', ['@bar' => $foo]);

```
> 3 votes

# Answer
```
<?php
  // Build row
  $rows[ $one_nid ] = array(
    'title' => array(
      'data' => $one_node->getTitle(),
      'class' => 'donkey',
    ),
    'price_change_today' => array(
      'data' => array(
        '#markup' => $price_change.'<span class="price-change-icon"></span>'.$price_percent_change,
      ),
      'class' => 'burro',
    ),
  );

// Return render array for table
return array(
  '#theme' => 'table',
  '#header' => $headers,
  '#rows' => $rows,
);
?>

```
> 0 votes

---
Tags: theming, 8
---


# Question
Title: How to embed videos using the video module?
I installed the video module and activated video and video ui modules using Drupal 7: https://www.drupal.org/project/video

I created a content type with a video field. Now I can upload videos with this content type.

But I am not able to embed a youtube video. I can not find any settings or any embed widget as shown here.

I want to upload videos and I want to embed videos (youtube, vimeo..). But I can not find any way to embed a video unsig this video module.

Do I have to install further modules? On the module page you can read:

> Video module allows you to embedded videos from YouTube, Vimeo, Facebook, Vine etc (Drupal 8 only) and upload videos and play using HTML5 video player.

I can not find out how to embed a video using this module. Can you help? I do not want to use another module, I want to find out how to embed videos using THIS module. Be in mind of this when you write your answer. Thank you.

# Answer
If you install the WYSIWYG module, you can enable a button for embedding videos that have been uploaded using the Video module, and then you can use that button to embed videos into content.
> 1 votes

# Answer
That's not what the Video module is for. It's for handling uploaded videos.

To get a video embed field use Video Embed Field.

> Video Embed field creates a simple field type that allows you to embed videos from YouTube and Vimeo and show their thumbnail previews simply by entering the video's url.
> 0 votes

---
Tags: 7, media
---


title: Date/Time +1h in Node

text:
# Question
Title: Date/Time +1h in Node
I have a module to import nodes with a date/time field. All times are correctly written into the database. But when I view a node or in node/edit I get the time +1 h. In Drupal I have set the timezone to Berlin, which is GMT +1 h. When I change the timezone, the time in node/view/edit is not changing.

I don't know what to do to see the correct times in nodes.

# Answer
> 2 votes
Looks like a classic "off-by-one" error. You should make sure that you are storing all date stamps in the UTC format.

Read the section on "Converting to and from UTC" here: https://www.drupal.org/node/291799

If the date/time field is storing the German time (UTC+1h) then it will end up adding another +1h when it localizes the time, and you'll end up one hour ahead.

"There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors."

**UPDATE:** As you say in your comment below, you can get the desired result by simply subtracting 1h from each datestamp in order to convert from Berlin time to UTC.

However, this approach will only work if you are *certain* that the time field in the import file will *always* contain UTC+1 times.

If you ever need to import files that could be in different time zones, you'll need to follow the API.

To convert a local date back to UTC to store it in the database, do:

```
$date = // local date value
$local_zone = // the name of the local timezone, e.g., 'Europe/Berlin'
$type = // the type of date value, DATE_DATETIME, DATE_ISO, or DATE_UNIX

$date = date_make_date($date, $local_zone, $type);
date_timezone_set($date, timezone_open('UTC'));

// $date now contains the UTC value of the date.
// Output it like:

print date_format_date($date, 'custom', 'm/d/Y H:i');

```

In order to generalize your database import, you would also need to include a field for the `$local_zone` for each timestamp.

It sounds like you will *always* be importing Berlin timestamps, but I just wanted to make sure that you understood the drawbacks to simply subtracting 1h from each timestamp rather than following the API.

Even if simply subtracting 1h works for you in this case, there is value to doing this the right way, in case you ever need to import a file from another timezone, or one with mixed timezones -- either in your current project, or a future one.

---
Tags: nodes, datetime
---


title: _blank attribute doesn't get set

text:
# Question
Title: _blank attribute doesn't get set
I'm trying to target on the Menu (Bootstrap) a `_blank` attribute.

This is my code. It works on my local machine.

```
if ($variables['url']->isExternal()) {
  $variables['options']['attributes'] = ['target' => '_blank'];
}

```

The HTML target.

```
<ul class="dropdown-menu">
  <li>
    <a href="https://example.com" target="_blank">MySite</a>
  </li>
<ul>

```

BUT,

In here is not working because of the "class="first".

```
<ul class="dropdown-menu">
  <li class="first">
    <a href="https://example.com/1">Example link 1</a>
  </li>
  <li>
    <a href="https://example.com/2">Example link 2</a>
  </li>
  <li class="last">
    <a href="https://example.com/3">Example link 3</a>
  </li>
</ul>

```

I'm missing something, any help? I don't want to install a module for this.

# Answer
> 2 votes
When you write `$variables['options']['attributes'] = ['target' => '_blank']` you are replacing all `attributes`, never ever do that!

Only set specific keys:
`$variables['options']['attributes']['target'] = '_blank'`.

If that key is an array, append your value:
`$variables['options']['attributes']['class'][] = 'appended_class'`

---
Tags: theming
---


title: How to know the menu ID

text:
# Question
Title: How to know the menu ID
Like a function to debug a page or something. Want to add a link via links.yml but can't get the menu 'parent' name

# Answer
> 0 votes
You can use `hook_menu_local_tasks()` or `hook_menu_local_task()`. It is primary Tabs.

```
function mymodule_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  foreach ($data['tabs'] as $key1 => $tabs) {
    foreach ($tabs['output'] as $key2 => $item) {
      // Conditionally change the link title.
      if ($item['#link']['path'] == 'some/path/here') {
        $data['tabs'][$key1]['output'][$key2]['#link']['title'] = 'New Title';
      }
    }
  }
}

```

# Answer
> 0 votes
What you're wanting is the *route name*, not menu parent name (it's changed since D7). You can retrieve a route name a couple of different ways:

* Use `Url::getRouteName()` to look up your current route:

`$path = \Drupal::service('path.current')->getPath();`
`$url = \Drupal\Core\Url::fromUri( 'internal:' . $path );`
`$url->getRouteName()`
* Use the Webprofiler module to look up the current route as you're viewing it.
* Look up URL patterns in the `router` DB table.

To see how the core node module does it for the tasks in your screenshot look at `core/modules/node/node.links.task.yml`

For further information on adding local tasks to routes, read *Providing module-defined local tasks*.

---
Tags: 8, navigation
---


# Question
Title: How to force child page added to book outline to top or bottom; update outline without clearing cache
Drupal 8. When you click the "Add child page" link at a book page, you go to "/node/add/content type" where you can create and save the child page. Upon return to the book page (assuming the book navigation block is being used to display the book outline), the newly added child is not displayed (usually) in the outline until the cache is cleared and the page refreshed. Children are displayed in alphabetical order by default.

This is challenging for content editors who enter child pages because they don't see the child they've just entered when returning to the book page, and when they do see them, the children are not listed in the order of entry.

Is there a way to:

1. Automatically clear the cache upon leaving the add child page? Or disable caching for the book navigation block, at least for users with certain roles? Or something else to allow the editor to see the added child?
2. Automatically add the child page to the top or the bottom of the book outline? Possibly by passing a weight (in the query string?) to the add child page that's placed in the "Weight" field in the Book Outline tab at the right? (Note that the parent node id IS passed via the query string and inserted into the Book and Parent item fields in the Book Outline tab.) Or something else so the editor will know where in the outline to look for the newly added child page?

To this second question, one might say, "Just have them enter the weight when creating the child page." This works fine until they drag to reorder the outline. When that happens, Drupal assigns weights beginning with -15 to the child pages, so editors aren't sure what weight to enter.

Just trying to make the process of entering child pages for books as simple as possible so there will be fewer mistakes (especially same chapter added twice, or not at all).

# Answer
> 1 votes
As an answer to the first question above about updating a book outline display without clearing the cache:

Add the following to a custom .theme file (see drupal.org/docs/8/theming) to add a tag to the cached book navigation block:

```
function YOURTHEME_preprocess_block(&$vars)
{
  if ($vars['plugin_id'] == 'book_navigation') {
    $vars['#cache']['tags'] = ['node_type:{content-type}'];
  }
}

```

Then add the following to a custom .module file (see drupal.org/docs/8/creating-custom-modules) to flush the cached book navigation block whenever a node of the specified content type is changed or deleted:

```
use Drupal\node\NodeInterface;
use Drupal\Core\Cache\Cache;

function YOURMODULE_node_presave(NodeInterface $node)
{
  if ($node->getType() == '{content-type}') {
    Cache::invalidateTags(['node_type:{content-type}']);
  }
}

function YOURMODULE_node_delete(NodeInterface $node)
{
  if ($node->getType() == '{content-type}') {
    Cache::invalidateTags(['node_type:{content-type}']);
  }
}

```

Credit to @oknate for the second half of this answer. See How do you clear cache on a block when node of certain bundle added or updated? for more detail.

---
Tags: 8, nodes
---


# Question
Title: Is it possible to make manual teaser breaks work with "Filtered HTML"?
This question is about Drupal 8.

Placing the following line inside a story node's body (I guess it also works for other content types) adds a manual teaser break:

```
<!--break-->

```

In Drupal 7, to make manual teaser breaks work with the "Filtered HTML" text format it was necessary to add `<!-->` to the text format's set of allowed HTML tags (for instance, see this "Drupal Answers" post).

In Drupal 8, however, this solution no longer works: Manual teaser breaks are silently ignored even if `<!-->` is present in the allowed HTML tags of "Filtered HTML". I have tried to add a couple of plausible seeming combinations to the "Filtered HTML" text format, such as `<!--break-->` or `<!---->`, and a couple of implausible combinations (`<!--...-->` and `<!--.*-->`), but nothing works.

I double-checked and manual teaser breaks work fine when I switch a story's text format to "Full HTML" text format.

How can I get manual teaser breaks to work again with "Filtered HTML" in Drupal 8? If this is not possible I will have to go through all nodes of my site after the D7 \> D8 migration and switch them to "Full HTML".

# Answer
This comes down to being a problem of `DomDocument` and its childNodes property that does not include `DomComments`. Specifically, `Drupal\filter\Plugin\Filter\FilterHtml::getHtmlRestrictions()` will not consider any comment-like tags that are added in the 'allowed HTML tags' list. This is due to these lines in that function's code:

```
$html = str_replace('>', ' />', $this->settings['allowed_html']);
// Protect any trailing * characters in attribute names, since DomDocument
// strips them as invalid.
$star_protector = '__zqh6vxfbk3cg__';
$html = str_replace('*', $star_protector, $html);
$body_child_nodes = Html::load($html)->getElementsByTagName('body')->item(0)->childNodes;

```

This loads the text of the 'allowed HTML tags' text as an HTML DomDocument and retrieves the list of the children. Only 'proper' HTML tags will be listed as part of the `childNodes` property and therefore, the Drupal 7 workaround will not work for Drupal 8.

In order to solve this, one could override the `FilterHtml` plugin in order to allow `<!--break-->` to remain in the text.

One attempt following this approach exists here:

https://www.drupal.org/project/drupal8breaks

which was in turn inspired by

https://medium.com/@djphenaproxima/how-to-bend-drupal-8-plugins-to-your-nefarious-will-94da0c31f095

Good luck!

P.S.: Also available on GitHub https://github.com/stefanospetrakis/drupal8breaks
> 5 votes

---
Tags: 8, input-formats
---


title: Can't edit Panels content

text:
# Question
Title: Can't edit Panels content
When trying to change the Panel content design, there are no controls displayed as shown:

This is happening only when using Charts in my Panel page. I got this error chrome inspector console:

`Uncaught SyntaxError: Unexpected token , in JSON at position 6
 at JSON.parse (<anonymous>)
 at Function.parseJSON (jquery.js?v=1.4.4:32)
 at HTMLDivElement.<anonymous> (charts_highcharts.js?v=1.0:11)
 at Function.each (jquery.js?v=1.4.4:34)
 at $.fn.init.each (jquery.js?v=1.4.4:27)
 at $.fn.init.$.fn.once (jquery.once.js?v=1.2:55)
 at Object.Drupal.behaviors.chartsHighcharts.attach (charts_highcharts.js?v=1.0:9)
 at Object.<anonymous> (drupal.js?pj2bso:112)
 at Function.each (jquery.js?v=1.4.4:33)
 at Object.Drupal.attachBehaviors (drupal.js?pj2bso:110)
parseJSON @ jquery.js?v=1.4.4:32
(anonymous) @ charts_highcharts.js?v=1.0:11
each @ jquery.js?v=1.4.4:34
each @ jquery.js?v=1.4.4:27
$.fn.once @ jquery.once.js?v=1.2:55
Drupal.behaviors.chartsHighcharts.attach @ charts_highcharts.js?v=1.0:9
(anonymous) @ drupal.js?pj2bso:112
each @ jquery.js?v=1.4.4:33
Drupal.attachBehaviors @ drupal.js?pj2bso:110
(anonymous) @ drupal.js?pj2bso:593
ready @ jquery.js?v=1.4.4:30
u @ jquery.js?v=1.4.4:38`

# Answer
Found the solution here: can't edit panels page with highcharts chart in quicktab (w/ workaround)
> 1 votes

---
Tags: 7, panels
---


# Question
Title: How to get the correct 'base hook' to override a template file in a custom module?
How can I find the 'base hook' to override a template file using a custom module?

'node' and 'user' are pretty straightforward, but others can be a little more elusive.

Example code...

MYMODULE.module:

```
/**
 ** Implements hook_theme().
 **/
function MYMODULE_theme($existing, $type, $theme, $path) {
  return [
    'username' => [
      'template' => 'username',
      'base hook' => 'how do you get this?',
    ],
  ];
}

```

# Answer
> 8 votes
Look into the \*.module file where the base hook is defined, in this case the User module. The base hook is the key of the template definition:

*user.module:*

```
/**
 * Implements hook_theme().
 */

function user_theme() {
  return [
    ...
    'username' => [
      'variables' => ['account' => NULL, 'attributes' => [], 'link_options' => []],
    ],
  ];
}

```

Then in your \*.module file

*mymodule.module*

```
/**
 * Implements hook_theme().
 */
function mymodule_theme() {
  return [
    'username__mymodule_template' => [
      'base hook' => 'username',
    ],
  ];
}

```

Start the name of your own hook with the base hook and double underscores.

---
Tags: 8, theming, hooks
---


# Question
Title: Is it possible to update module provided configuration schema in an hook_update_N()?
So I have a custom module with a module.schema file, defining a configuration schema for that module, not talking about database/field schema.

```
module.settings:
type: config_object
label: 'Settings for Module'
mapping:
  my_ids:
   type: sequence
   label: 'Ids from config'
   sequence:
    type: string
    label: 'ids'

```

I provided a module.settings file like:

```
my_ids:
 - 1
 - 2
 - 3
 - 4

```

**As you can see, my mistake is that I needed a `type: int` in my schema not `type: string`.**

On the configuration synchronization page I see Drupal has taken care of this and corrected this in its active configuration, by setting string values for "my\_ids", and of course producing a diff between the staged and active configuration. The active conf has now strings:

```
my_ids:
 - "1"
 - "2"
 - "3"
 - "4"

```

I would like to update the schema of that configuration to `int`, without re-installing that module.Is this possible.

Tried to write to schema service in an update hook like:

```
  $name = 'module.schema';
  $path = '/home/user/Drupal/docroot/modules/module/config/schema';
  $source = new FileStorage($path);
  /** @var \Drupal\Core\Config\ExtensionInstallStorage $active_schema */
  $active_schema = \Drupal::service('config.storage.schema');
  $active_schema->write($name, $source->read($name));

```

But it turns out that `"Write operation is not allowed."` and that does not sound like a surprise.. :)

So is there another solution for this schema update, except re-installing the module?

Thank you.

# Answer
Well it turns out I spent some time here because I tried to update the schema file, by typing `int` not `integer` LOL. All I needed was `integer` and clear caches after all :)
> 3 votes

# Answer
I think everything you need is here: https://www.drupal.org/docs/8/api/update-api/updating-configuration-in-drupal-8

The second example should be your case
> 2 votes

---
Tags: 8, configuration
---


title: User added with Drush not working

text:
# Question
Title: User added with Drush not working
So, I have to work on a D8 site I don't have a user account for. So, when I brought the code and database over to my local environment, I thought this would be an easy fix for drush.

My local dev environment is an Ubuntu server running on WSL, with php 7.2, and Drush version 8 I used the `Drush ucrt` and `urol` in the terminal, and both returned successes. I also had to temporarily deactivate the basic\_auth service as the login pages weren't accessible after the move. Finally, when I tested the new user and password, it didn't work. I cleared the caches, re-set the password again, and then finally had the account blocked from too many failed attempts.

What's going on here? why didn't this work? and what do I do to make it work? I'd rather not add the user in Mysql, as I haven't seen a good tutorial for this.

# Answer
> 2 votes
what i personally usually do with local databases is overriding the admin password:

```
drush uinf 1

```

will help you to get the user 1 name (just to be sure it is 'admin') in that case :

```
drush upwd admin --password=MY_LOCAL_PASSWORD

```

then go to /user and try it :)

# Answer
> 0 votes
You should also be able to log in as user 1 by using:

```
drush uli

```

https://drushcommands.com/drush-8x/user/user-login/

This will generate a one-time login link:

`http://default/user/reset/1/{numbers}/{jibba-jabba}/login`

To use this, copy everything *after* `http://default` and paste it after the domain in your local dev environment.

**UPDATE:** https://drupal.stackexchange.com/a/54108/80164 shows a better way to include your dev domain instead of `http://default`.

Once you're logged in as User 1, you should be able to reset the password for that account, or create a new user account for yourself.

Drush documentation: https://drushcommands.com

---
Tags: 8, users, drush
---


title: CSV row number as key

text:
# Question
Title: CSV row number as key
In the Drupal 7 migrate module, you can use 'csvrownum' as the mapping key when migrating content from a CSV (https://www.drupal.org/node/1152158). For the Drupal 8 version, I am not sure what the equivalent is. Here is my yml file configuration (migrate plus):

```
id: timesheet_data
label: Importing Timesheet
migration_group: csvimport
migration_tags:
  - node
  - csvimport
source:
  plugin: csv
  path: 'somepath/timesheet.csv'
  header_row_count: 1
  keys:
    - csvrownum
  column_names:
    0:
      name: Name of Contact
    1:
      address: Address
destination:
  plugin: 'entity:node'
  default_bundle: timesheets
process:
  title: name

```

I tried this approach thinking it might be similar to the drupal 7 migrate module. I also tried not specifying a key, both resulted in an error.

# Answer
> 0 votes
I couldn't find a way to do this, but I found out you can specify multiple keys to make the row more unique for mapping.

```
keys:
- name
- address

```

When I applied more keys as a mapping, all the records imported since it was more unique.

Hopefully this helps someone else.

---
Tags: 8, migrations
---


# Question
Title: How to get value from {{ item.content }}
I have a node named "reviews" and a custom field named "field\_rating". I created a field template named `field--node--field_rating--reviews.html.twig`.

I want inside the node to change the color with an if statement.

I try to do something like that:

```
{% for item in items %}
  {% if item.content > 5 %}
    <div style="background-color:green">{{ item.content }}</div>
  {% endif %}
{% endfor %}

```

but it doesn't work.

Any suggestions?

Drupal Version 8.6.1

# Answer
You are comparing an array with a number:

```
item.content > 5

```

Try the field value instead:

```
element['#items'][key].value > 5

```

Full code example:

```
{% for key, item in items %}
  {% if element['#items'][key].value  > 5 %}
    <div style="background-color:green">{{ item.content }}</div>
  {% endif %}
{% endfor %}

```
> 4 votes

# Answer
Although it is of course possible to implement this kind of logic in Twig (check Hudri's comment of your question), but I would opt for using a preprocess function. In addition, I also recommend to add an extra class attribute, instead of adding an inline style. From my experience, implementing the functionality in this way provides a lot more flexibility. In your (sub-)theme's .theme or custom module's .module file, you can add something like:

```
/**
 * Implements hook_preprocess_field() for field_rating.
 */
function THEMENAME_preprocess_field__field_rating(&$variables) {
  foreach ($variables['items'] as &$item) {
    if ($item['#key_of_the_value_you_want_to_check'] > 5) {
      $item['content']['#attributes']['class'][] = 'extra_class_attribute';
    }
  }
}

```

In your css (or Sass) you can then assign the styling:

```
.extra_class_attribute {
  background-color: green;
}

```

In the case you needed a wrapping element around your field, you can set the `#prefix` and `#suffix` properties of the render array (instead of the `#attributes`).
> 2 votes

# Answer
I notice that you said:

> I have a node named "reviews"

I just wanted to make sure that you meant that you have a Content Type with the machine name "reviews", and not a node title or pathname.

Otherwise, the field template named `field--node--field_rating--reviews.html.twig` might not even be sourced.

You can test this by printing a debugging statement in your twig template using one of the methods discussed here:

https://www.drupal.org/docs/8/theming/twig/discovering-and-inspecting-variables-in-twig-templates

Make sure that you only use this for local testing, and disable it on production environment.

If the debugging statement prints, then your template is being sourced. You can use `dump()` or `kint()` to discover and inspect variables until you find the correct one.

If the debugging statement does not print, turn on theme suggestions as shown here:

https://www.drupal.org/node/2358785

You may find that your twig template really needs to have a different name, such as `field--node--field_rating--review.html.twig`, or even just `field--field_rating.html.twig`.

I mention this because I tried the exact code that you pasted above, and it worked for me in an identically-named twig template, so it's possible that something else is at play.
> 1 votes

---
Tags: 8, theming
---


title: How do I set the theme logo?

text:
# Question
Title: How do I set the theme logo?
How can I set the logo in my custom theme in Drupal 8?

I can see that Drupal looks for the logo.svg file. I have a PNG logo.png file that I used in Drupal 7 and I would like to re-use it. I cannot set the logo as a theme setting as in Drupal 7.

Is there a way through UI or custom code in the theme to set the logo?

# Answer
# After Drupal 8.6.x

In your `THEME.info.yml` add a line like `logo: logo.png`. You need to clear cache for Drupal to detect this change.

# Before Drupal 8.6.x

Default logo file has now become `logo.svg` in Drupal 8. However, to use `logo.png` or something else, you need to add custom settings definition in your theme. To do this, add the following lines to `config/install/THEME.settings.yml` file in your theme folder (replace `THEME` with your theme's machine name).

```
logo:
  path: 'themes/THEME/logo.png'
  use_default: false

```

After doing this, you must reinstall your theme if already installed. The file asks Drupal to install the given settings when the theme is installed. Hence, when you install the theme, the logo `path` parameter gets saved to the database and the default logo is disabled by the `use_default` parameter.
> 21 votes

# Answer
For regular themes, you can just go to the appearance page, go to the settings tab and deselect `Use the logo supplied by the theme`. The upload form that appears allows to upload another image instead.

If you are actually building the theme and want to supply a default image, please refer to one of the other answers.
> 8 votes

# Answer
As of Drupal 8.6 your contrib or custom theme (say it's called mythemename) can easily define the default logo in its `mythemename.info.yml` file:

`logo: images/acme-logo-stacked.png`

See https://www.drupal.org/docs/8/theming-drupal-8/defining-a-theme-with-an-infoyml-file#logo

Note that to be used the logo `use_default` setting must be true.
> 6 votes

# Answer
In the MYTHEME.theme file of your theme, add the following code.

```
/**
 * Implements hook_preprocess_HOOK() for block templates.
 */

function MYTHEME_preprocess_block(&$variables) {
  switch ($variables['base_plugin_id']) {
    case 'system_branding_block':
      $variables['site_logo'] = '';
      if ($variables['content']['site_logo']['#access'] && $variables['content']['site_logo']['#uri']) {
        $variables['site_logo'] = str_replace('.svg', '.png', $variables['content']['site_logo']['#uri']);
      }
      break;

  }
}

```

Put the logo file in the MYTHEME directory. Replace MYTHEME with the machine name of your theme.
> 5 votes

# Answer
In Drupal 8, the default logo needs to be a SVG file. You can still use a PNG file with a custom logo, or if the theme has extra custom settings to give support to non-SVG default logos.

This is what reported in The default logo type for themes is SVG, a change record for Drupal 8.0.0-beta5.

As reported in the comment, you could also use the following in the theme settings file.

```
logo:
  path: 'themes/THEME_NAME/logo.png'
  use_default: false

```

This would automatically use a custom logo without setting it from the UI.
> 4 votes

# Answer
In */your-drupal-folder/themes/THEME.theme* file add this:

```
function THEME_preprocess_page(&$variables) {
  global $base_url, $base_path;
  $variables['logo'] = $base_url . $base_path . drupal_get_path('theme','THEME') . '/logo.svg';

  ##Uncomment this if you want to use png instead of svg image
  #$variables['logo'] = str_replace('.svg', '.png', $variables['logo']);
}

```
> 3 votes

# Answer
In Drupal 8.6 this can be set in your .info.yml file as follows:

```
logo: 'images/MY_THEME_LOGO.png'

```

the theme path is automatically added to the src path
> 1 votes

# Answer
I don't think you need to change the code. In some cases, `Global settings` might be stopping you to take the respective theme logo. Hence, make sure `LOGO IMAGE` of **Global Settings** and **your theme logo** should be same in Drupal 8(Some cases).
> 0 votes

# Answer
A simple option is to place the logo in a custom block.

> /admin/structure/block/block-content

this is flexible and particularely useful if u want that logo to show up sowehat different in other sections of the site
> 0 votes

---
Tags: 8, media
---


# Question
Title: add an id to an element that doesn't have
So, I want to create an onclick event with javascript for each option of a "select form" when clicked, but since drupal doesn't use HTML I can't modify it manually and put an id to each. This is the exact element I want to change (pic below). Can I do it modifying the php of the theme? I took a look at it but didn't make sense to me. (This is the Chrome inspect tool)

# Answer
Actually `<option>` is not a valid target, see this: https://stackoverflow.com/a/1402268/9976763

You should bind the https://api.jquery.com/change/ event for the `<select>` instead and check if the given option is selected or not. For that, you do not need to put an ID on the option.

Also check https://www.drupal.org/docs/7/api/javascript-api on how to write Javascript properly for Drupal.
> 1 votes

---
Tags: entities
---


# Question
Title: Is it necessary to clear site caches after putting site into maintenance mode?
I enabled maintenance mode on a Drupal 7 site; however, when I checked the homepage as an anonymous user, I noticed that the original homepage was still being displayed rather than the maintenance page. It was only after clearing the site's caches that the maintenance page was displayed. Anonymous page caching is enabled on the site.

I am wondering if it is necessary to clear the site cache's for maintenance mode be be effective or is it sufficient to just enable maintenance mode in the admin UI? My main objective to be able to safely run database updates, which should be run whilst the site is in maintenance mode. The actual display of the maintenance page is not really important.

# Answer
> 0 votes
As you stated that 'The actual display of the maintenance page is not really important' hence it is not necessary to clear the site caches in this case.

But it is best practice to do so, because if any user interactions like forms are there, user will be getting error messages!!

---
Tags: 7, caching, updating, maintenance-mode
---


# Question
Title: use-ajax class for ajax link not working in dynamic content load
use-ajax class link not working when i load new content using custom ajax code, which has the use-ajax class links.

I use normal jquery ajax to load the content because, i have drag and drop functionality which use ajax to load new content

i tried a lot but didn't get the idea why it is not working

Thanks in advance

```
jQuery(".clips-list .section-add-clip").droppable({
        accept: '.mysrapbook-clip-drag',
        hoverClass: "ui-state-active",
        drop: function(event, ui) {
            var source_url = ui.draggable.find('a').attr('rel');
            var destination_url = jQuery('.scrapbook-mongo-id').data('scrapbooid');
            var section_idx = Number(jQuery(this).attr('rel'));
            var ul_container = jQuery(this).parent().parent().find('li.clips-inner');

            var post_data = {
                source_url: source_url,
                destination_url: destination_url,
                idx: section_idx,
                load_node: 1,
                index_countr: ul_container.length
            };
            var ajax_data = jQuery(this);

            //call ajax to save clip to haggadah
            jQuery.ajax({
                url: "/clip-to-page",
                data: post_data,
                type: 'POST',
                success: function(data) {
                    //console.log(data);
                    console.log(data);
                    if (data[1].data != "") {
                        ul_container.last().after('<li class="clips-inner clip-idx-' + post_data.idx + '-id-' + post_data.index_countr + '">' + data[1].data + '</li>');
                    }
                }
            });
        }
    });

```

here is the code where i fire ajax to load new content and that content has 'use-ajax' class link which is not working it works fine page page is loaded

# Answer
When you using jQuery load ajax content you need call Drupal behaviors manually to apply use-ajax and other Drupal behaviors for new content:

```
        jQuery.ajax({
            url: "/clip-to-page",
            data: post_data,
            type: 'POST',
            success: function(data) {
                Drupal.attachBehaviors();
            }
        });

```
> 1 votes

# Answer
Did you use Drupal.behaviors? Javascript event listeners that are attached to DOM objects at the jQuery(document).ready event won't be attached to ajax-loaded stuff. Drupal.behaviors sort that out for you.
> 0 votes

# Answer
I had the same problem. Using **Drupal 8** and drupal.behaviour. My call is done via a periodicalupdater script that load a link which is itself 'ajax enabled' with the class 'use-ajax'. But behavious does not enable ajax to the link. I solved the above problem by calling another function after the link is returned and displayed. So this function should be called in from your script in 'success'

probably:

```
success: function(data) {
                //console.log(data);
                console.log(data);
                if (data[1].data != "") {
                    your code + **addajax();**
                }
            }

```

Maybe there is a better solution, but this one works.

**the function is this one:**

```
function addajax() {
  // Bind Ajax behaviors
  jQuery('.use-ajax:not(.ajax-processed)').addClass('ajax-processed').each(function ()    {
    var element_settings = {};
    // Clicked links look better with the throbber than the progress bar.
    element_settings.progress = { 'type': 'throbber' };

    // For anchor tags, these will go to the target of the anchor rather
    // than the usual location.
    if (jQuery(this).attr('href')) {
      element_settings.url = jQuery(this).attr('href');
      element_settings.event = 'click';
    }
    var base = jQuery(this).attr('id');
    Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
  });
    }

```

inspired from http://drupalapi.attiks.com/api/drupal/misc%21ajax.js/property/Drupal.behaviors.AJAX/7
> 0 votes

# Answer
this is the solution I use for D8.

//html code

```
  <a href="#url" title="" id="link-dismiss-buynow" class="use-ajax">title</a>

```

//how to call

```
  $('#link-dismiss-buynow').attachAjaxToDynamicLink();

```

//magic function

```
  $.fn.attachAjaxToDynamicLink = function() {

    var base = $(this).attr('id');
    var elementSettings = {
      base: base,
      progress : { 'type': 'throbber' },
      url : $(this).attr('href'),
      event : 'click'
    };
    elementSettings.selector = '#' + base;
    $(elementSettings.selector).once('drupal-ajax').each(function () {
      elementSettings.element = this;
      elementSettings.base = base;
      Drupal.ajax(elementSettings);
    });
  }

```
> 0 votes

---
Tags: ajax, navigation
---


# Question
Title: How to setup different confirmation email per webform instance
Background: I have a ContactUs webform made by Drupal 8 webforms contrib module and used that ContactUs Form on 3 different pages.

Is it possible to setup 3 different confirmation emails per instance?

Many tanks

# Answer
> 0 votes
You can pass a custom confirmation message from a Webform node to the Webform email handler using a token like `[webform_submission:node:field_confirmation_message]`

---
Tags: 8, webforms
---


title: Webform to content type

text:
# Question
Title: Webform to content type
In the Webform module version 8.x-5.0-rc27 there isn't the tab to add a webform to a certain content type.

Is this intentional? If not, is there a workaround for this issue?

# Answer
> 3 votes
The Webform (node) References tab should still be working as expected in rc27.

---
Tags: 8, webforms
---


title: Access_Callback problem

text:
# Question
Title: Access_Callback problem
From time to time (and anytime after I run "drush cc all") my custom module with an access callback returns an 'access denied' error for Admins when they attempt to edit a user. I can solve this issue by disabling and re-enabling (any) module -- not just the one with the access callback code. If I remove this code, an admins ability to edit a user is fully and permanently restored. Here is the code in my custom module:

```
function cs_menu_alter(&$items) {
    $items['user/%/edit']['access callback'] = 'cs_user_edit_access';
}
function cs_user_edit_access() {
    global $user;
    if (!user_has_role(3, $user) || !user_has_role(4, $user)) {
        return FALSE;
    }
    else {
        return TRUE;
    }
}

```

I don't know why this code would suddenly stop working, but I don't really want to lose the functionality that this custom code supplies (most of the time).

# Answer
I was able to solve for my use case by dropping the secondary function, and just using the following code:

```
function cs_menu_alter(&$items) {
  $items['user/%user/edit']['access arguments'] = array('administer users');
  $items['user/%user/edit']['access callback'] = 'user_access';
}

```
> 0 votes

---
Tags: users
---


# Question
Title: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away:
After entering some custom fields, I went to /content and now I am getting the following error:

> SQLSTATE\[HY000\]: General error: 2006 MySQL server has gone away.

I've tried the following with no success:

* Cleared cache (via drush)
* Rebuilt Docker Container with increase in PHP config’s `max_allowed_packet` (recommended by several posts online).
* Restart `container/docker`.

*If I connect to another database, I don't see the error.* Database connection was fine, this error happened after making changes to fields in Drupal Admin UI. The other answers seem to be for issues connecting to SQL, I have no such issues. Just specefic to the contents of a single database.

Here is the complete error:

> Additional uncaught exception thrown while handling exception. Original
>
> Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE\[HY000\]: General error: 2006 MySQL server has gone away: CREATE TABLE {cache\_default} ( `cid` VARCHAR(255) BINARY CHARACTER SET ascii COLLATE ascii\_general\_ci NOT NULL DEFAULT '' COMMENT 'Primary Key: Unique cache ID.', `data` LONGBLOB NULL DEFAULT NULL COMMENT 'A collection of data to cache.', `expire` INT NOT NULL DEFAULT 0 COMMENT 'A Unix timestamp indicating when the cache entry should expire, or -1 for never.', `created` DECIMAL(14, 3) NOT NULL DEFAULT 0 COMMENT 'A timestamp with millisecond precision indicating when the cache entry was created.', `serialized` SMALLINT NOT NULL DEFAULT 0 COMMENT 'A flag to indicate whether content is serialized (1) or not (0).', `tags` LONGTEXT NULL DEFAULT NULL COMMENT 'Space-separated list of cache tags for this entry.', `checksum` VARCHAR(255) CHARACTER SET ascii COLLATE ascii\_general\_ci NOT NULL COMMENT 'The tag invalidation checksum when this entry was saved.', PRIMARY KEY (`cid`), INDEX `expire` (`expire`), INDEX `created` (`created`) ) ENGINE = InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT 'Storage for the cache API.'; Array ( ) in Drupal\views\ViewsData-\>cacheSet() (line 211 of /var/www/html/core/modules/views/src/ViewsData.php).
>
> Drupal\views\ViewsData-\>cacheSet('views\_data', Array) (Line: 259) Drupal\views\ViewsData-\>getData() (Line: 162) Drupal\views\ViewsData-\>get('block\_content') (Line: 91) Drupal\views\Plugin\Derivative\ViewsEntityRow-\>getDerivativeDefinitions(Array) (Line: 101) Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator-\>getDerivatives(Array) (Line: 87) Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator-\>getDefinitions() (Line: 284) Drupal\Core\Plugin\DefaultPluginManager-\>findDefinitions() (Line: 175) Drupal\Core\Plugin\DefaultPluginManager-\>getDefinitions() (Line: 147) views\_theme(Array, 'module', 'views', 'core/modules/views') (Line: 447) Drupal\Core\Theme\Registry-\>processExtension(Array, 'views', 'module', 'views', 'core/modules/views') (Line: 334) Drupal\Core\Theme\Registry-\>build() (Line: 233) Drupal\Core\Theme\Registry-\>get() (Line: 86) Drupal\Core\Utility\ThemeRegistry-\>initializeRegistry() (Line: 67) Drupal\Core\Utility\ThemeRegistry-\>\__construct('theme\_registry:runtime:seven', Object, Object, Array, 1) (Line: 253) Drupal\Core\Theme\Registry-\>getRuntime() (Line: 142) Drupal\Core\Theme\ThemeManager-\>render('html', Array) (Line: 437) Drupal\Core\Render\Renderer-\>doRender(Array, 1) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array, 1) (Line: 139) Drupal\Core\Render\Renderer-\>Drupal\Core\Render{closure}() (Line: 582) Drupal\Core\Render\Renderer-\>executeInRenderContext(Object, Object) (Line: 140) Drupal\Core\Render\Renderer-\>renderRoot(Array) (Line: 66) Drupal\Core\Render\BareHtmlPageRenderer-\>renderBarePage(Array, Object, 'install\_page', Array) (Line: 76) Drupal\Core\ProxyClass\Render\BareHtmlPageRenderer-\>renderBarePage(Array, Object, 'install\_page', Array) (Line: 1005) install\_display\_output(Array, Array) (Line: 156) install\_drupal(Object) (Line: 44)
>
> Additional
>
> Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE\[HY000\]: General error: 2006 MySQL server has gone away: CREATE TABLE {cache\_default} ( `cid` VARCHAR(255) BINARY CHARACTER SET ascii COLLATE ascii\_general\_ci NOT NULL DEFAULT '' COMMENT 'Primary Key: Unique cache ID.', `data` LONGBLOB NULL DEFAULT NULL COMMENT 'A collection of data to cache.', `expire` INT NOT NULL DEFAULT 0 COMMENT 'A Unix timestamp indicating when the cache entry should expire, or -1 for never.', `created` DECIMAL(14, 3) NOT NULL DEFAULT 0 COMMENT 'A timestamp with millisecond precision indicating when the cache entry was created.', `serialized` SMALLINT NOT NULL DEFAULT 0 COMMENT 'A flag to indicate whether content is serialized (1) or not (0).', `tags` LONGTEXT NULL DEFAULT NULL COMMENT 'Space-separated list of cache tags for this entry.', `checksum` VARCHAR(255) CHARACTER SET ascii COLLATE ascii\_general\_ci NOT NULL COMMENT 'The tag invalidation checksum when this entry was saved.', PRIMARY KEY (`cid`), INDEX `expire` (`expire`), INDEX `created` (`created`) ) ENGINE = InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT 'Storage for the cache API.'; Array ( ) in Drupal\views\ViewsData-\>cacheSet() (line 211 of /var/www/html/core/modules/views/src/ViewsData.php).
>
> Drupal\views\ViewsData-\>cacheSet('views\_data:block\_content', Array) (Line: 178) Drupal\views\ViewsData-\>get('block\_content') (Line: 91) Drupal\views\Plugin\Derivative\ViewsEntityRow-\>getDerivativeDefinitions(Array) (Line: 101) Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator-\>getDerivatives(Array) (Line: 87) Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator-\>getDefinitions() (Line: 284) Drupal\Core\Plugin\DefaultPluginManager-\>findDefinitions() (Line: 175) Drupal\Core\Plugin\DefaultPluginManager-\>getDefinitions() (Line: 147) views\_theme(Array, 'module', 'views', 'core/modules/views') (Line: 447) Drupal\Core\Theme\Registry-\>processExtension(Array, 'views', 'module', 'views', 'core/modules/views') (Line: 334) Drupal\Core\Theme\Registry-\>build() (Line: 233) Drupal\Core\Theme\Registry-\>get() (Line: 86) Drupal\Core\Utility\ThemeRegistry-\>initializeRegistry() (Line: 67) Drupal\Core\Utility\ThemeRegistry-\>\__construct('theme\_registry:runtime:seven', Object, Object, Array, 1) (Line: 253) Drupal\Core\Theme\Registry-\>getRuntime() (Line: 142) Drupal\Core\Theme\ThemeManager-\>render('html', Array) (Line: 437) Drupal\Core\Render\Renderer-\>doRender(Array, 1) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array, 1) (Line: 139) Drupal\Core\Render\Renderer-\>Drupal\Core\Render{closure}() (Line: 582) Drupal\Core\Render\Renderer-\>executeInRenderContext(Object, Object) (Line: 140) Drupal\Core\Render\Renderer-\>renderRoot(Array) (Line: 66) Drupal\Core\Render\BareHtmlPageRenderer-\>renderBarePage(Array, 'Error', 'install\_page', Array) (Line: 76) Drupal\Core\ProxyClass\Render\BareHtmlPageRenderer-\>renderBarePage(Array, 'Error', 'install\_page', Array) (Line: 1005) install\_display\_output(Array, Array, Array) (Line: 260) \_drupal\_log\_error(Array, 1) (Line: 600) \_drupal\_exception\_handler(Object)

# Answer
See this question:

Database general error: 2006 MySQL server has gone away

Basically, you need to increase the MySQL max\_allowed\_packet setting. There is an option as well to compress cached data if you can't.

http://drupal.org/node/1281408
> 5 votes

---
Tags: 8, database
---


# Question
Title: How do I embed a form in a controller response?
I have a controller that returns a normal renderable page array. I'd like to embed a form in that page, but the form is not appearing in the rendered output. The form is properly added to the renderable array correctly, but it's not in the final HTML for some reason. What's going on here?

Here's my controller (which extends ControllerBase through BlockController):

```
use Drupal\block\Controller\BlockController;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Render\Element;
use Symfony\Component\DependencyInjection\ContainerInterface;

class LayoutController extends BlockController {

  /**
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $formBuilder;

  /**
   * {@inheritdoc}
   */
  public function __construct(ThemeHandlerInterface $theme_handler, FormBuilderInterface $form_builder) {
    parent::__construct($theme_handler);
    $this->formBuilder = $form_builder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('theme_handler'),
      $container->get('form_builder')
    );
  }

  /**
   * Overrides the region demo page, adding placeholder elements for sortable
   * lists of blocks, plus a control panel form.
   *
   * @param string $theme
   *   The theme key.
   *
   * @return array
   *   The renderable page.
   */
  public function layout($theme) {
    $page = parent::demo($theme);

    foreach (Element::children($page) as $region) {
      if (isset($page[$region]['block_description'])) {
        $page[$region]['block_description']['#template'] .= '<ul data-region="{{ region }}"></ul>';
        $page[$region]['block_description']['#context']['region'] = $region;
      }
    }
    $page['layout_control'] = $this->formBuilder->getForm('Drupal\block_ui\Form\LayoutControlForm');
    $page['#attached']['library'][] = 'block_ui/backbone.collectionView';

    return $page;
  }

}

```

# Answer
> 10 votes
To embed a form in a renderable array, you use:

```
$form_class = '\Drupal\my_module\Form\MyForm';
$build['form'] = \Drupal::formBuilder()->getForm($form_class);

```

Which is similar to your code.

But the problem is of a different nature. You are extending a special controller, one that returns a renderable array of `'#type' => 'page'`. It uses the page template to render the output and that template does not contain the `{{ layout_control }}` variable to output your form. If you use `$page['header']['layout_control'] = ...` to add the form to the render array, it should show the form in the header region of the layout demo page.

# Answer
> 11 votes
You can render a form and place it wherever you want in your markup.

In your controller method, you want to do `$this->formBuilder()->getForm()` and then render that form array using `\Drupal::service('renderer')->render()`

I'm not sure what side effects this might have with submission / error control if you have multiple forms on a single page but it is possible to do it.

See below controller

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\Markup;

class MyController extends ControllerBase
{

    public function displayForm()
    {

        $myForm = $this->formBuilder()->getForm('Drupal\my_module\Form\MyForm');
        $renderer = \Drupal::service('renderer');
        $myFormHtml = $renderer->render($myForm);

        return [
            '#markup' => Markup::create("
                <h2>My Form is Below</h2>
                {$myFormHtml}
                <h2>My Form is Above</h2>
            ")
        ];
    }
}

```

# Answer
> 2 votes
So it turns out that Drupal 8 doesn't let you to do the kind of loose, willy-nilly page alteration that Drupal 7 allowed. Instead, you have to use one of the hooks which replace hook\_page\_build() and hook\_page\_alter(). In particular, hook\_page\_top() and hook\_page\_bottom() are where you can insert arbitrary renderable elements.

There's an API change record explaining this: https://www.drupal.org/node/2357755.

Here's the code I used to fix my problem (in the .module file):

```
/**
 * Implements hook_page_bottom().
 */
function block_ui_page_bottom(array &$page_bottom) {
  $route_match = \Drupal::routeMatch();

  if ($route_match->getRouteName() == 'block.admin_display_theme') {
    $region_list = system_region_list($route_match->getParameter('theme'), REGIONS_VISIBLE);
    $form_state = new FormState();
    $form_state->set('region_list', $region_list);
    $page_bottom['layout_control'] = \Drupal::formBuilder()->buildForm('\Drupal\block_ui\Form\LayoutControlForm', $form_state);
  }
}

```

---
Tags: forms, 8
---


# Question
Title: How to make a select form element with textfields for the array id and key?
In a custom module which I'm working on, I have a select list which currently has a hard-coded array of key=\>value which could change and I would like to expose these options to the user.

I would like to be able to have a select form element which contains one textfield for the user to enter the ID of the option and another for the user to enter the value of the option. I *could* make a separate form for these options, but I'd like to keep all the configurations on one page since there aren't too many.

Does anyone know how I can make a select form element where the key and value of each option is keyed in by the user?

# Answer
Do you know of Drupal's core field type "List" or what it's called and its "Allowed Values" field? Where admins can enter `key|value` pairs divided by a pipe character?

It's exactly what you seem to describe.

I'd start by mimicking exactly that. But all in one form. Maybe multi-step. Maybe peppered with some Ajax...
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Date popup field won't display in tableselect element
I am attempting to embed a couple of date fields within a `tableselect` element, and after trying to use both `textfield` and `date_popup` field types, I can't get either to work. Here's my form function using textfields:

```
function language_dashboard_overview_form($form, &$form_state, $entity) {
  $form = [];
  $options = [];

  $header = [
    'language_locale' => t('Language Locale'),
    'status' => t('Status'),
    'staging_url' => t('Staging URL'),
    'start_date' => t('Start Date'),
    'end_date' => t('End Date'),
    'display_title' => t('Display Title')
  ];

  $translations = $entity->translations->data;

  foreach($translations as $locale => $locale_data) {
    // Get data for all the other fields here
    ...
    // Define start and end date text fields.
    $start_date = new DateTime($entity->field_locale_publishing_dates[$locale][0]['value']);
    $new_start_date = $start_date->format('m-d-Y');

    $end_date = new DateTime($entity->field_locale_publishing_dates[$locale][0]['value2']);
    $new_end_date = $end_date->format('m-d-Y');

    $start_date_field = [
      'data' => [
        '#type' => 'textfield',
        '#size' => 10,
        '#maxlength' => 10,
        '#default_value' => $new_start_date
      ]
    ];

    $end_date_field = [
      'data' => [
        '#type' => 'date_popup',
        '#date_format' => 'm-d-Y',
        '#date_year_range' => '0:+20',
        '#default_value' => $new_end_date
        ]
    ];

    $options[] = [
      'language_locale' => $locale_link,
      'status' => $status,
      'staging_url' => $stage_url,
      'start_date' => $start_date_field,
      'end_date' => $end_date_field,
      'display_title' => $title
    ];

  }

  $form['dashboard'] = [
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $options
  ];

  $form['submit'] = [
    '#type' => 'submit',
    '#value' => t('Submit')
  ];

  return $form;
}

```

With that, I get the fields, but no default value is filled in (and I've verified that the `$start_date_field` and `$end_date_field` variables have the desired data).

If I try it with `date_popup` fields like so:

```
$start_date_field = [
  'data' => [
    '#type' => 'date_popup',
    '#date_format' => 'm-d-Y',
    '#date_year_range' => '0:+20',
    '#maxlength' => 10,
    '#default_value' => $new_start_date
  ]
];

$end_date_field = [
  'data' => [
    '#type' => 'date_popup',
    '#size' => 10,
    '#maxlength' => 10,
    '#default_value' => $new_end_date
  ]
];

```

I get no field at all in those columns. From the multiple items I've read on this, I'm adding the fields correctly to the `tableselect`. Is there something else I'm missing?

**UPDATE:** I discovered that for the text field, you use `#value` instead of `#default_value`. changing that shows my default date as desired. so the only remaining issue is that I can't get anything to show for a `date_popup` field.

# Answer
I still can't get the date\_popup element to work in a tableselect element, so I ended up going with text field and the jQuery\_ui datepicker (included in core).

```
  $form['dates'] = [
    '#type' => 'fieldset',
    '#title' => t('Set Dates'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE
  ];

  $form['dates']['start_date_popup'] = [
    '#type' => 'date_popup',
    '#title' => t('Start Date'),
    '#date_format' => 'Y-m-d',
    '#date_year_range' => '0:+20',
    '#maxlength' => 10,
    '#date_label_position' => 'none',
    '#id' => 'apply-start-date'
  ];

  $form['dates']['end_date_popup'] = [
    '#type' => 'date_popup',
    '#title' => t('End Date'),
    '#date_format' => 'Y-m-d',
    '#date_year_range' => '0:+20',
    '#date_label_position' => 'none',
    '#id' => 'apply-end-date'
  ];

  $form['dates']['apply_dates_button'] = [
    '#type' => 'button',
    '#value'=> t('Apply Dates'),
    '#attributes' => array('id' => array('apply-dates')),
  ];

...

 'start_date' => array(
   'data'=> array(
     '#type'=>'textfield',
     '#value'=> $new_start_date,
     '#title' => 'Start Date',
     '#title_display'=>'invisible',
     '#name'=> 'start_date[' . $locale . ']',
     '#id'=>  'start-date[' . $locale . ']',
     '#attributes' => array('class' => array('datepicker')),
     '#size' => 10,
     '#maxlength' => 10
   ),
 ),
 'end_date' => array(
   'data'=> array(
     '#type'=>'textfield',
     '#value'=> $new_end_date,
     '#title' => 'End Date',
     '#title_display'=>'invisible',
     '#name'=> 'end_date[' . $locale . ']',
     '#id'=> 'end-date[' . $locale . ']',
     '#attributes' => array('class' => array('datepicker')),
     '#size' => 10,
     '#maxlength' => 10
   ),
 ),

```

and this JS behavior:

```
(function ($) {
  Drupal.behaviors.dashboardDatepicker = {
    attach: function (context, settings) {
      // Attach the datepicker to the selected fields.
      $( ".datepicker" ).datepicker({
        dateFormat: "yy-mm-dd",
        changeYear: true,
        yearRange: '-30:+30',
        minDate: '-0',
        showButtonPanel: true
      });

      // Add click handler for apply button.
      $("#apply-dates", context).click(function(event) {
        // Keep the form from being submitted.
        event.preventDefault();
        // Get the dates from the fieldset
        var startDate = $("input[id*='apply-start-date']").val();
        var endDate = $("input[id*='apply-end-date']").val();
        // Get the set of selected checkboxes.
        if(startDate) {
          $("table#locale-table").find("tr.selected").find("input[id*='start-date']").val(startDate);
        }
        if (endDate) {
          $("table#locale-table").find("tr.selected").find("input[id*='end-date']").val(endDate);
        }
      })
    }
  };
}(jQuery));

```
> 0 votes

---
Tags: 7, forms, datetime
---


# Question
Title: Moving the Sites/Default/Files Directory
We have a client with simple request to move the Public File folder up simply so that links will be shorter like `example.com/files/` instead of `example.com/sites/default/files/`.

I assumed this would just entail running

`mv ./sites/default/files/ ./files/`

in the root directory where my index.php resides and then changing the line in settings.php. Yet, this does not work, and I can't figure out why. In the `file_managed` table the uri column looks like `public://example.png`. Does that variable 'public' not resolve to the default public path?

Here's what my settings.php line reads:

```
# Change Public File directory
$settings['file_public_path'] = 'files';

```

The folder is right next to my index.php file and the entire folder, including contents is set to 775, or rwxrwxr-x.

```
drwxrwxr-x. 47 apache webgrp  28672 Nov 15 10:14 files
-rwxrwxr-x.  1 apache webgrp    648 Oct 25 08:17 index.php

```

Weirder, in the browser inspector, it appears that Drupal is looking for files at `/files/example.png` and there is definately a matching file at `/files/`. What am I missing? The only docs I can find are for Drupal 7, and all modules I've seen are only for 7 as well.

# Answer
Look in Admin \> Config \> Media \> File System:

`/admin/config/media/file-system`

> **Public file system path** `sites/default/files` A local file system path where public files will be stored. This directory must exist and be writable by Drupal. This directory must be relative to the Drupal installation directory and be accessible over the web. This must be changed in `settings.php`

So there you have it. If you want to change the file system path for the `public://` stream wrapper, you will need to edit `settings.php`.

**EDIT:** I'm not sure what else is at play here. If you still can't get this working to your client's specifications, you may be able to spoof it with a symbolic link in the file system:

```
ln -s files sites/default/files

```

The files would still be hosted in the wrong location, so this is actually no solution. Hopefully somebody else can point you in the right direction. Good luck!
> 3 votes

# Answer
Doing just a `mv` move command isn't enough. You need to set the public file path in the admin to a path accessible by the application.

In the files table, `public://` is a stream wrapper which will resolve to the public files path, but only if you have updated this configuration. Moving the files, it does not know about it.

Check that you've named the variable correctly in settings.php and also change it in the admin screen and verify both. The folder needs to be readable and writeable as well.
> 1 votes

---
Tags: 8, files
---


# Question
Title: How to mock a node field value for phpunit?
I'm working on a project where we need to have code coverage using phpunit.

I have a method that includes this code:

```
  $node = \Drupal::entityTypeManager()->getStorage('node')->load($node_id);

  $form['data-title']['#value'] = $node->label();

  $form['data-description']['#value'] = $node->field_description->value;

```

So I need to mock out the node object.

I can get the node label to work, but not the field\_description-\>value

Here's my set up function in my test class:

```
/**
   * {@inheritdoc}
   */
  protected function setUp() {
    $container = new Container();
    $container->set('string_translation', $this->getStringTranslationStub());

    $renderer = $this->getMockBuilder(Renderer::class)
      ->disableOriginalConstructor()
      ->getMock();
    $renderer
      ->method('render')
      ->willReturn('Hello world');

    $container->set('renderer', $renderer);

    // Mock entity type manager.
    $this->entityTypeManager = $this->getMockBuilder(EntityTypeManagerInterface::class)
      ->disableOriginalConstructor()
      ->getMock();

    // Mock a node and add the label to it.
    $node = $this->getMockBuilder(Node::class)
      ->disableOriginalConstructor()
      ->getMock();
    $node->expects($this->any())
      ->method('label')
      ->willReturn('shaken not stirred');

    $node->expects($this->any())
      ->method('access')
      ->willReturn(TRUE);

    $node->expects($this->any())
      ->method('id')
      ->willReturn(1);

    // @todo figure out how to add a field to a mock node.
    /*$field_description = new \stdClass();

    $field_description->value = 'This is a description';

    $node->set('field_description', $field_description);*/

    $node_storage = $this->getMockBuilder(EntityStorageInterface::class)
      ->disableOriginalConstructor()
      ->getMock();
    $node_storage->expects($this->any())
      ->method('load')
      ->willReturn($node);
    $this->entityTypeManager->expects($this->any())
      ->method('getStorage')
      ->willReturn($node_storage);

    $this->uuid = $this->getMockBuilder(UuidInterface::class)
      ->disableOriginalConstructor()
      ->getMock();

    $container->set('entity_type.manager', $this->entityTypeManager);

    $entity_repository = $this->getMockBuilder(EntityRepository::class)
      ->disableOriginalConstructor()
      ->getMock();
    $entity_repository->expects($this->any())
      ->method('getTranslationFromContext')
      ->willReturn($node);

    $container->set('entity.repository', $entity_repository);

    \Drupal::setContainer($container);
    $this->form = MyForm::create($container);

  }

```

# Answer
The following should work using PHPUnit Mock Objects as in your example.

First mock FieldItemListInterface \__get magic method.

```
$fieldDescMock = $this->getMockBuilder('\Drupal\Core\Field\FieldItemListInterface')
  ->disableOriginalConstructor()
  ->getMock();
$fieldDescMock->expects($this->any())
  ->method('__get')
  ->with('value')
  ->willReturn('blah');

```

Then mock the Node/ContentEntityBase \__get magic method.

```
$node->expects($this->any())
  ->method('__get')
  ->with('field_description')
  ->willReturn($fieldDescMock);

```
> 10 votes

# Answer
Mradcliffe's answer worked for me, here's my example code:

Here's what ended up working for me:

```
$this->node = $this->getMockBuilder(Node::class)
  ->disableOriginalConstructor()
  ->getMock();

$fieldAdsEnabled = $this->getMockBuilder(FieldItemListInterface::class)
  ->disableOriginalConstructor()
  ->getMock();
$fieldAdsEnabled->expects($this->any())
  ->method('__get')
  ->with('value')
  ->willReturn(1);
$this->node->expects($this->any())
  ->method('__get')
  ->with('field_widgets_enabed')
  ->willReturn($fieldAdsEnabled);

```

Note: for me using Node object and not NodeInterface helped. I suspect because otherwise \__get isn't available.
> 4 votes

---
Tags: 8, testing
---


# Question
Title: Your PHP version does not satisfy that requirement
We use the following for our local development environment. When we run `composer require 'drupal/module_name:^1.1'`, we get the following error message. We have doubled checked that all settings for `Acquia Dev Desktop` are set to `php7.1.11`, but still getting this message.

Error Message:

> Problem 1
>
> ```
> - symfony/browser-kit v4.1.7 requires php ^7.1.3 -> your PHP version (5.6.32) does not satisfy that requirement.
> - symfony/browser-kit v4.1.7 requires php ^7.1.3 -> your PHP version (5.6.32) does not satisfy that requirement.
> - symfony/browser-kit v4.1.7 requires php ^7.1.3 -> your PHP version (5.6.32) does not satisfy that requirement.
> - Installation request for symfony/browser-kit (locked at v4.1.7) -> satisfiable by symfony/browser-kit[v4.1.7].
>
> ```

Local Development environment:

1. Acquia Dev Desktop
2. `Dev Desktop` set to php `v7.1.1`
3. Using `git bash` by navigating to `~/Sites/local-dev/dev`

Running `php --version` in the `~/Sites/local-dev/dev` (which is one level above `docroot`) we get `php 5.6.32`

Why am I still getting the `your PHP version (5.6.32) does not satisfy that requirement` even though `Acquia Dev Desktop` is set to `phpv7.1.11`?

# Answer
After searching, I found out that I had an outdated composer so I did the following steps and now composer is seeing the correct php version.

Previous version of composer was `1.6.3` and php version `5.6.32`

Steps:

1. ran `composer self-update`
2. ran `composer diagnose` and observed the following below

> Checking platform settings: OK
>
> Checking git settings: OK
>
> Checking http connectivity to packagist: OK
>
> Checking https connectivity to packagist: OK
>
> Checking github.com oauth access: OK
>
> Checking disk free space: OK
>
> Checking pubkeys: Tags Public Key Fingerprint: xxxxx
>
> Dev Public Key Fingerprint: xxxxx
>
> OK Checking composer version: OK
>
> Composer version: 1.8.0
>
> PHP version: 7.1.11
>
> PHP binary path: C:\path\to\devdesktop\php7\_1\php.exe
> 1 votes

---
Tags: 8, installation, composer, acquia-dev-desktop
---


# Question
Title: How to change the image size within a Drupal view
Does anybody know the best way to change the image size of a field within a view using Drupal 8?

# Answer
> 4 votes
You can create an image style at admin interface and then use same style at your view settings.

Navigate to `admin/config/media/image-styles` and add new style. After that edit image field inside your view which will look like below image.

In image you can see Image style which you have created in earlier step. This way you can change the image sige at views.

---
Tags: views, 8
---


# Question
Title: How to add pagination to programmatically rendered search result template
I am trying to implement the pagination in drupal 8 custom page.

I have a custom array which I am rendering using theme, I need to add pagination for it.

```
    $internal_result = array_merge($internal_result, $basic_data);
    $response = new AjaxResponse();
    $terms['internal'] = $internal_result;
    $renderable = array(
        '#theme' => 'search_result_template',
        '#data' => $terms
    );
    $rendered = \Drupal::service('renderer')->render($renderable);

```

I need to add pagination for above result. Can anyone help me?

# Answer
I tried with the search\_result template and it worked, hope this helps you :

> ```
> $output['prefix']['#markup'] = '<h2>Test page</h2>';
> //This sets up necessary global variables for the type => #pager
> $page = pager_default_initialize(5, 2);
> $render = [];
>   $output[] = [
>     '#theme' => 'search_result',
>     '#result' => 's',
>   ];
> $pager = [
>   '#type' => 'pager',
> ];
> $output['suffix']['#markup'] = '</ol>' . \Drupal::service('renderer')->render($pager);
> return $output;
>
> ```

We just need to set up the global variables which help to process rendered array to output pagers items. And add a pager to the suffix.
> 2 votes

---
Tags: 8, theming, search, paging
---


title: Commands character limit?

text:
# Question
Title: Commands character limit?
I have 2 functions in a custom AJAX callback which are really confusing me, one returns an image from a single node, the other retrieves a list of nodes first, then loops through them and returns images from each of them, even though the code which returns the image HTML is shared by both functions, the multiple node return wraps everything in a div.

Single AJAX callback

```
function _append_thumb_to_deck($node) {
    if (!empty($node)) {
        if ($node->field_image) {
            // Load the image as a thumbnail
            $thumbnails = get_thumbnails($node);

            // Prepare an ajax command to insert the node html into our ajax wrapper.
            $commands = array();
            $commands[] = ajax_command_append('#thumbs', $thumbnails);
            $commands['effect'] = 'fade';

            // Render the commands into JSON and print them.
            print ajax_render($commands);
            exit;
        }
    }
}

```

Multiple AJAX

```
function _append_multi_thumb_to_deck($node) {
    if (!empty($node)) {
        if ($thumbs = get_thumb_list($node->nid)) {
            // get_thumb_list is just a function to return an array of Node ID => Node object
            // Load each image as a thumbnail
            foreach ($thumbs as $nid => $node) {
                if ($node->field_image) {
                    $thumbnails .= get_thumbnails($node);
                }
            }

            // Prepare an ajax command to insert the node html into our ajax wrapper.
            $commands = array();
            $commands[] = ajax_command_append('#thumbs', $thumbnails);
            $commands['effect'] = 'fade';

            // Render the commands into JSON and print them.
            print ajax_render($commands);
            exit;
        }
    }
}

```

HTML callback

```
function get_thumbnails($node) {
    $img = image_get_info($node->field_image[LANGUAGE_NONE][0]['uri']);
    $vars = array(
        'style_name' => 'thumbnail',
        'path' => $node->field_image[LANGUAGE_NONE][0]['uri'],
        'width' => $img['width'],
        'height' => $img['height'],
        'alt' => t(''),
        'title' => t(''),
        'attributes' => array(
           'data-nid' => $node->nid,
        ),
    );
    $thumbnail = theme_image_style($vars);
    $thumbnail = "<li class='thumb' data-nid='{$node->nid}'>{$thumbnail}</li>";
    return $thumbnail;
}

```

This returns something like

```
<li class="thumb" data-nid="9"><img data-nid="9" src="http://dummyimage.com/160x90/cccccc/000000.png" width="160" height="90" alt="" title=""></li>

```

I can even inspect the HTML which is intended to be returned by the multiple function and it appears to be correct, it's just a long string of multiple `li` tags containing images, properly formed HTML, no hanging tags, no opening or closing divs etc, and yet for some reason, the function to append multiple thumbs wraps everything in a div, whereas the other one doesn't.

Is there some kind of character limit or something which is causing it to be added in a div?

# Answer
> 0 votes
Apparently yes, because reasons

https://stackoverflow.com/questions/9607393/drupal-7-ajax-command-creates-unwanted-div

The solution to anyone else having this issue is to use either your own callback, or instead use `ajax_command_invoke("#my-div", 'append', array($content));` and that will do the same as `ajax_command_append`, both solutions are more fleshed out in the link

---
Tags: 7, ajax
---


# Question
Title: Sometimes the v=<version number> parameter is added to the product URL
I have a new Drupal 8 site running commerce. When I view a product, most of the time the clean URL is perfect. Other times, it has a version parameter attached to it. I can access the page and no parameter, then refresh and I get a ?v=2 or something like that. I'm baffled. Has anyone experienced this issue? We're afraid that if users copy this link (with parameter) to other sites, it will cause us duplicate issues with SEO.

I'm not sure what I need to post here for help, so if anyone can help, let me know and I'll provide anything I can.

# Answer
> 2 votes
This is because you've got more than 1 variation on a product. The v parameter allows you (and drupal commerce) to directly link to the product page with the correct variant set as the selected one

For example you have "t shirts" product with variations for colour. You might want to link directly from the product listing page/cart/anywhere else to a specific colour tie.

---
Tags: commerce
---


# Question
Title: Add icon to menu link that has system.admin as a parent
So I have this code in my links.meny.yml file:

```
webtrack_update_reminder.main:
  title: 'Reminders'
  description: 'Reminders for your project'
  parent: system.admin
  route_name: webtrack_update_reminder.content
  weight: 100

```

Which adds a link to the "manage toolbar". Now my question is, how do I place an icon next to the link, just like the other links in the toolbar?

I have been searching but I didn't came up with an answer for Drupal 8.

# Answer
You can take look at what the core toolbar module's toolbar.icons.theme.css.

I think the class for your menu item becomes `.toolbar-icon-webtrack-update-reminder-main`.

```
.toolbar-icon-webtrack-update-reminder-main:before {
  background-image: url(path/to/svg);
}
.toolbar-icon-webtrack-update-reminder-main:active:before,
.toolbar-icon-webtrack-update-reminder-main.is-active:before {
  background-image: url(path/to/svg);
}

```
> 0 votes

# Answer
Don't take any chances

**mymodule.module**

```
/*
 * Implements hook_toolbar_alter()
 */
function mymodule_toolbar_alter(&$items) {
  $items['administration']['#attached']['library'][] = 'mymodule/toolbar';
}

```

**mymodule.libraries.yml**

```
toolbar:
  version: VERSION
  css:
    theme:
      css/toolbar.css: {}

```
> 3 votes

# Answer
As per the answer by @mradcliffe, styles for the regular and active states would need to be created. However you'd want to add them as a separate library which you'd include on admin pages, rather than edit core files.

So take the styles in @mradcliffe's answer, or whatever you determine to be correct, and save it to your module in **css/webtrack-update-reminder-toolbar-icon.css**.

In your module's **webtrack\_update\_reminder.libraries.yml** file, something like this:

```
toolbar-icon:
  version: 1.0
  css:
    theme:
      css/webtrack-update-reminder-toolbar-icon.css: {}

```

Then in your module's **webtrack\_update\_reminder.module** file, something like so:

```
/**
 * Implements hook_page_attachments().
 */
function webtrack_update_reminder_page_attachments(array &$attachments) {
  $is_admin = \Drupal::service('router.admin_context')->isAdminRoute();
  if ($is_admin){
    $attachments['#attached']['library'][] = 'webtrack_update_reminder/toolbar-icon';
  }
}

```

That should be all that's needed to load the library (i.e. your stylesheet) on any admin pages, which will in turn apply your styles to the toolbar item and show your custom toolbar icon.
> 2 votes

---
Tags: 8, toolbar
---