# Question
Title: Ajax submission leads to => An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (2 MB) that this server supports
So i'm trying to submit a form using ajax, in my form i have the following:

```
        $form['actions']['#type'] = 'actions';
        $form['actions']['submit'] = array(
        '#type' => 'submit',
        '#value' => $this->t('OK'),
        '#button_type' => 'primary',
        '#prefix' => '<div class="tc btn_pay relative">',
        '#suffix' => '</div>
                        </div>',
        '#attributes' => array(
            'class' => array('proximabold', 'tc', 'transition', 'no-underline', 'ph3', 'pv2', 'mb2', 'dib', 'white'),
        ),
        '#ajax' => [
            'event' => 'click',
            'callback' => '::updateTable',
            'wrapper' => 'table-wrapper',
            'progress' => [
                'type' => 'throbber',
                'message' => t('Verifying entry...'),
            ],
        ],
    );

```

and a simple updateTable function:

```
public function updateTable(array $form, FormStateInterface $form_state) {
    return "Hello World";
}

```

But when i click on submit i get the error: **An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (2 MB) that this server supports.**

I knew that the error is server side (Maybe i'm wrong), so i went to php.ini (i use PHP7) and update the following lines:

```
post_max_size = 6144M
memory_limit = 6144M
upload_max_filesize = 6144M
max_file_uploads = 1000

```

but without luck, this configuration shouldn't be necessary as the request size is only 1.5KB

# Answer
By debugging the code I found the solution. The error was triggered from `core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php`

```
if ($exception instanceof BrokenPostRequestException && $request->query->has(FormBuilderInterface::AJAX_FORM_REQUEST)) {
  $this->drupalSetMessage($this->t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', ['@size' => $this->formatSize($exception->getSize())]), 'error');
  $response = new AjaxResponse();
  $status_messages = ['#type' => 'status_messages'];
  $response->addCommand(new ReplaceCommand(NULL, $status_messages));
  $response->headers->set('X-Status-Code', 200);
  $event->setResponse($response);
  return;
}

```

The error triggered if the `BrokenPostRequestException` exception is thrown.

Now if we got to `core/lib/Drupal/Core/Form/FormBuilder.php` we find that this exception is thrown if the post request is bigger than what is allowed by the server and also if the **request doesn't carry the form id**.

```
if ($ajax_form_request && !$request->request->has('form_id')) {
  throw new BrokenPostRequestException($this->getFileUploadMaxSize());
}

```

> It would be better if there was another exception for this case rather than getting the same error for when the post request exceeds the configured allowed size (post\_max\_size)

In my case it was not a matter of post size request, rather I didn't include the form id in my twig file.

I added the lines containing *form\_id* and *form\_build\_id*:

```
<div class="fr relative filtrehold">
        <div class="filtr_btn  br-pill shadow-2 ttu dark-gray f5 proximabold">Filtres</div>
        <form> //Added this one
            {{ McRefund_build_data.filterform.form_build_id }} // Added
            {{ McRefund_build_data.filterform.form_id }} // Added
            {{ McRefund_build_data.filterform.RelevesMensuels }}
            {{ McRefund_build_data.filterform.from }}
            {{ McRefund_build_data.filterform.to }}
            {{ McRefund_build_data.filterform.example_select }}
            {{ McRefund_build_data.filterform.actions.submit }}
        </form> //Added this one
</div>
<div class="table_hold bg-white br2">

    <div id="table-wrapper">

        {% for Num_refund,refund in McRefund_build_data.filterform.RefundsContainer['Refunds']['#Refunds_data'] %}
                   ............
                   ............
                   ............
        {% endfor %}
    </div>
</div>

```
> 9 votes

# Answer
Due to an identical error message ("***An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size that this server supports***")in a project based on Drupal 8, I just discovered a third use of the same exception discussed above. In my case, the exception was thrown by reaching limit of allowed variables in the php.ini file.

1. **Open the file** -\> vim /etc/php/7.2/apache2/php.ini
2. **Locate the line** -\> /max\_input\_vars/n
3. **Uncomment the line and put** -\> max\_input\_vars = 3000
4. **Restart Apache** -\> sudo /etc/init.d/apache2 restart

My two Cents.
> 5 votes

---
Tags: forms, ajax
---


# Question
Title: Implementing IP recognition and price conversion (2 parts)
The commerce (kickstart) site has default prices in USD. Site should convert the price to local currency for international visitors, based off IP or other means.

*Example:*

**Widget Price - $2** (USD).

***Australians see***: **A$2.15**

***Canadians see***: **C$2.18**

***Japanese see***: **¥204.70**

So the functions needed are

1. **Detect country from IP**
2. **Lookup visitor's currency**
3. **Lookup conversion rate from USD**
4. **Convert + format price**
5. **Display wherever price field is called.**

There doesn't seem to be a single module to do this (I wish there is!) and bits and pieces of advice here and there which involve rules etc, which I'm not familiar with.

I hope I can find a guru here who can show the way. Thanks!

# Answer
I don't think there is any module provides this functionality.. The best way is to use some third party services to get data and display it..

I'd do such things to acheive this:

* get user ip by ip\_address()\`
* get user info by this service: `http://www.geoplugin.net`.

here is an example:

```
$countryInfo = drupal_http_request('http://www.geoplugin.net/json.gp?ip=' . $user_ip);
$countryInfoData = json_decode($countryInfo->data);
$userCurrencyCode = $countryInfoData->geoplugin_currencyCode;

```
* and use google converter to get result:

some sample code:

```
  $amount = urlencode($amount);
  $from_Currency = urlencode($from_Currency);
  $to_Currency = urlencode($userCurrencyCode);
  $get = file_get_contents('https://www.google.com/finance/converter?a=' . $amount . '&from=' . $from_Currency . '&to=' . $to_Currency);
  $get = explode("<span class=bld>",$get);
  $get = explode("</span>",$get[1]);
  $converted_amount = preg_replace("/[^0-9\.]/", null, $get[0]);

```

this piece of code's gotten from this post :)

and, so, it's up to you to display the results...

I don't think this is a real solution to your problem and also I can't guarantee this will work:) .. but you can play around it to find better solution..
> 0 votes

# Answer
Yes you can do it with modules, I did.

Using a conbination of rules, commerce\_multicurrency https://www.drupal.org/project/commerce\_multicurrency and smartip https://www.drupal.org/project/smart\_ip.

1. Activate the modules.
2. Configure smart\_ip external service in /admin/config/people/smart\_ip FYI https://IPInfoDB.com free version worked right away for me (you need to register and get an API key though).
3. Go to /admin/commerce/config/currency choose your default currency and activate the currencies you need.
4. Got to /admin/commerce/config/currency/handling add the currencies you want to the products types you want (but don't add the default currency).
5. Now to /admin/commerce/config/product-pricing you need to create the rules that will convert the price for each currencies. Here is an exported example rules that convert a price in USD if the user IP is from the US:

{ "rules\_set\_price\_in\_usd" : { "LABEL" : "Set price in USD", "PLUGIN" : "reaction rule", "OWNER" : "rules", "TAGS" : \[ "price conversion" \], "REQUIRES" : \[ "smart\_ip", "commerce\_multicurrency", "rules", "commerce\_product\_reference" \], "ON" : { "commerce\_product\_calculate\_sell\_price" : \[\] }, "IF" : \[ { "smart\_ip\_condition\_in\_country" : { "country" : { "value" : { "US" : "US" } } } } \], "DO" : \[ { "commerce\_multicurrency\_set\_user\_currency\_code" : { "currency\_code" : "USD" } }, { "component\_commerce\_multicurrency\_use\_usd" : { "commerce\_line\_item" : \[ "commerce\_line\_item" \] } } \] } }

Once the rules for each currencies have been established, you only have to go to each products and enter the prices (use the price field four your default currency, and the dedicated fields for the others).

You may use the debug mode in /admin/config/people/smart\_ip to make tests.
> 0 votes

---
Tags: commerce
---


# Question
Title: How to convert currency dynamically on Product Page?
I am using drupal 7 and commerce modules. I want a dynamic currency converter on product display page or cart page (priority is product display page). Suppose Product A is displayed with price 1 USD and user is from India or some other country then I want to give the user an option to change the currency before adding product to cart. If the user selects INR then the 1 USD will be converted to INR which makes it 67 and payment will be made in INR. How can I achieve this kind of functionality in Drupal ?

Suggestions are welcomed.

Thanks

# Answer
You can use Commerce Multicurrency module for INR price field in the products content types.
> 1 votes

# Answer
See my answer there https://drupal.stackexchange.com/a/275805/14465 for a step by step solution. It include a way to automaticaly change currency based on the user IP.
> 0 votes

---
Tags: 7, commerce
---


title: How to add prefix to button text field

text:
# Question
Title: How to add prefix to button text field
I am trying to wrap button value with span as follows in my form alter hook.

```
$form['actions']['submit']['#value'] = '<span>'.t('Submit').'</span>';//Here want to add span
$form['actions']['submit']['#attributes'] = array('class' => array('green-gradient-button'));

```

This doesn't seem to be working.

# Answer
You can't put html in there for the value. The value is used on the html submit button **value=""** e.g.:

```
<input data-drupal-selector="edit-submit" type="submit" id="edit-submit" name="op" value="Submit" class="button js-form-submit form-submit">

```

What are you hoping to achieve by putting a span around the button? You could use #prefix #suffix to add the span

```
 '#prefix' => '<span>',
 '#suffix' => '</span>'

```

Or a custom template, this link might set you on the right track https://www.axelerant.com/resources/team-blog/playing-with-input-templates-in-drupal-8
> 2 votes

---
Tags: 8
---


# Question
Title: How to pass variable to a views template?
I have this in my template.php:

```
function mytheme_preprocess_views_view(&$vars) {
$vars['test'] = 'Filtertest';
}

```

And this in my views-view-responsive-grid--taxonomy-term.tpl.php:

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

```

... this does not work though. The template is called and works but my $test variable does not get printed.

What am I missing here? Any help is greatly appreciated.

# Answer
Replace this, with your function

```
public static function mytheme_preprocess_views_view(&$vars) {
  $vars['test'] = 'Filtertest';
  return $vars['test'] ;
}

```

Then use this short code on your twig view:

```
{{ test }}

```

or if wanna use it in something.php in your views:

```
dump(test )

```
> 1 votes

# Answer
In case anyone else have the same problem. Changing the name of the template file to `views-view-responsive-grid.tpl.php` and then using that same name in the preprocess function in `template.php`, like this:

```
function mytheme_preprocess_views_view_responsive_grid(&$vars) {
  if($vars['view']->name == 'taxonomy_term') {
    $vars['test'] = 'Filtertest';
  }
}

```

... fixed the problem. Now the $test variable is printed. Apparently the template's filename can't be too specific.
> 0 votes

---
Tags: 7, views, theming
---


title: how do 404 pages work?

text:
# Question
Title: how do 404 pages work?
How does the 404 page you can define in /admin/config/system/site-information work?

I found Drupal\system\Controller\Http4xxController-\>on404(), but how does that display whatever path I definied in basic site settings?

I'm trying to deliver a 410 when a page is deleted. I hve a database table with deleted paths, an InboundPathProcessorInterface to call a custom controller. Now I want to output the exact same thing as a 404, just with another status code.

Alternativly, how do I get the content of a given system path (i.e. node/123) to output in a Symfony\Component\HttpFoundation\Response?

# Answer
For the configured custom path:

CustomPageExceptionHtmlSubscriber::on404

```
   public function on404(GetResponseForExceptionEvent $event) {
    $custom_404_path = $this->configFactory->get('system.site')->get('page.404');
    if (!empty($custom_404_path)) {
      $this->makeSubrequestToCustomPath($event, $custom_404_path, Response::HTTP_NOT_FOUND);
    }
  }

```

If no custom path is configured the subrequest is built for '/system/404' pointing to the controller you've mentioned:

DefaultExceptionHtmlSubscriber::on404

```
  public function on404(GetResponseForExceptionEvent $event) {
    $this->makeSubrequest($event, '/system/404', Response::HTTP_NOT_FOUND);
  }

```

To customize other status codes than 403 or 404 extend DefaultExceptionHtmlSubscriber and override on4xx().
> 2 votes

---
Tags: 8, routes
---


# Question
Title: Only the word "array" gets printed when I try to render custom block in template
I am building a custom block in a module, like this:

```
<?php

function filterblock_block_info() {
  // Sökfilter till temperaturöversikten.
  $blocks = array();

  $blocks['filterblock-temperatur'] = array(
    'info' => t('Temperatursökfilter'),
  );

  return $blocks;
}

function filterblock_block_view($delta = '') {
  $block = array();
  switch ($delta) {
    case 'filterblock-temperatur':
      $block['subject'] = t('');
      $block['content'] = filterblock_block_content();
      break;
  }
  return $block;
}

function filterblock_block_content(){
    return drupal_get_form('temperaturfilter');
}

function temperaturfilter($form, &$form_state)
{
    $form = array();

    $form['alla'] = array(
        '#type'         => 'textfield',
        '#title'        => t("Alla"),
        '#weight'       => 10,
        '#required'     => false,
    );
    $form['IR'] = array(
        '#type'         => 'textfield',
        '#title'        => t("IR"),
        '#weight'       => 11,
        '#required'     => false,
    );

    $form['hightemp'] = array(
        '#type'         => 'textfield',
        '#title'        => t("> +500 °C"),
        '#weight'       => 12,
        '#required'     => false,
    );
    $form['lowtemp'] = array(
        '#type'         => 'textfield',
        '#title'        => t("< -50 °C"),
        '#weight'       => 13,
        '#required'     => false,
    );

    return $form;
}

```

In my template file I have this:

```
   <?php $block = module_invoke('filterblock', 'block_view', 'filterblock-temperatur'); ?>
   <?php  if ($block['content']) {
     $output = "<div class=\"filter-block\">\n";
     $output .= "<div class=\"content\">".$block['content']."</div>\n";
     $output .= "</div>\n";
     print $output;

```

But the only thing that is rendered on the page is the word "array". I have checked with var\_dump in the block module that `$block['content']` actually contains the fields from the function `temperaturfilter`. I have tried to use print render($output) in stead of just print, but with no luck.

What am I doing wrong?

# Answer
> 1 votes
You haven’t rendered the render array:

```
$output .= "<div class=\"content\">".render($block['content'])."</div>\n";

```

---
Tags: 7, theming, blocks
---


# Question
Title: Menus, drush uli link, and some images not working after moving site to localhost
I've just gotten a site I'm supposed to do some work on but I'm having trouble with migrating to a local development environment. I don't have admin access to the site itself, but I do have access to the server. I pulled the database down along with the code base, but I seem to have messed up the file permissions when moving the site because the site loads, but not all the functionality is present.

The site isn't accessible beyond the splash page, and none of the image assets load except the site logo. Accessing any menu links generates a 404. The image that loads has the same ownership and permissions as the image which loads which are `myuser:www-data` and 640. Initially, no images loaded, but following this post about securing file permissions got the logo loaded.

I am also having issues with accessing the site. Since, I can't access any menus beyond the root, it seems that I can't access the login page either. I've added a user for myself with Drush, and even run `drush uli` with the the URI provided as a parameter, but the link is inaccessible and returns a 404. I also used the File Permissions module, but it doesn't seem to have helped.

At this point, my next step is going to be setting up a clean install and importing the db through backup and migrate and moving the theme and modules manually, but I'd like to figure out what I did wrong and how to avoid this.

# Answer
> 0 votes
I did recently a manual migration and had some problems, similarly to you. After this, I made a script to manually migrate the site and the database. You need to have a zip with the Drupal installation, not the folder of the installation, just the files inside it, the database and know if the database has some prefix. Change all the prefix in the database, you could use notepad++ or similar to change all in one command. Change the url i.e: mydomain.com/drupal to localhost/drupal. Then import the database, and unzip the files in your localhost server. Then go to sites/default/settings.php and at the bottom of the file edit the data of your database, prefix if you have one, pass, user, port if you changed it and, in same file, look for `$settings['update_free_access'] = FALSE;` and change it to true. Now, in your browser visit localhost/yourinstallationfoldername/update.php and follow the instructions. If you don't know the users you can see in the database for the table users and you can see there their ID (uid) and password (uuid) on md5. Just search on google for any md5 generator and copy paste it on uid 1 (admin user generated on installation) for know the name of the user you can go to the table users\_field\_data and look on name column.

If you have a virtual server working on your server, you must remember to point it to the new folder where is your Drupal installation. This is a good tutorial about how to do it: Installing virtual hosts for Drupal sites and subsites.

---
Tags: 8, database, files, deployment
---


# Question
Title: Pass Variable to Custom Block template file
I want to create my custom block with custom content in Drupal 8,in start I create Block with just simple text on it, and work correctly, my Problem is how can I pass my custom variable to it? I saw some tutorial about it , my Module name is `tcdev` and this is content of `.module` file.

```
function tcdev_theme($existing, $type, $theme, $path) {
    return array('tcdev' =>
        array(
            'variables' => array(
                'title' => 'Default title',
                'description' => null
            ),
            'template' => 'block--sliderblock'
        )
    );
}

```

and my `SliderBlock.php`

```
    namespace  Drupal\tcdev\Plugin\Block;
use Drupal\Core\block\BlockBase;

/**
 * Provides a 'SliderBlock' block.
 *
 * @Block(
 * id = "slider_block",
 * admin_label = @Translation("Slider Block"),
 * )
 */

class SliderBlock extends BlockBase{
    /**
     * {@inheritdoc}
     */
    public function build(){
        return array(
            '#title' => 'my title ',
            '#description' => 'my custom desc'
        );
}
}

```

and finally my template file `block--sliderblock.html.twig`

```
  <h2>My Custom Block{{ title }}-{{ description }}</h2>

```

But Result is only "My Custom Block-" . **The problem is variables not getting passed to template file,where is my fault?**

appreciate any help

# Answer
Your return array doesn't contain a `#theme` key. So at the moment you aren't using a template file at all.

And you probably have a mix up between the outer block and theming the content inside of the block. Your template inside has the name tcdev, because that is the name you defined at the top of the array in `*_theme()`, and tcdev.html.twig is where your variables will end up.

Your code would look like the following one.

```
function tcdev_theme($existing, $type, $theme, $path) {
  return array('tcdev' =>                  // this is the name of the template
           array(
            'variables' => array(
                'title' => 'Default title',
                'description' => null
            ),
        )
    );
}

```

### SliderBlock.php

```
namespace  Drupal\tcdev\Plugin\Block;
use Drupal\Core\block\BlockBase;

/**
 * Provides a 'SliderBlock' block.
 *
 * @Block(
 * id = "slider_block",
 * admin_label = @Translation("Slider Block"),
 * )
 */

class SliderBlock extends BlockBase{
    /**
     * {@inheritdoc}
     */
    public function build() {
        return array(
            '#theme' => 'tcdev',
            '#title' => 'my title ',
            '#description' => 'my custom desc'
        );
   }
}

```

### tcdev.html.twig

```
  <h2>My Custom Block{{ title }}-{{ description }}</h2>

```

You wrote that you saw some tutorials about it. Probably this was about two different topics, and you are trying to apply them at the same time.

The custom template in the first link is tcdev.html.twig. What you are trying to do with the method in the second link is for block--sliderblock.html.twig.
> 17 votes

# Answer
So that I found, you want to overwrite a default block template with a custom block (module) template, and then pass your variables to it, first of all you must make sure overwrite your template correctly because seems your current block template outputed from your Theme directory (not module):

```
<!-- BEGIN OUTPUT from 'themes/gttc_2016/templates/block--sliderblock.html.twig' -->

```

To do this first you should create a directory called `templates/` in your modules root and then place your template there.

Now let Drupal know you store the template in your module. in `your_module.module` add this function:

```
function YOUR_MODULE_theme($existing, $type, $theme, $path) {
  return array(
    'block__my_module' => array(
      'render element' => 'elements',
      'template' => 'block--my-module',
      'base hook' => 'block'
    )
  );
}

```

Finally be careful about where you place your twig file and what you name it. Create a templates directory in your module directory, and replace the `_` in the theme function name with `-`:
`mymodule-block.html.twig`

Don´t forget to clear the cache.

---

With the help of the answer written by `Nicensin` in this post:
Drupal 8 custom block (module) create twig template file
> 4 votes

# Answer
I got to this point too. The variables don't seem to be pass to to the block template. I have almost the same code as you, in my case I enabled twig debug and disable cache in services.yml. Even clearing cache I was having this issue but got solved once I activated this config in my dev environment.

```
twig.config:
# Not recommended in production environments
# @default false
debug: true
# Not recommended in production environments
# @default null
auto_reload: true

```
> 1 votes

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


title: Order receipt email content

text:
# Question
Title: Order receipt email content
I have a Drupal 8.6.7 site with Commerce 8.x-2.11 installed. I would like to include slightly more information in the emails sent out when customers complete the checkout process. I would like to reference both the equipment category field and a more general category field present in both the product and product variations.

At the moment I just see the Title, Unit Price and Quantity if I look at the list of orders (all tests right now) at /Administration/Commerce/Orders.

Is there a way of adding these fields through the web admin GUI so that they end up in an order receipt email? I also have 'MIME Mail' and 'Mail System' modules installed if that helps.

# Answer
This is not really an answer but closer to one than I've been before; even though I cannot go any further.

In /core/themes/bartik/templates I've placed a copy of commerce-order-receipt.html.twig. I can change the wording in this template, refresh the cache and I can see that come through in new emails. I see there's a mention of an 'order\_entity' which I do not know how to reference so it appears in an email receipt.

If you can see the screenshot I've uploaded, it may become clear where I'm at or where I'm going wrong.

I thought I might be able to change one of the columns in the order item (as the current four columns are exactly those that appear in receipt emails) and then try and reference it through {{ order\_entity.getSomething }} in commerce-order-receipt.html.twig (after clearing the cache).

If I can get the fields in 'Purchased Entity' into the receipt email, I can then complete my business case for my Drupal site as everything else works a treat.

Thanks again.
> 0 votes

---
Tags: commerce
---


title: How to create a custom login form

text:
# Question
Title: How to create a custom login form
I need to know please any suggestion about how to create a custom login form for another type of users in drupal 8 , I have now `/user/login` is for administrator, but I need to add `/account/login` it's different for the first one and it's for a normal user and this form should use the functionnalities of Drupal 8.

# Answer
> 0 votes
Try with the following:

1. Add your new route to `[MODULE].routing.yml`

```

[MODULE].login:
  path: '/account/login'
  defaults:
    _form: '\Drupal\[MODULE]\Form\CustomUserLoginForm'
    _title: 'Log in'
  requirements:
    _user_is_logged_in: 'FALSE'
  options:
    _maintenance_access: TRUE

```
2. Create `CustomUserLoginForm` inside *\[MODULE\]/src/Form/* folder like the following:

```

namespace Drupal\[MODULE]\Form;

use Drupal\user\Form\UserLoginForm;

class CustomUserLoginForm extends UserLoginForm{

}

```
3. Flush the cache.
it works but i don't know if it's the best approach.

# Answer
> 0 votes
Try this solution :
1. add your roote to `routing.yml`

```
myModule.account:

  path: /account/login

  defaults:

    _title: 'Connect'

    _controller:

'\Drupal\myModule\Controller\AccountController::Login'

```
2. Add your Controller file in
`myModule/src/Controller/AccountController.php`

```

namespace Drupal\myModule\Controller;

use Drupal\Core\Controller\ControllerBase;

class AccountController extends ControllerBase

{

public function Login(){

}

```

---
Tags: 8, forms
---


# Question
Title: How to access single field in views-view-fields.html.twig
If I enumerate all fields using loop then everything is printed properly:

```
{% for field in fields -%}
    {{ field.content }}
{%- endfor %}

```

But I need to print here the fields individually and the following prints nothing:

```
{{ fields[0].content }}

```

What's wrong? This is used in `views-view-fields.html.twig`

# Answer
> 4 votes
You can retrieve it with:

```
{{ fields.machine_name_of_field.content }}

```

So for example if your field is a title with:

```
{{ fields.title.content }}

```

Install devel to list key / values inside the array of fields with:

```
{{ dsm(fields) }}

```

---
Tags: views, theming
---


title: How do I reset my search result link?

text:
# Question
Title: How do I reset my search result link?
I created a custom search plugin for a custom entity. I would like to change the link that is presented to the user on the list of results. I had originally set it to the canonical page using $entity-\>url(‘canonical’), but now I want to use Url::fromRoute(), to a custom controller.

I made the appropriate changes to the plugin class, cleared cache and ran cron a few times and the search results still point to the admin canonical page. Is there something else I need to do to push the change through?

# Answer
I waited some more, cleared cache and ran cron again and it worked.
> 0 votes

---
Tags: 8, search, plugins
---


# Question
Title: How to grab $form_state value from text-format from drupal form
I created a form for my module. I have a formatted text box

```
$form['message'] = array(
'#type' => 'text_format',
'#title' => 'Body',
'#format' => 'basic_html',
'#default_value' => '<p>The quick brown fox jumped over the lazy dog.</p>',
);

```

When I try to save the form message comes back as an array and I don't know how to pull the value out of it.

```
public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);
    \Drupal::logger('td')
      ->notice('text: @message', array('@message' => $form_state->getValue('message'),));
  }

```

# Answer
Try with:

```
$message = $form_state->getValue('message')['value'];

```
> 1 votes

---
Tags: 8, forms
---


title: twig call macro in different folder

text:
# Question
Title: twig call macro in different folder
i build a macro that contains a function. The function basically crop a text without catting words. My problem is how to call that twig macro if it is in different folder. if it is i same folder its easy. i just import the twig name. {% import 'croptext.twig' as cropText %} But since this file contains a useful function all templates will call it so its better to put it in special folder like "tool" or "filter". But i still have any way to call it any help ?

```
{% macro crop_text(text, len) %}
  {% if text | length < len %}
    {{ text }}
  {% else %}
    {% set break = false %}
    {% set croppedParagraph = '' %}
    {% set paragraph = text | split(' ') %}
    {% set totalLength = 0 %}
    {% for word in paragraph  if not break %}
        {% if totalLength >= len %}
          {% set break = true %}
        {% else %}
          {% set totalLength = totalLength + 1 +  word | length %}
          {% set croppedParagraph = croppedParagraph ~ ' ' ~  word %}
       {% endif %}
    {% endfor %}
    {{ croppedParagraph ~ ' ...' }}
 {% endif %}

```

{% endmacro %}

The function is working. I think its better to share more code to have a better idea about what i am doing. this is my project structure.

# Answer
> 3 votes
You can call the macro by:

1. In the same twig Using `_self`:
From Documentation:
> It's possible to place the macro within the same twig from which you call it. The \_self context is used in this case...

`{{ _self.crop_text(text, len) }}`

2. From External File using `import` :
Like the following:
Just move your `croptext.twig` into `yourtheme/templates` folder and then you can use the following call in any twig:

`{% import '@yourtheme/croptext.twig' as cropText %}`

For more information take a look at Macros in Twig Templates documentation.

---
Tags: theming
---


# Question
Title: HTML tags in views field label. Is it possible?
By default in views field label it possible to put only plain text, so the markup looks like:

```
<div class="views-field views-field-price">
  <span class="views-label views-label-price">Price: -10%</span>
  <span class="field-content">9.99</span>
</div>

```

But I need to add some text wrapped with tags, like

```
<div class="views-field views-field-price">
  <span class="views-label views-label-price">Price: <span>-10%</span></span>
  <span class="field-content">9.99</span>
</div>

```

How it is possible?

# Answer
Uncheck create label

Click on rewrite results, check mark override out and put:

```
  <span class="views-label views-label-price">Price: <span>-10%</span></span>
  <span class="field-content">{{ field_price }}</span>

```

I'm not 100% that it's `{{ field_price }}`, but you can click on replacement patterns to see the pattern name.
> 1 votes

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


# Question
Title: Why do my main menu tabs show up on two lines instead of one?
In Drupal 8, I have a main menu in the "Primary menu" block of the default Bartik theme. You can see a screenshot below. This site was upgraded from Drupal 7.

Why does the menu show up on two lines instead of one? There is plenty of space available for the menu items. I have tried adjusting the menu and block settings, but have not managed to reduce these to one line. All of the menu items other than "WOW" and "About" have "WOW" as the parent item.

You can see the site here:

http://worldsowisdom.com/wow/

Thank you!

# Answer
This is happening because of the CSS technique/code being used. Both `<li>` and `<a>` have been floated.

The first WOW item actually contains all the other WOW items as children, and it's reflected in the HTML structure, there is an `<ul>` inside the WOW `<li>`. Since `<li>` is floated but it hasn't been given a specific width, there are some cases that can happen, like this one, that seem a bit odd, but they're just following the code.

I guess the authors of that theme didn't anticipate the menu might be used in this way, to display two levels of menu hierarchy on one line.

Usually one level of the menu is displayed in one region, and deeper levels are displayed elsewhere or in a drop-down.

You could add two Main menu blocks to that region, and set one Block to display Initial visibility level and Number of levels to display to 1 and 1, and the other Block to 2 and 1. This way you'd get WOW and About in one row, but when you visit WOW a second row would appear with all the WOW-subitems.

If they are meant to always be displayed maybe it makes sense not to have two levels in hierarchy?

But in the end you can always adjust the CSS to make them display all on one row (you can use CSS edit module to override CSS if you don't have a subtheme):

```
.region-primary-menu .menu-item,
body:not(:target) .region-primary-menu .menu-item {
  float: none;
}

```

This will make them show on one row since now only anchors are floated. But the margin won't have affect so you'll need to add margin to the anchor elements instead, if you want them separate a bit like before.
> 2 votes

---
Tags: blocks, navigation
---


# Question
Title: webform submission presave in a custom module
I'm quite noob at drupal, i have a custom module with the function below:

```
function at_custom_webform_submission_presave($node, &$submission) {
// my code here
}

```

i don't know why, but it's seems that the function is not called... what's the problem ?

I tried to use an email function php and nothing happened. and when i tried the same thing with : at\_custom\_user\_presave, i got an email.

So that's why i'm thinking that the function is not called anymore. Before it was.

The website use 7.61 version's drupal and 7.x-4.18 version's webform.

Thanks for helping.

# Answer
> -2 votes
I think i find why it was not triggered. the form was an user create form, no a webform. so that's why, thanks for the help.

# Answer
> 2 votes
According to your sample code,to use hook\_webform\_submission\_presave your module name must be "at\_custom"

1. Enable Webform module
2. Enable your at\_custom module
3. Put your hook under your module file: 'at\_custom.module'

```
    function at_custom_webform_submission_presave($node, &$submission) {
    // your code here
    }

```

---
Tags: 7, webforms
---


title: View of blog posts grouped by year

text:
# Question
Title: View of blog posts grouped by year
Client wants a blog archive with the posts inside accordions whose toggle is the year. Two example years HTML below.

I have the individual fields exposed as tokens within my view with no problem. What I can't see how to do is to enable conditional logic so I express the Year toggle structure once per year of posts.

Is this possible with a View?

I went over Blog monthly archive block - list of posts grouped by year then month I read the 10 year old post at http://chrisshattuck.com/blog/how-create-monthly-archive-block-drupal-blog-views

I have a working view Block but not nesting the way I need it. It outputs a whole accordion per post (as I knew it would).

```
<div class="fcx-accordion" id="accordion">

<h4 class="fcx-toggle"><a data-toggle="collapse" href="#list2019">2019</a></h4>
<div class="panel">
    <div class="accordion-content panel-collapse collapse" id="list2019">

        <ul>
            <li>{Authored on} - {Linked title}</li>
        </ul>

    </div>
    <!-- accordion-content -->
</div>
<!-- panel-->
<h4 class="fcx-toggle"><a data-toggle="collapse" href="#list2018">2018</a></h4>
<div class="panel">
    <div class="accordion-content panel-collapse collapse" id="list2018">

        <ul>
            <li>{Authored on} - {Linked title}</li>
        </ul>

    </div>
    <!-- accordion-content -->
</div>
<!-- panel-->

```

# Answer
You can do this with the Views Accordion module.

Add the `Authored on` field, choose the formatter that only shows the year of the created date. Then edit the `Format` settings to set the `Grouping field Nr.1` field to your yearly Authored on field.

This way you get all the results split into groups by year.

Now you configure the Views Accordion to use the Grouping as accordion headings and the grouped results as accordion content.
> 2 votes

---
Tags: views, 8
---


title: Combination of multiple taxonomies

text:
# Question
Title: Combination of multiple taxonomies
I have these following 4 Taxonomies
**1.** New Taxonomy
**2.** Content Category
**3.** Technology Taxonomy

* Applications
* Gamification
* Architecture
* etc. Totally 170 terms

**4.** Vertical Taxonomy

* Automotive
* Banking

Have used Taxonomy term views to create listing pages for these. I want to know is it possible for me to dynamically combine multiple taxonomies ( Technology & Vertical) to display content. Eg : example.com/applications/automotive . If yes how can this be done?

# Answer
> 5 votes
Yes, you can do it with Contextual filters in Views. You can Duplicate the Taxonomy term Views and work on it, disable the original for future reference.

You need to add one Contextual filter for each of your Vocabularies. You probably have one field for each of those on your Content type, so add the Taxonomy reference fields as your Contextual filters. The alternative is to use "Has taxonomy term" twice and limit Vocabularies.

You'll need to set up a default value taken from the URL. You can find a lot of tutorials online about the details of setting it up: Add a contextual filter to a view, How to use Contextual Filter in Drupal 8.

The above approach will only work with term IDs `example.com/16/35`.

To have term names displayed instead of TIDs you need to add a Relationship to the Taxonomy field to your Views, then add `Taxonomy term: Name` in your Contextual filters and it will use that Relationship in the Taxonomy Contextual filter. Repeat for the other Vocabulary. Also see this answer: How to setup view to filter based on second URL parameter?

That is how you can get `example.com/applications/automotive`.

# Answer
> 1 votes
Thanks to prkos solved this problem. Will put down the steps I did to accomplish this.

1. Disabled the taxonomy term view
2. Duplicated the taxonomy term view added two contextual filters using my two taxonomy reference fields - field\_case\_study\_industry, field\_case\_study\_technology. Now I set the options of `WHEN THE FILTER
VALUE IS NOT IN THE URL` to provide default value and selected Taxonomy term ID from URL . Check the Load default filter from term page. Now I set the path to /case-study/%/%. This works perfectly for `example.com/case-study/3033/3222`
3. To add the term name in the url. Added two relationships: Taxonomy term referenced from field\_name. Unchecked require this relationship. Added two contextual filters "Name". Selected the Relationship. And for `When the filter value is not in the UR`L, chose display all results. So now the url `/case-study/applications/automotive` works

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


# Question
Title: How to link migrated image file to the user profile picture field?
I used the following migration file to migrate user pictures from a Drupal 7 site installation to Drupal 8:

> migrate\_plus.migration.drupal7\_image.yml

```
id: drupal7_image
label: Images
migration_group: dhm_migrate_taxonomy
migration_tags:
  - Drupal 7
source:
  plugin: d7_file
  constants:
    source_base_path: '/var/www/html/migrate_training_7/web/'
process:
  fid: fid
  filename: filename
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - filepath
    -
      plugin: urlencode
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - uri
  filemime: filemime
  status: status
  created: timestamp
  changed: timestamp
  uid: uid
destination:
  plugin: entity:file
migration_dependencies: {}

```

And I am using this next snippet to link the migrated image files to the user picture field (This is used in my user migration file):

> migrate\_plus.migration.custom\_user.yml

```
  user_picture: # Image field name in Drupal 8 site
    plugin: iterator
    source: user_picture # Image field name in Drupal 7 site
    process:
      target_id: fid
      alt: alt
      title: title
      width: width
      height: height

migration_dependencies:
  required:
    - drupal7_image

```

I can see that the files are being migrated and downloaded to my Drupal 8 installation but when I check the users I don't see any user pictures (fields are blank).

I really don't know what I am missing, I searched for examples on the Internet but I didn't find much.

Any help would be much appreciated. Thanks in advance. ;)

# Answer
> 1 votes
Thanks a lot @MrD I tested using the **`migration_lookup`** plugin and it works like a charm:

```
  user_picture:
    -
      plugin: default_value
      source: picture
      default_value: null
    -
      plugin: migration_lookup
      migration: drupal7_image

```

---
Tags: 8, migrations
---


# Question
Title: Command to list all media entities in console?
I have an issue in my site which is not allowing me to visit the `/en/admin/content/media` page.

I'm looking for an approach to list and delete media entities on the command line.

When I run `drupal debug:entity media` I get an error:

```
[ERROR] <em class="placeholder">Notice</em>: Undefined index: media in <em
         class="placeholder">Drupal\Console\Command\Debug\EntityCommand->execute()</em> (line <em
         class="placeholder">79</em> of <em
         class="placeholder">/home/ubuntu/site/vendor/drupal/console/src/Command/Debug/EntityCommand.php</em>
         ). <pre class="backtrace">Drupal\Console\Command\Debug\EntityCommand->execute(Object, Object)
         (Line: 255)
         Symfony\Component\Console\Command\Command->run(Object, Object) (Line: 971)
         Symfony\Component\Console\Application->doRunCommand(Object, Object, Object) (Line: 248)
         Symfony\Component\Console\Application->doRun(Object, Object) (Line: 185)
         Drupal\Console\Core\Application->doRun(Object, Object) (Line: 64)
         Drupal\Console\Application->doRun(Object, Object) (Line: 148)
         Symfony\Component\Console\Application->run() (Line: 89)
         require('/home/ubuntu/site/vendor/drupal/console/bin/drupal.php') (Line: 4)
         </pre>

```

The docs of this command is also really uninformative.

What's the best approach to list and delete media entities on the command line?

# Answer
If you use Drush, you can try drush sql-query like this :
`drush sql-query "Delete from name_table weher condition"`
> -1 votes

---
Tags: 8, console
---


# Question
Title: How to create a textfield with autocomplete function for the view?
My Drupal 8 website is multilingual, and on one of the views I present a list of nodes (titles). On top of the page I need to implement a textfield with autocomplete function, where the user can start typing in the language, and then by choosing one the content on the page will be presented in chosen language.

I have started by creating a custom block:

```
public function build(){

$block = array(
  '#type' => 'textfield',
  '#title' => t('Choose language'),
  '#autocomplete_path' => '?????',
  '#cache' => array(
    'max-age' => 0,
  ),
);
return $block;

```

}

What should I write in '#autocomplete\_path' =\> '?????' as the list of languages is not taxonomies. It is coming from Languages module. Could you please help me?

# Answer
I think no need to create block of view programmatically, You can do it with **Views Autocomplete Filters** module and **views** Module:
Try the following steps how to create view with language filter, using autocomplete:

1. Install Views Autocomplete Filters Module.
2. Create View with `Fields` Display add the language field `The language of the content or translation.` and your additional fields:
3. Add **Combine fields filter**

configure it like the following:

4. the result will be like:
> 2 votes

---
Tags: 8, blocks
---


title: Language pages are triplicated

text:
# Question
Title: Language pages are triplicated
Our website was developed with Drupal and we only have a small set of Spanish language pages on a primarily English website.

My question is, I'm getting THREE pages generated for every one page:

* .com/node/11
* .com/espanol/node/11
* .com/conveniences/gift-cards -- all of these use the same English content.

The dev team says this is working as intended as long as there is no Spanish content, we get a Spanish URL as well.

We apparently have 3x the pages now because of this.

Is there something we can do?

# Answer
> 3 votes
As already stated in comments, you have one page but more than one link/path to access it. From the SEO perspective it is something to consider, eventhough Drupal "knows" this is the same content.

The `/node/11` is the base URI for your English content, you can't be without it, it's a Drupal internal.

`/conveniences/gift-cards` is the path alias of the `/node/11`. It is usually created with the help of Path or Pathauto modules to improve the URIs for better UX and better SEO. They're usually coupled with Global Redirect or Redirect modules that automatically and permanently redirect to the alias. This way search engines only ever see one URI for this content.

`/espanol/node/11` This link comes from Multilingual features, actually the specific way you have them configured. It's important to distinguish two independent parts of the website that can be translated: Interface and Content. Roughly speaking, Content is what usually goes into a node, and Interface is everything else surrounding the node.

Multilingual sites need a way to determine which Interface language to display, and which Content exactly when a request is made (a link clicked). Usually this is done by constructing links that contain both information. The language prefix is being used to determine the Interface language, and what follows it is a normal path to some content.

The `/espanol/` is the language prefix and is telling Drupal to display the interface in Spanish language. `/node/11` is the content path and is telling Drupal to pull the contents of node 11 from the database. When you put that together you have Spanish interface, but you're looking at English content. This might be the case for a Spanish translator: they are using their native language as the default interface language, but they might want to edit the English content.

In D7 every translation is a new node, but in D8 all translations of the same node share the NID, so some configuration might differ there.

Multi-Language Link and Redirect (MultiLink) module can help with some multilingual link handling, automatically changing the output of links to point to the translation of the content based on the current interface language, so you don't mix interface and content languages, unless you create it like that on purpose in menus.

The way to correctly tell search engines about pages being translations of one another is through `hreflang`: Hreflang.

---
Tags: nodes, i18n-l10n
---


# Question
Title: How to make custom blocks print unsanitized markup
Goal: I like to create a block to display phone no and a link as shown below:

Structure \> Block layout \> custom block \> Add custom block, added this:

When I go to my site, I see this:

How can I create a block based on my above goal?

---

**Update 1**

Full HTML shows no CKEditor

FULL HTML \> Configure shows this:

Block:

My page still shows html code:

# Answer
> 1 votes
TWO solutions:

1.-in text formats, disable WYSYWIG in full-html format, you are looking HTML tags because of this.

2.-write your code in plain-text format, select 'plain-text' write code, when done, do choose full-html and save your block.

in other words, do not write code inside WYSYWIG.

---
Tags: 8, blocks
---


# Question
Title: How do I use the value of a webform_field as the default-value for a later webform_field?
Is there a way with Drupal 8 Webform UI to set the default value of a text field as the value of an earlier text field in the same form, and update via Ajax?

example:

```
user_name:
     '#type': textfield
     '#title': 'User Name'

nick_name:
    '#type': textfield
    '#title': 'Nick Name'
    '#default_value': '[webform_submission:values:user_name]'
    '#ajax': true

```

But the default value does not render the token and just prints plain text.

Any help is much appreciated, thanks.

# Answer
The short answer is 'No' to using tokens to sync two element values, unless the two elements are on different pages. The simplest solution is a write a little JavaScript to sync the nickname with the username.

You can search for examples of sync'ing two input fields.

The Webform module's Options admin widget uses a little JS to sync an option's value with the option's text. @see webform.element.options.admin.js
> 1 votes

---
Tags: 8, webforms
---


# Question
Title: How can I prevent a particular page being cached?
I have activated the cache on my Drupal 8 site, and of course all pages are cached as expected.

However, I'd like to have a specific page bypass that cache.

In my controller I built the page as follows:

```
public function myPage() {
  return [
    '#markup' => time(),
  ];
}

```

How can I tell Drupal not to cache my page?

# Answer
## For Drupal 7

Drupal has the function drupal\_page\_is\_cacheable() which can be used to set a page to uncacheable.

Here is the documentation: https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal\_page\_is\_cacheable/7

## For Drupal 8

```
// Deny any page caching on the current request.
\Drupal::service('page_cache_kill_switch')->trigger();

```

Then the code is:

```
public function myPage() {
  \Drupal::service('page_cache_kill_switch')->trigger();
  return [
    '#markup' => time(),
  ];
}

```

As usual, **clean your cache** once done.

## Best practice (*Drupal 8 | 9 | 10*)

For performance and good practice reasons it is recommended to **use dependency injection** inside your Controller class.

> modules/custom/my\_module/MyController.php

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * A controller class that respects Drupal coding standards.
 *
 * @see https://www.drupal.org/docs/develop/standards
 */
class MyController extends ControllerBase {

  /**
   * Page cache kill switch.
   *
   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch
   */
  protected $killSwitch;

  /**
   * {@inheritdoc}
   */
  public function __construct(KillSwitch $kill_switch) {
    $this->killSwitch = $kill_switch;
  }

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

  /**
   * Render my page with a renderable array.
   *
   * @return array
   */
  public function myPage() : array {
    $this->killSwitch->trigger();
    return [
      '#markup' => time(),
    ];
  }

}

```
> 44 votes

# Answer
Disable cache for a specific page

> Disable cache for a custom page from route declaration. If you want to disable cache for a custom controller (Custom module), You have `no_cache` option (YOUR\_MODULE.routing.yml). Example : File : mymodule.routing.yml

```
mymodule.myroute:
  path: '/mymodule/mypage'
  defaults:
    _controller: '\Drupal\mymodule\Controller\Pages::mypage'
    _title: 'No cache page'
  requirements:
    _access: 'TRUE'
  options:
    no_cache: 'TRUE'

```

Added 'no\_cache' route option to mark a route's responses as uncacheable
> 34 votes

# Answer
In Drupal 8, you can mention cache as max-age till you want your page ouput to be cached. For removing cache of a particular page(Controller page), write `'max-age' => 0,`.

```
public function myPage() {
  return [
   '#markup' => time(),
   '#cache' => ['max-age' => 0,],    //Set cache for 0 seconds.
  ];
}

```
> 16 votes

# Answer
If you need to do something with a contrib module you can use a RouteSubscriber to fix the cache issue. you need a service ... or just run `drupal gr` if have drupal console.

```
 namespace Drupal\mymodule\Routing;

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

 class RouteSubscriber extends RouteSubscriberBase {

/**
 * {@inheritdoc}
 */
protected function alterRoutes(RouteCollection $collection) {
  // Find the route you need ...
  if ($route = $collection->get('some.contrib.route')) {
    $options = $route->getOptions();
    $options['no_cache'] = TRUE;
    $route->setOptions($options);
  }
 }
}

```

more info see https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones
> 7 votes

# Answer
You can use this module to avoid drupal cache and also server side cache like varnish https://www.drupal.org/project/ape

Its works for me in Varnish cache on acquia server.
> 0 votes

---
Tags: caching, 8
---


# Question
Title: Webform Address Element and Canada provinces
In the webform (drupal 8) module I am using the address element and notice that the state/province field does not contain any Canadian provinces - only US States and Territories.

Where can I add the Canadian Provinces?

# Answer
> 3 votes
You can alter the default state options via /admin/structure/webform/config/options/manage.

I recommend installing the Address module for substantially better international address support.

---
Tags: 8, webforms
---


title: Add class to Previous / Next Button

text:
# Question
Title: Add class to Previous / Next Button
In Webform 7 I was able to add classes to the Previous / Next Page button but can't seem to be able to do this with Webform 8.

Is there a way to do this?

# Answer
> 4 votes
You need to 'Customize' your submit buttons via the button/link at the bottom of the form builder.

---
Tags: 8, webforms
---


title: Override field twig template in views

text:
# Question
Title: Override field twig template in views
I am trying to override the field rendered in a view. The field name is: **this\_is\_field**

I copied the /core/modules/views/views-view-field.html.twig and placed it my theme folder.

I renamed with both methods below

```
views-view-field--this-is-field.html.twig
views-view-field--display-name--block-name--this-is-field.html.twig

```

I have turned on Twig debugging and still the copied template isn't working.

Am I renaming wrong?

# Answer
It needs to be:

**views-view-field--\[field-machine-name\].html.twig**

If you look in Manage Fields, your field machine name is probably field\_this\_is\_field.

Therefore, in your case:

**views-view-field--field-this-is-field.html**

Note that this is will override for all views that have this field, if you want to only target a specific view use:

views-view-field--\[view-machine-name\]--\[field-machine-name\].html.twig
> 6 votes

# Answer
I tried second method from above answer and it didn't work. What works for me is views-view-field--\[view-name\]--\[field-machine-name\].html.twig
> 2 votes

---
Tags: views, 8
---


# Question
Title: Change Entity Value In hook_feeds_presave()
I am trying to modify data coming from a feed before it saved to a node by using hook\_feeds\_presave().

I have code that looks like this:

```
my_module_feeds_presave(FeedsSource $source, $entity, $item) {
     $email =  $item['email address'];
    //Remove "NOT GIVEN" from the email column to stop errors
    if($email == "NOT GIVEN"){
        $entity->field_email['und'][0]['value'] = '';
    }
}

```

I would think that when the node is saved that value in the email filed would be blank. However, it is still saving the value of *NOT GIVEN.*

If anyone can please point me in the right direction with this I would appreciate it.

Thanks,

Josh

# Answer
Can you mention your Drupal version?

* For Drupal 7, your code looks good enough at a first glance.
* If it's Drupal 8, all you need is `$entity->field_email = ''`.

If that doesn't work, leave a comment and I'll take a detailed look.
> 1 votes

# Answer
If you are using the email field from the Email Field module, then the column you need to save the value under is '**email**', not 'value'.

```
/**
 * Implements hook_feeds_presave().
 */
function my_module_feeds_presave(FeedsSource $source, $entity, $item) {
  if ($source->importer->id != 'my_importer') {
    // No modification needed for this importer.
    return;
  }

  $email = $item['email address'];
  // Remove "NOT GIVEN" from the email column to stop errors.
  if ($email == "NOT GIVEN"){
    $entity->field_email['und'][0]['email'] = '';
  }
}

```

Note that you can alternatively also use the hook `hook_feeds_after_parse()` to modify the parsed data:

```
/**
 * Implements hook_feeds_after_parse().
 */
function my_module_feeds_after_parse(FeedsSource $source, FeedsParserResult $result) {
  if ($source->importer->id != 'my_importer') {
    // No modification needed for this importer.
    return;
  }

  // Remove mail addresses that contain 'NOT GIVEN'.
  foreach ($result->items as &$item) {
    if (isset($item['email address']) && $item['email address'] == 'NOT GIVEN') {
      $item['email address'] = '';
    }
  }
}

```

Note that in the code examples above I added code to restrict modification to a particular importer. This is recommended if you are using multiple importers and the modification should only be applied to a single importer.
> 1 votes

---
Tags: feeds
---


# Question
Title: Use hook_cron to send daily mail but I get 4~5 the same mail every day?
I'd like to make all of my partners in my company receive daily metrics like new users, pageviews everyday, I wrote a custom module using hook\_cron.

This is my code:

```
function custom_metrics_cron() {
  global $language;

  $default = strtotime('-24 Hours', REQUEST_TIME);
  $last_send  = variable_get('custom_metrics_daily_last_send', $default);
  $only_after = strtotime('+24 Hours', $last_send);

  if (REQUEST_TIME >= $only_after) {
    variable_set('custom_metrics_daily_last_send', REQUEST_TIME);
    drupal_mail('custom_metrics', 'daily', MAIL_RECIEVERS, $language);
  }
}

function custom_metrics_mail($key, &$message, $params) {
  $date = date('m-d-Y', strtotime('-1 Day', time()));
  $metrics = custom_metrics_get_metrics();
  switch($key) {
    case 'daily':
      $message['subject'] = t('Daily Metrics: !date', array('!date' => $date));
      $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
      $message['body'][] = custom_metrics_get_metrics();
      break;
  }
}

```

It works okay, I get the mails everyday, but the problem is I get not only one mail, I already set the variable and make it send ONE mail every 24 hours but I still get 4~5 mails every 24 hours. Can anyone tell me where does I do wrong?

# Answer
> 5 votes
D7, I struggled a lot, this is what i did, works perfect, following modules are required: Job shcheduler, Rules, and optionally Rules switch user, i use core cron; make a custom module 'MYMODULE' and place this code:

```
   /**
   * Implements hook_cron_job_scheduler_info().
   *
   * Do not forget to run job_scheduler_rebuild_all() on any changes here,
   * see https://drupal.org/comment/8406919#comment-8406919
   */
  // * Implements hook_cron()
  function MYMODULE_cron_job_scheduler_info() {
    $schedulers = array();
  //add as many scheduled jobs as needed.
  //$schedulers['daily_email_6_am'] = array(...);
    $schedulers['daily_email_7_am'] = array(
      'worker callback' => 'send_emails_action_7_am',
      'jobs' => array(
        array(
          'type' => 'notification',
          'id' => 1,
          'crontab' => '0 7 * * 1-6', // 7am, mon-sat
          //'crontab' => '0 * * * *', // once a day, midnigth
          //'crontab' => '*/1 * * * *', // once every minute, dev settings
          'periodic' => TRUE
        ),
      )
    );
    return $schedulers;
  }
  function send_emails_action_7_am() {
    // Do stuff.
    rules_invoke_component('rules_send_emails_component_7_am');
}

```

now you have a cron based scheduled job at 7 am from monday to saturday that executes a rule-component machine name: 'send\_emails\_component\_7\_am', be carefull, function calls: rules\_MACHINENAME of component, built rule component to send your emails, i usually i built my emails with views rules module and have a great control to built email-body-value. see this answer, and this one also could be many emails, benefits of using views-rules as you can loop by views all users and filter them as needed and inject to rules whatever you imagine. emails are not 'duplicated', only 1 mail per user.

cron run as anonymous user, so, only if you have some content\_access restrictions your emails won't be sent, here comes the benefit of 'Rules switch user', do pay attention with this module settings as this img suggest, i hope this helps someone.

# Answer
> -1 votes
One of the safest general solutions is Elysia CRON module - when using it you can write your `hook_cron` without any checks, and set how often it should be really called in Elysia Cron GUI. That way you only need to code module-specific logic in your module, saving time. And if you will ever need to send mail twice a day, it will save you the need of updating module.

---
Tags: emails, cron
---


title: Using PHP cURL to send http get request

text:
# Question
Title: Using PHP cURL to send http get request
I am able to do the HTTP GET request using cURL in my custom function, my code below works fine for me, but is there Drupal way to do this?

```
function some_page_callback() {
    $url = 'https://api.example.com/data';
    $accesstoken = 'SoMedGFidHThX2NvdW50eV90bWNhOkEyakJEM2ND';
    $headr = array();
    $headr[] = 'Accept: application/json';
    $headr[] = 'Authorization: Basic '.$accesstoken;

    //cURL starts
    $crl = curl_init();
    curl_setopt($crl, CURLOPT_URL, $url);
    curl_setopt($crl, CURLOPT_HTTPHEADER,$headr);
    curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($crl, CURLOPT_HTTPGET,true);
    $reply = curl_exec($crl);

    //error handling for cURL
    if ($reply === false) {
       // throw new Exception('Curl error: ' . curl_error($crl));
       print_r('Curl error: ' . curl_error($crl));
    }
    curl_close($crl);
    //cURL ends

    //decoding the json data
    $decoded_data = json_decode($reply, true);

    // putting the data into table
      $rows = array();

      $output = '';
      // Example of theme_table().
      $output .= '<h2>Example</h2>';
      $headers = array(t('ID'), t('Name'));

      foreach ($decoded_data['data'] as $line) {
          $tablerow = array(
          array('data' => $line['id']),
          array('data' => $line['name']),
         );
          $rows[] = $tablerow;
      }
      $output .= theme('table', array('header' => $headers, 'rows' => $rows));

return $output;
}

```

# Answer
I ended up needing to do something like this not too long ago in a custom module. Drupal has a function called drupal\_http\_request() to hit the external URL. You can execute it inside a hook function if necessary in your module.

```
$url = 'http://my-url.com';
      $response = drupal_http_request($url);

```
> 2 votes

# Answer
The equivalent in **Drupal 8** would be the Guzzle HttpClient as documented by this change record

```
try {
  $response = \Drupal::httpClient()->request('GET', $url);
  $data = $response->getBody()->getContents();

  //if dealing with json file
  $decoded = json_decode($data);
  if (!$decoded) {
    throw new \Exception('Invalid data returned from API');
  }

} catch (\Exception $e) {
  return "";
}

```
> 1 votes

---
Tags: 7
---


title: Hide the shortcut toolbar

text:
# Question
Title: Hide the shortcut toolbar
How can I hide the shortcut toolbar in Drupal 8.6? I need the very top menu gone (the green part highlighted in screenshot).

# Answer
> 1 votes
It looks like you are using adminimal as admin theme, so go to `themes/contrib/adminimal_theme/css/adminimal.css` and paste this code in the bottom.

```
.toolbar-icon.toolbar-item {
  display: none !important;
}

```

It should do the trick.

# Answer
> 0 votes
The Toolbar module provides tabs (that you want to hide), and links related to those tabs. Since links are listed within the tab elements in HTML it isn't easy to just hide them with CSS.

But you can use the Toolbar Themes module.

Toolbar Themes configuration comes with the option not to use Toolbar tabs at all.

> \[ \] Show toolbar tabs
> Unchecked this will remove tabs except for the Manage tab which is replaced by an icon.

Most people also install Admin Toolbar to get the drop-down menus, it significantly speeds up navigating and number of clicks.

---
Tags: 8, toolbar
---


# Question
Title: Why does PhpSpreadsheet fail to identify my Xlsx file in public://?
I'm working on a module that imports a Xlsx file and inserts the rows to database. Everything works fine, except PhpSpreadsheet throws the error `Unable to identify a reader for this file` when my uploaded file is in `public`. This error doesn't happen when the file is in `base_path()`. Why is this happening? Below is my code:

```
public function submitForm(array &$form, FormStateInterface $form_state) {
    $connection = \Drupal::database();
    $fid = $form_state->getValue("xlsx_upload");
    $input = File::load(reset($fid));
    $input->setPermanent();
    $uri = \Drupal::service('file_system')->realpath($input->getFileUri());
    //$uri = '/home/joe/file.xslx'; <--- this works perfectly.
    $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile($uri);
    $spreadsheet = $reader->load($filename);
    $dataArray = $spreadsheet->getActiveSheet()->toArray();
    $connection->truncate("mitacan")->execute();
    $connection->query("SET NAMES utf8");
    foreach ($dataArray as $dataItem) {
      $connection->insert('mitacan')
      ->fields([
        'stokkodu'      => $dataItem[0],
        'logo'          => $dataItem[1],
        'resim1'        => $dataItem[2],
        'grupkodu'      => $dataItem[3],
        'grupadi'       => $dataItem[4],
        'grupindex'     => $dataItem[5],
        'paketadedi'    => $dataItem[6],
      ])
      ->execute();
    }
    drupal_set_message('Excel verisi veritabanına eklendi.');
  }

```

EDIT: The above code throws `"PHP message: Uncaught PHP Exception InvalidArgumentException: "File "" does not exist ." at File.php line 137"`, even though line 137 throws an exception saying it's not a file, but `\dpm(is_file($uri))` returns TRUE.

# Answer
> 2 votes
Looks like PhpSpreadsheet can't read URIs, but only file paths. You need to find the path to the file on the system.

```
$real_path_to_file = \Drupal::service('file_system')->realpath($file->getFileUri());

```

*(Ideally you'd inject file\_system and not call this service statically.)*

---
Tags: 8
---


# Question
Title: Changing the label of Change Password Form
How to change the form label from `Password` to `New Password` and `Confirm password` to `New Confirm password` on `THEME_form_user_form_alter`(without changing any `twig` files)? I had tried `kint($form['account']['pass'])` to see any possible way, no clue...

**Current Change Password Form**

Current password

|||||||||||||||||

Password **(to New Password)**

|||||||||||||||||

Confirm password **(to New Confirm password)**

|||||||||||||||||

```
function THEME_form_user_form_alter(&$form, $form_state) {
  kint($form['account']);
}

```

There are no `#title` element on `pass` field.

# Answer
You have to create a new module and use hook\_element\_info\_alter to alter title input like this:

```
function my_module_element_info_alter(array &$types) {
  if (isset($types['password_confirm'])) {
    $types['password_confirm']['#process'][] = '_mymodule_change_title';
  }
}

```

and process function

```
function _mymodule_change_title(&$element) {
  $element['pass1']['#title'] = t('New title 1');
  $element['pass2']['#title'] = t('New title 2');
  return $element;
}

```

and as a result
> 8 votes

---
Tags: views, 8
---


# Question
Title: How to have the autocomplete option with ajax in a text field?
I am struggeling with creation of tetxfield with autocomplete option for my Drupal 8. My Drupal website is multilingual, and on one view page we present some content in Default language, by typing in the textfield some other language, I need to change the language of the content. For this I created a filter (Translation language = Content language selected for a page), and I want to expose it in a custom block.

My custom block looks like following:

```
<?php
/**
 * @file
 * Contains \Drupal\filters\Plugin\Block\FilterLanguages.php
 */
namespace Drupal\filters\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * @Block(
 *   id = "block_filters_languages",
 *   admin_label = @Translation("Filter for languages"),
 *   category = @Translation("Filters"),
 * )
 */
class FilterLanguages extends BlockBase {

  /**
   * {@inheritdoc}
   */

public function build(){

$form['language'] = array(
  '#type' => 'textfield',
  '#placeholder' => t('Choose language autocomplete'),
  '#autocomplete_route_name' => 'filters.autocomplete',

);

return $form;
  }
}

```

To provide autocompletion option, I have created routing file:

```
filters.autocomplete:
  path: '/filters/autocomplete'
  defaults:
    _controller:'\Drupal\filters\Controller\AutocompleteController::handleAutocomplete'
 requirements:
    _access: 'TRUE'

```

And Controller:

```
namespace Drupal\filters\Controller;

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

class AutocompleteController extends ControllerBase{
  /**
   * Returns response for the autocompletion.
   */
  public function handleAutocomplete(Request $request) {

    $languages = \Drupal::languageManager()->getLanguages();
    return new JsonResponse($languages);
  }
}

```

I have oriented on the followin tutorial But the autocompletion still doesnt work. Could you please help me to solve the problem?

# Answer
You need to filter the user input and return the matches.

```
  public function handleAutocomplete(Request $request) {
    // Getting the user input.
    $string = $request->query->get('q');
    // Getting the languages.
    $languages = \Drupal::languageManager()->getLanguages();
    // Getting the matches.
    $matches = preg_grep("/$string/i", $languages);
    // Returning the matches.
    return new JsonResponse($matches);
  }

```
> 2 votes

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


# Question
Title: How to output from custom module without rest of theme
What the proper method of outputting a page from your module without any additional theming beyond your template, for example to make a page that is good for printing?

I've tried a few different methods based on Drupal 7 versions. The only one to work being to render the build array and the kill further PHP loading, however this doesn't feel right. In Drupal 7, I could set up a 'delivery callback' in the hook\_menu() - but I can't seem to figure out how to replicate that behaviour now.

my\_module.routing.yml:

```
my_module.user_timesheets:
  path: '/my_module/timesheets/{weekOf}/{uid}'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyModuleAdminController::timesheets'
    _title: 'My Module Timesheets'
  requirements:
    _permission: 'admin'

```

my\_module.module:

```
  $theme['timesheets'] = [
    'render element' => 'build',
    'template' => 'timesheets',
  ];

```

MyModuleAdminController.timesheets:

```
public function timesheets($weekOf, $uid = null) {
    $build['#theme'] = 'timesheets';

    ...code building values...

    $build['#staff'] = $staff;

    $build['#title'] = 'Timesheets - ' . $weekOf . ' to ' . $this->dateService->getWeekStartDate($weekOf);
    $build['#attached']['library'][] = 'my_module/timesheets';
    //print render($build);
    //die();
    return $build;
  }

```

my\_module.libraries.yml:

```
timesheets:
  css:
    theme:
      lib/timesheets.css: {}

```

Edit: To over-ride something like page.html.twig in your module, you make a template called page--my\_module--html.twig and then declare it in your modules my\_module\_theme() function.

```
/**
 * Implements hook_theme().
 */
function my_module_theme() {
  $theme['page__my_module__timesheets'] = [
    'template' => 'page--my_module--timesheets',
  ];

   return $theme;
}

```

# Answer
> 8 votes
The controller does not have to return a render array, it can also provide a symphony response, for example:

```
use Symfony\Component\HttpFoundation\Response;

$response = new Response();
$response->setContent('<h1>Hello world</h1>');
//$response->headers->set('Content-Type', 'text/xml');
return $response;

```

This will bypass the Drupal rendering and theming.

**Edit:**

You can use two approaches to replace your Drupal 7 code:

1) Override `page.html.twig` and `html.html.twig`, remove anything out of this templates and put only that in what you want.

2) Render the HTML like you are doing it now in Drupal 7 and use a Symfony response.

Rendering in Drupal 8:

```
use Symfony\Component\HttpFoundation\Response;

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

$response = new Response();
$response->setContent($output);

return $response;

```

# Answer
> 9 votes
If you utilize the html\_response.attachments\_processor and renderer services along with `BareHtmlPageRenderer` you can still get libraries to load in the head tag of an otherwise un-templated page.

```
use Drupal\Core\Render\BareHtmlPageRenderer;

$attachments = \Drupal::service('html_response.attachments_processor');
$renderer = \Drupal::service('renderer');

$bareHtmlPageRenderer = new BareHtmlPageRenderer($renderer, $attachments);

$response = $bareHtmlPageRenderer->renderBarePage($build, 'Page Title', 'markup');
return $response;

```

# Answer
> 6 votes
I do not have enough reputation to add a comment on a reply, but the anwser by @Arosboro is almost complete, except the "build variable is in the wrong spot. It must be the last variable, like so:

```
return $bareHtmlPageRenderer->renderBarePage([], 'Address', 'checkout_address', $build);

```

This way the twig variables I placed in $build were rendered correctly.

My full code:

```
$build = [
  '#theme' => 'checkout_address',
  '#content' => [],
  '#edit' => FALSE,
];

...

$attachments = \Drupal::service('html_response.attachments_processor');
$bareHtmlPageRenderer = new BareHtmlPageRenderer($this->renderer, $attachments);

return $bareHtmlPageRenderer->renderBarePage([], 'Address', 'checkout_address', $build);

```

And the template:

```
{{ content }}
{% if edit == true %}
    <button class="btn-edit-address">Edit Address</button>
{% endif %}

```

This is how I got it to work.

---
Tags: theming, 8, routes
---


title: Exclude a JavaScript file from a node

text:
# Question
Title: Exclude a JavaScript file from a node
I'd like to exclude a js file from loading on to a specific node.

Right now my libraries.yml file looks like this:

```
global-styling:
  version: 1.x
  css:
    theme:
      css/bootstrap/bootstrap.css: {}
      css/style2.css: {}
      css/header.css: {}
      css/color-1.css: {}
      css/themify-icons.css: {}
      css/jquery-ui.css: {}
  js:
    js/bootstrap.js: {}
    js/jquery-ui.js: {}
    js/popper.js: {}
    js/tooltip.js: {}
    js/wow.min.js: {}
    plugin/appear/jquery.appear.js: {}
    js/custom.js: {}
  dependencies:
    - core/jquery

```

I'd like to exclude the js/custom.js from loading on node/4. Alternatively I would like to load that file ONLY for the front page.

# Answer
**Delete/Exclude** `js/custom.js` from the `global-styling` section in `THEMENAME.libraries.yml` and define it as a library at the end of the same file

```
# THEMENAME.libraries.yml
custom-js:
  version: 1.x
  js:
    js/custom.js: {}
  dependencies:
    - core/jquery

```

And then include the library conditionally to where you want it using `THEMENAME_preprocess_page` function in `THEMENAME.theme`

```
//THEMENAME.theme
function THEMENAME_preprocess_page(&$variables) {

    //include it if its front_page
    if ($variables['is_front'] == TRUE) {
        $variables['#attached']['library'][] = 'THEMENAME/custom-js';
    }

    //include it if its NOT node 4
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface && $node->id() != 4) {
        $variables['#attached']['library'][] = 'THEMENAME/custom-js';
    }
}

```

For more info read the docs
> 4 votes

# Answer
If you want to load the file only for the front page, separate that file to another library like:

```
global-custom-styling:
  js:
    js/custom.js: {}

```

And preprocess page then attach library:

```
function mytheme_preprocess_page(&$variables){
  if ($variables['is_front'] == TRUE) {
    $variables['#attached']['library'][] = 'my-theme/global-custom-styling';
  }
}

```
> 2 votes

---
Tags: javascript
---


title: Multiple instances of a Custom Block?

text:
# Question
Title: Multiple instances of a Custom Block?
So I have a custom block that has been created within the module. I have used the drupal API to generate the brand new fields - which works perfectly.

However, I am having an issue regarding multiple instances of the custom block. As I want the blocks to be sandboxed as the custom fields are only related to the block used within the one region.

Now using Multi Block, I can create another instance of that block but the field is exactly the same. What would be the best approach for having one block but whenever its used, its custom fields per block.

```
case 'live_chat_block' :
    variable_set('text_variable', $edit['text_body']);
break;

```

Now the idea I had was to add in the "panel page" as variable ID but there might be a better way. Any suggestions would be useful.

---

Just to expand on what i would like to achieve:

We currently have panel pages implemented and we have built a custom block with custom fields inside that custom block. The requirement is that every block that we drag into one of the panel pages, we would like for them to have unique fields.

Panel Page: 1 Block ID: 123 Custom Field Title: Superman

Panel Page 2: Block ID: 123 Custom Field Title: Batman

Now as you see, the only thing that changes is the panel pages, the block stay the same and the custom fields need to be unique to that panel page and not the block.

Currently, when changing one block, it impacts on all the other blocks as well.

```
function livechat_block_configure($delta=''){
  $form = array();

  switch($delta) {
     case 'live_chat_block' :
        // checkbox example:
      $form['text_body'] = array(
        '#type' => 'textfield',
        '#title' => t('Enter in Title here'),
        '#default_value' => variable_get('text_variable', ''),
      );

        break;
  }
  return $form;

}

```

# Answer
> 0 votes
Add the following function in your template.php

```
function <themeName>_render_block($module, $delta, array $options = array()){
  $default_options = array(
    'title' => '<none>',
    'region' => -1,
  );

  $options = array_merge($default_options, $options);

  $block = db_query('SELECT * FROM {block} WHERE module = :module AND delta = :delta', array(':module' => $module, ':delta' => $delta))->fetchObject();
  if($block) {
    $block = block_load($module, $delta);
    $block->title = $options['title'];
    $block->region = $options['region'];
    $blocks = array($block);
    $rblocks = _block_render_blocks($blocks);
    $render_array = _block_get_renderable_array($rblocks);
    return drupal_render($render_array);
  }
  return "";
}

```

then when you want to render the block just write the following line

```
print render <themeName>_render_block($module_name, <id of block>, array of options like title etc)

```

You can find module name and block id by going to block configuration page so for the path admin/structure/block/manage/views/locations-block\_1/configure
module name is "views" and id is "location-block\_1"

So the render function will be

```
print render <themeName>_render_block("views", "location-block_1", array("title" => t("My block title")));

```

# Answer
> 0 votes
I would look at using Bean and Bean Panels to achieve what you're looking to do. Drupal 7's blocks were pretty minimalistic in terms of handling fields for instances. Bean was designed to address this (and was the basis for the much improved Drupal 8 custom blocks).

Another approach would be to put the custom content in fields on your nodes, and have views load that information using a contextual filter.

---
Tags: 7, blocks
---


# Question
Title: Admin block listing showing unwanted debug info
Suddenly my Drupal 8 admin panel is displaying some unwanted objects/arrays in different places. Below is a screenshot of the block layout page.

This is a localhost site that is not available to public.

# Answer
That looks like someone put a `print_r` or similar debugging call into your copy of Seven. If you are using git (which your project should be) you will be able to see the change in that tool and undo it. The other solution would be to download a fresh copy of Drupal and replace the files in the core directory with the ones in the fresh copy.

If there are multiple people working on the project, ask around about who was testing out ideas and ask them to undo the changes to the admin theme.
> 3 votes

---
Tags: 8
---


title: Change the site slogan on certain pages

text:
# Question
Title: Change the site slogan on certain pages
I have a Drupal 8 site with a content type called **Landing Page**. I'm using the bootstrap theme and I have the block showing the brand info (including site slogan) in the navbar.

I want some of the landing pages to have a different site slogan (shown in the navbar). How can I do that?

**What I tried**

I thought of adding a text field **custom site slogan** to my **Landing Page** content type and then using a twig template (content type node template) to show the slogan, but the slogan is printed in the header, and the template comes after that.

I could also make a different branding block for each page I need to change the slogan on and manually change the text in a twig template, but that seems like a very horrible, labor intensive way to do it.

# Answer
Ok, thanks to the hint from @Hudri, here's what I did.

In **mycustomtheme.theme**:

```
function MYCUSTOMTHEME_preprocess_block(&$vars) {
  if ($vars['configuration']['id'] === 'MYMODULE_site_branding_nolinks_block') {
    $site_config = \Drupal::config('system.site');
    $vars['site_slogan'] = $site_config->get('slogan');
    $vars['site_name'] = $site_config->get('name');
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      $type = $node->getType();
      // For landing pages, set the site slogan to the value of the slogan field.
      if ($type === 'landingpage') {
        $node = \Drupal::entityTypeManager()->getStorage('node')->load($node->id());
        $slogan_field = $node->get('field_slogan')->getValue();
        $slogan_field = $slogan_field[0]['value'];
        $vars['site_slogan'] = $slogan_field;
      }
    }
  }
}

```

But, we're not done yet, because the block (provided by my custom module) is cached the same for every page; it needs to be cached per URL, since it might be different for each landing page.

To fix that, in **mymodule/src/Plugins/Blocks/myBlock.php**, add this code:

```
  // Caching must be added here:
  // https://drupal.stackexchange.com/questions/223376/what-is-the-correct-way-to-set-cache-contexts-on-custom-blocks
  public function getCacheContexts() {
    return Cache::mergeContexts(parent::getCacheContexts(), ['url.path', 'url.query_args']);
  }

```
> 2 votes

---
Tags: 8, theming
---


title: How to fix my SQL Group By issue?

text:
# Question
Title: How to fix my SQL Group By issue?
I have a problem with MySql request on Drupal 8. I want to translate this request to Drupal:

```
SELECT x.camp AS camp, x.code AS espece, y.des AS designation, x.pf AS pf,
ROUND( SUM( x.pn - x.qte ) , 3 ) AS qte
FROM apport.apport x, apport.cereale y, apport.operation z
WHERE x.code = y.code
AND x.ope = z.code
GROUP BY x.camp, x.code
ORDER BY x.camp, x.code

```

This request works on PhpMyAdmin.

So, I do this:

```
    $query = $db->select('apport.apport','x');
    $query->join('apport.cereale','y', 'x.code = y.code');
    $query->join('apport.operation','z', 'x.ope = z.code');

    $query->fields('x', array('camp', 'code' ,'pf'));
    $query->fields('y', array('des'));

    $query->addExpression('ROUND(SUM(x.pn-x.qte),3)','qte');
    $query->groupBy('x.camp')->groupBy('x.code');
    $query->orderBy('x.camp','ASC')->orderBy('x.code','ASC');

    $result = $query->execute();

    $tableau = array();

    foreach ($result as $record) {
        $row['camp'] = $record->camp;
        $row['code'] = $record->code;
        $row['des'] = $record->des;
        $row['pf'] = $record->pf;
        $row['qte'] = $record->qte;

        $tableau[] = $row;

        print_r($tableau);
    }

```

But it doesn't work. The problem comes probably from here:

```
    $query->addExpression('ROUND(SUM(x.pn-x.qte),3)','qte');
    $query->groupBy('x.camp')->groupBy('x.code');

```

Because when I comment the above two lines, I do get a result.

Any help please ?

# Answer
> 2 votes
By default, Drupal use "Full\_ group\_by" so that why you need to Group all your fields.

If you want disable it and group only on one field, you have to update setting.php

Add this :

```
$databases['default']['default'] ['init_commands'] = [
'sql_mode' => "SET sql_mode = 'STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'",
];

```

# Answer
> 1 votes
I got the solution !

You need to group by all arrays

```
    $query = $db->select('apport.apport','x');
    $query->join('apport.cereale','y', 'x.code = y.code');

    $query->fields('x', array('camp', 'code'));
    $query->fields('y', array('des'));

    $query->addExpression('ROUND(SUM(x.pn-x.qte),3)','qte');
    $query->groupBy('x.code')->groupBy('x.camp')->groupBy('y.des');
    $query->orderBy('camp','ASC')->orderBy('code','ASC');

```

I have deleted 'pf' because i didn't want to group by this and the table 'operation' because it was useless

bye :)

---
Tags: 8, database
---


# Question
Title: How to make user.html.twig template for two different pages (users)?
I want to make `user.html.twig` template for user ID1 is not such as to all other users. How to?

I tried this code in `MYTHEME.theme` file:

```
function MYTHEME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  if ($user = \Drupal::routeMatch()->getParameter('users')) {
    // For make files, like:
    // page--user--[id].html.twig
    $suggestions[] = 'page__user__' . $user->uid();
  }
}

```

But template `page--user--1.html.twig` or `page--user--%.html.twig` don't work. Cache is clear.

# Answer
Platon, you appear to be mixing up the template for the user itself (`user.html.twig`) and the overall page template (`page.html.twig`).

If you want to override the user template then you need to implement hook\_theme\_suggestions\_HOOK where "HOOK" is "user" which is the theme hook you are overriding.

Here is an example of what that code would look like if you were using Bartik (but of course in practice you should be using your own subtheme rather than hacking core):

```
function bartik_theme_suggestions_user_alter(array &$suggestions, array $variables) {
  $suggestions[] =  'user__' . $variables['elements']['#user']->id();
  return $suggestions;
}

```
> 3 votes

# Answer
In "themename.theme" file use below template suggestion hook

```
function themename_theme_suggestions_user_alter(array &$suggestions, array $variables) {
    if($currentUserID == 10){
        $suggestions[] =  'user__info';
    }
    elseif($currentUserID == 12){
        $suggestions[] =  'user__profile';
    }
  return $suggestions;
}

```

and create two new files "user--info.html.twig" and "user--profile.html.twig" under 'themename/templates/page/' directory and copy the content of "user.html.twig" and paste into it
> -1 votes

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


# Question
Title: How can I define HTML element classes with twig pattern fields?
I want to use drupal fields to define class names in ui\_patterns. i.e. define a field in a pattern twig.html file and use its {{ twig variable }} as a class name. The following doesn't work. Is there a correct way of doing this? is it even possible?

```
{%
set classes = [
'class_name_1',
'class_name_2',
{{ ui_yml_field_name }},
]
%}
<div{{ attributes.addClass(classes) }}>

```

# Answer
> 1 votes
yaml\_field\_name.field\_drupal\_machine\_name\[0\]\['#markup'\] gave me the selection. problem solved.

---
Tags: theming
---


# Question
Title: Return data from WebformHandler to Controller
I created WebformHandler where I need to get data entered in the form on submit. It's something like this:

```
<?php

namespace Drupal\xxx\Plugin\WebformHandler;

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

/**
 * Form submission handler.
 *
 *
 * @WebformHandler(
 *   id = "xxx",
 *   label = @Translation("xxxx"),
 *   category = @Translation("xxx"),
 *   description = @Translation("xxx"),
 *   cardinality =
 *       \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
 *   results =
 *    \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 * )
 */
class XxXx extends WebformHandlerBase {

  public function confirmForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {

    $values = $webform_submission->getData();
    // Get data here
  }
}

```

I also have the Controller and defined route with template file. Controller looks like this:

```
<?php

namespace Drupal\xxx\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\xxx\Plugin\WebformHandler;

/**
 * Class SearchFlightsController.
 */
class XxXController extends ControllerBase {

  /**
   * xXx.
   *
   * @return array
   *   Return search parameters string.
   */
  public function xXx() {

    return [
      '#theme' => 'xxx',
      '#search_query' => $this->t('Test Value'),
    ];

  }

}

```

My question is how to pass the data that I get in WebformHandler on form submit to Controller that need to show the page with defined route?

# Answer
> 0 votes
I don't know why you want to pass the data to the controller, you can do anything with the data in the webformhandler code. or you can pass the data using the namespace declared on the controller. please check the following code. Inside the controller file place the below code that I have added new function to handle the webform data.

> ```
> namespace Drupal\xxx\Controller;
>
> use Drupal\Core\Controller\ControllerBase;
> use Drupal\xxx\Plugin\WebformHandler;
>
> /**
>  * Class SearchFlightsController.
>  */
> class XxXController extends ControllerBase {
>
>   /**
>    * xXx.
>    *
>    * @return array
>    *   Return search parameters string.
>    */
>   public function xXx() {
>
>     return [
>       '#theme' => 'xxx',
>       '#search_query' => $this->t('Test Value'),
>     ];
>
>   }
>
>   public function getwebform($formdata){
>       /** place your code what want to do with $formdata*/
>   }
>
> }
>
> ```

//After that inside the webformhandler code write the following code /\** take the data from webform and save in an array variable $formdata then pass to the function defined inside the controller \*/

use Drupal\xxx\Controller\XxXController; $webfrmdata = new XxXController;
$webfrmdata-\>getwebform($formdata);

I have not tested but hope this code can help you

---
Tags: 8, routes, webforms
---


# Question
Title: Set "Use the administration theme when editing or creating content" to true in install profile
I am creating an installation profile, and I can succesfully download and enable my custom theme as default. The issue I am running into is the "Use the administration theme when editing or creating content" setting is disabled on a fresh install, and I always want that enabled.

1. How do I enable the "Use the administration theme when editing or creating content" setting in my install profile?
2. What is the easiest way to find out how to configure settings like this in the future? The install profile documentation does not give any info on this, and I can't find anything in the API.

Update: I've found this API article api document to be helpful in figuring out which fields to target.

# Answer
> 2 votes
Setting it is as simple as:

```
variable_set('node_admin_theme', 1);

```

Most (not all, but most) config settings used in Drupal are managed using a `system_settings_form()`, which basically takes the array keys of the elements used in that form, and saves them as variables.

So an abridged version of the theme settings form would be

```
function some_form($form, &$form_state) {
  $form['node_admin_theme'] = array(
    '#title' => t('Use the administration theme when editing or creating content'),
    '#type' => 'checkbox',
    '#default_value' => variable_get('node_admin_theme', 0),
  );

  return system_settings_form($form);
}

```

When Drupal processes that form, a variable called `node_admin_theme` is created/updated with the appropriate value.

If you're certain a form is using `system_settings_form()`, finding the names of the associated variables is as easy as inspecting the elements themselves and looking at the 'name' parameter, e.g.

If you're not sure, lookup the function that defines the form and check. If it does use `system_settings_form()` then great, and if not you get an insight into how that form actually manages its data.

# Answer
> 2 votes
I spent sometime on your question 1. and i found this solution : Create a file named : "node.settings.yml" and put it in your config\>install folder of your profile. Just write this in the file :

```
use_admin_theme: true

```

Edit: this solution is for drupal 8.

---
Tags: installation
---


# Question
Title: Must at least one bundle have the same name as the entity in hook_entity_info()?
I'm working with `hook_entity_info`, and I'm defining an entity which will have multiple bundles.

Do I need to define a bundle which has the same name as the entity, or will the base entity become entirely "abstract" once I define entity bundles?

In the below piece of code, I've defined a `setting` entity which has the bundle `generic`. Should `generic` really be called `setting`, or can i completely regard the entity as an "abstract" concept?

```
function settings_entity_info() {
  $info['setting'] = array(
    'access callback' => 'settings_entity_access',
    'admin ui' => array(
      'path' => 'admin/structure/settings',
      'controller class' => 'EntityOperationsDefaultAdminUIController',
    ),
    'base table' => 'setting',
    'bundle keys' => array(
      'bundle' => 'type',
    ),
    'bundles' => array(
      'generic' => array(
        'label' => t('Generic Setting'),
        'admin' => array(
          'path' => 'admin/structure/settings/generic',
        ),
      ),
    ),

```

# Answer
> 1 votes
No, it's not required. It's not necessary to have a bundle whose machine name is the same machine name used for the entity type. And no, defining bundles doesn't make the entity more abstract in any way.

See, for example, `node_entity_info()`, where none of the content types (which are node bundles) is called *node*. Vice versa, in `user_entity_info()` the only bundle is *user*.
What you can gather from the implementations of `hook_entity_info()` done from Drupal core modules is that entities with a single bundle use the same machine name for the bundle and the entity. That is not mandatory, though.

What Drupal assumes is that, if `hook_entity_info()` doesn't define any bundle, the entity has a single bundle named after the entity type. See `entity_get_info()`.

```
    // If no bundle key is provided, assume a single bundle, named after
    // the entity type.
    if (empty($entity_info[$name]['entity keys']['bundle']) && empty($entity_info[$name]['bundles'])) {
      $entity_info[$name]['bundles'] = array(
        $name => array(
          'label' => $entity_info[$name]['label'],
        ),
      );
    }

```

---
Tags: 7, entities
---


title: Dropbutton in Twig

text:
# Question
Title: Dropbutton in Twig
I'm adding a few links to a views twig template file and I would like to render them as a dropbutton. For example ...

Is this at all possible ... to render this in twig? If this were a form, I understand how I could define it, but it's just a straight collection of links. I'm sure I could locate some other CSS and JS to make this work, but would love for it to just keep the consistent look if possible.

Thanks!

# Answer
You can build and manipulate render arrays inside a Twig template, and then render them with the `render_var()` function or the `|render` filter: https://www.drupal.org/node/2448219

As dropbutton is a render element this means you can define it in Twig just as you would in a form, and then directly render it.
> 0 votes

---
Tags: 8, theming
---