# Question
Title: Getting session variable in view contextual filter drupal 8
I am new to Drupal 8. I get group\_id in session variable just like that `$_SESSION['groupbysession']['group_id'] = $path[2];`. now i want to get that session variable in view **Contextual filters**.I have no idea how to do this. I also use view extra module for this but doesn't work for me.Thanks in advance

# Answer
> 0 votes
You'll need to create a custom module and pass the value Group ID value using hook\_views\_pre\_view

Example:

```
/*
 * Implements hook_views_pre_view()
 */
function mymodule_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
  // Modify contextual filters for my_special_view.
  if ($view->id() == 'my_special_view') { // target a specific view
    // if you want you could make it even more specific by adding ex: "&& $display_id == 'block_1')"
    $group_id = $_SESSION['groupbysession']['group_id'];
    $args[0] = $group_id; // set argument
  }
}

```

---
Tags: group
---


# Question
Title: How do I detect the language using node alias
I know to get the current language of a website:

```
$current_lang = \Drupal::languageManager()->getCurrentLanguage()->getId();

```

However, given that I have a node alias

```
$alias = \Drupal::service('path.alias_manager')->getAliasByPath('/node/'.$nid);

```

How do I get the language of that `$alias` node?

# Answer
> 1 votes
To get the path alias of specific language try with:

```
$current_lang = \Drupal::languageManager()->getCurrentLanguage()->getId();
/** @var \Drupal\Core\Path\AliasManager $aliasManager */
$aliasManager =  \Drupal::service('path.alias_manager');
$alias = $aliasManager->getAliasByPath('/node/10', $current_lang);

```

If you want to get the language code from alias try with:

```
$aliasArray = \Drupal::service('path.alias_storage')->load(['source' => '/node/' . $nid]);
$lang_code = $aliasArray['langcode'];

```

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


# Question
Title: Ajax Multiple Callbacks is not working for first callback?
I have been trying to load the data to other select list field from the first select list callback.

I want to change the two select list variables based on the first select list on changes, please refer the below sample code for understanding.

```
function example_form_alter(&$form, FormStateInterface $form_state) {
     $form['field_example']['widget']['#ajax'] = [
      'callback' => 'example_ajax_callback',
      'wrapper' => 'example-company-wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => t(''),
      ],
    ];

function example_ajax_callback(&$form, FormStateInterface $form_state) {
  $first_callback = example_company_form_trigger(&$form, FormStateInterface $form_state);
  $second_callback = example_company2_form_trigger($first_callback, $form_state);
  return $second_callback;
}

function example_company_form_trigger(&$form, FormStateInterface $form_state) {
return $form['field_example1'];
}

function example_company2_form_trigger(&$form, FormStateInterface $form_state) {
return $form['field_company2'];
}

```

When the ajax callback is calling, the second callback (example\_company2\_form\_trigger ) is only working, the first callback(example\_company\_form\_trigger) is not working.

I am facing this issue while returning the form.

Could anyone please help me to sort out this issue?

# Answer
> 3 votes
You don't need multiple ajax callbacks, you need multiple ajax commands.

First wrap each form element in a separate div container and then return for each one an ajax command from the same callback:

```
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;

...

  function example_ajax_callback(&$form, FormStateInterface $form_state) {
    $response = new AjaxResponse();
    $response->addCommand(new ReplaceCommand('#example-wrapper1', $form['field_example1']));
    $response->addCommand(new ReplaceCommand('#example-wrapper2', $form['field_example2']));
    return $response;
  }

```

---
Tags: 8, forms, hooks, ajax, taxonomy-terms
---


# Question
Title: Published checkbox only available for administrator
Only the administrator can publish a node of content type Report. It is not using content moderation or groups though other content types are. All permissions are set for the "site admin" to create/edit own/others of this type. The only buttons available are "Save" and "Preview" and the published checkbox doesn't show for non-administrator users. Save sets as "Draft" even though it's not using content moderation.

# Answer
This answer discusses the different permission settings that would allow non-admins to have access to this. However, that would give them too much permission that they shouldn't be allowed to have in our case (both permissions show the "Warning: Give to trusted roles only;" message). Our work around was to create a "simple workflow" that would only have draft and published states so that these users can publish.
> 1 votes

# Answer
You can use the following module.

Override Node Options

The Override Node Options module allows permissions to be set to each field within the Authoring information and Publishing options field sets on the node form. It also allows selected field sets to be set as collapsed and / or collapsible.
> 2 votes

---
Tags: nodes
---


title: Cache clearing without drush

text:
# Question
Title: Cache clearing without drush
I am using Drupal 8, and I am wondering how I can clear more caches than the button in admin/config/development/performance does.

I have had trouble with installing Drush, so I am looking for any alternative solutions.

# Answer
Just execute core/rebuild.php.
As the documentation says, it rebuilds the cache even when Drupal doesn't work; it require a token you can generate with scripts/rebuild\_token\_calculator.sh, so you call it as http://example.com/core/rebuild.php?token=TOKEN\_YOU\_GET\_FROM\_THE\_SCRIPT.
> 8 votes

# Answer
Check out Admin Toolbar for Drupal 8, it emulates all the dev functions from a drop down menu like we had in Drupal 7 from Admin Menu. Be sure to activate "Admin Toolbar Extra Tools" as part of the module.
> 1 votes

# Answer
That button clears all caches, just like drush would.

The only alternative to that would be to clear the caches directly in the database, which isn't much convenient.
> 0 votes

# Answer
The methods I've come across for clearing the JavaScript cache in Drupal (either from the Admin UI or from Drush) do not work reliably, which causes a **huge** amount of frustration when you're using a framework on top of Drupal to create a web application.

The workaround I use is to alter the version number in your module.libraries.yml file, which is at the root of your module folder.

Example:

```
reporting:
  version: 1.31
  css:
    layout:
      css/jquery.notifyBar.css: {}
      css/tagify.min.css: {}
      css/bootstrap-datepicker.min.css: {}
    theme:
      css/reporting-theme.css: {}
  js:
    js/smsw-utils.js: {}
    js/shim.min.js: {}
    js/xlsx.full.min.js: {}
    js/reporting.js: {}
    js/knockout-min.js: {}
    js/jquery.notifyBar.js: {}
    js/bootstrap-datepicker.min.js: {}
    js/tagify.min.js: {}
  dependencies:
    - core/jquery
    - core/drupalSettings

```
> 0 votes

---
Tags: 8, caching
---


# Question
Title: How to set Ajax callback from jquery on node edit form?
I must to create a dependent Fields with three fields in my content type. This fields are select list, but the options for each Field will be prepopulate from a sql query on external DB.

So, this is my form.js file:

```
 (function ($, Drupal) {
  'use strict';

  Drupal.behaviors.customTest = {
    attach: function (context, settings) {
      getTypes();

      function getTypes() {
        $('#edit-field-test1 option').not(':first').remove();
        alert("test")
        var request = $.ajax({
          url: "../../modules/custom/my_module/script/ajax.php",
          method: "POST",
          data: 'field_test1 =1',
          dataType: "json"
        });

        request.done(function(data){
          var opt = '';

          for(var i = 0, max = data.length; i < max; i++){
            opt += '<option value="'+data[i].id+'">'+data[i].name+'</option>';
          }

          $('#edit-field-test1').append(opt);
        });

        request.fail(function(jqXHR, textStatus){
          alert('Request failed: '+textStatus);
        });
      }
    }
  };
}(jQuery, Drupal));

```

And this is my ajax.php file:

```
    <?php
include '../db/bd.php'; <!--This file With host, user, password external DB-->

if(\Drupal::request()->request->get('field_test1')){
    $out = array();
    $sql = "SELECT * FROM `car_type`";
    $res = $db->query($sql) or die(mysqli_error($db));
    while($row = mysqli_fetch_object($res)){
        $out[] = array(
            'id' => $row->id_car_type,
            'name' => $row->name
        );
    }
    echo json_encode($out);
}

```

So, form.js file is declarated in my\_module.libraries.yml, but ajax.php? where should i declare it? how do i use it?

# Answer
> 0 votes
Listening to your suggestion I did this. Now this is **my\_module.module** file:

```
    /**
 * Implements hook_form_FORM_ID_alter().
 */
function my_module_form_node_test_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  $form['field_test1']['widget']['#ajax'] = [
    'event' => 'change',
    'callback' => 'my_module_myAjaxCallback',
    'disable-refocus' => FALSE,
    // Or TRUE to prevent re-focusing on the triggering element.
    'progress' => [
      'type' => 'throbber',
      'message' => t('Verifying entry...'),
    ]
  ];

  $form['#attached']['library'][] = 'my_module/trytest'; //form.js
}

/**
 * An Ajax callback.
 */
function my_module_myAjaxCallback(array &$form, FormStateInterface $form_state) {
  $db = new mysqli('host', 'user', 'password', "db");
  mysqli_set_charset($db, "UTF8");
  // Check connection
  if ($db->connect_error) {
    die("Connection failed: " . $db->connect_error);
  }
  else{
    echo "Connected successfully";
  }

  if(\Drupal::request()->request->get('field_test1')){
    $out = array();
    $sql = "SELECT * FROM `car_type`";
    $res = $db->query($sql) or die(mysqli_error($db));
    while($row = mysqli_fetch_object($res)){
      $out[] = array(
        'id' => $row->id_car_type,
        'name' => $row->name
      );
    }
    echo json_encode($out);
  }
}

```

Obviously it doesn't work because I don't know if it is correct to insert the data of the connection to the DB in this file and even if the code to return the query result to the file form.js. is correct.

---
Tags: 8, javascript
---


title: Import date field with feeds

text:
# Question
Title: Import date field with feeds
I have a csv with a Date field that contains the date in one of the following formats:

* dd/mm/yy (ex. 13/11/04)
* dd/mm/yyyy (ex. 13/11/2004)

I need to import these dates to my field in the format dd-mm-yyyy, using feeds.

I've tried everything but without success. I have my date field set with my custom date format (dd-mm-yyyy).

What do I need to do in feeds (or even feeds tamper) to import this data?

Thanks.

# Answer
I've struggled with this question today, and because i didn't found any clear answer here's the method with drupal 8.7:

* go to your node type structure, and select the display of your field (for example : DD-MM-YYYY)
* go back to the feeds mapping, remove your date entry.
* add a new entry for the date, or rebuild the entire mapping if you can't change the order of your csv.
* clear the cache
* the date work now with your new format
> 1 votes

# Answer
The date itself typically is stored in the mysql database as a timestamp or datetime format, depending on the configuration when you setup the field.

To ensure the Feeds' built-in date mapper importer processes the dates properly, I recommend:

1. open the CSV as a spreadsheet
2. reformat the date column to be an integer timestamp field
3. Resaved the csv with the numeric value for the date rather than the formatted value.
4. Update your feed importer mapping for the revised date field/column data from the CSV.
5. Run the import.

Alternatively, the Feeds Tamper module may be used to parse the date parts from a string formatted date in your Csv, and then join them as needed into a properly formatted date entry; but it would still require a consistent format in the csv. (you need either two or four-digit years in all the dates)
> 0 votes

# Answer
Goussing is right, this ansewr is based on his (i upvoted his answer), i did this on D7, steps:

1.- convert your date to unix (https://www.extendoffice.com/documents/excel/2473-excel-timestamp-to-date.html), (i did this in libreoffice, same thing) this way no matter wich language is your drupal site and date formatting.

2.- go to your node display settings, select your date field (my case a field collection field), select custom and in format enter U (for unix).

3.- important! as Goussin sugests, delete this field mapping and re-enter it again, dont mind of CVS order in columns.

4.- clerar caches

5.- do your import by feeds.

6.- change your field display as desired. done.
> 0 votes

---
Tags: datetime, feeds
---


# Question
Title: Install using Composer doesn't create .htaccess file
Followed instructions at (https://www.drupal.org/docs/develop/using-composer/using-composer-to-install-drupal-and-manage-dependencies) to install Drupal with Composer using the command:

"**composer create-project drupal/recommended-project my\_site\_name\_dir**"

Composer download all the files and displayed that Drupal was ready to install. However, when trying go to the page in a browser get "Forbidden You don't have permission to access / on this server. "

Looking in the "my\_site\_name\_dir" there is no .htaccess file so the server doesn't know to go into the "/web" subdirectory. The "my\_site\_name\_dir" directory has only the following files: /Vendor /web .editorconfig .gitattributes composer.json composer.lock

Should the .htaccess file be created automatically by Composer? I thought Composer used to do this in earlier installations. Is there a recommended .htaccess template to use. Thanks.

Environment: Windows 10, PHP Version 7.1.20, Apache 2.4

# Answer
> 2 votes
Both `drupal-composer/drupal-project` and `drupal/recommended-project` create Drupal installations with a relocated `DOCROOT`, or web root. So, the .htaccess folder isn't in the root of the installation.

You need to point Apache to the 'web' directory, which is where the .htaccess and index.php files are. This is done at the Apache config level, not .htaccess level.

For example, on one of my servers, I have my git checkout in /var/www/prod. The config looks like

```
DocumentRoot /var/www/prod/web
<Directory /var/www/prod/web>
  AllowOverride All
  Options -Indexes
  Options +FollowSymLinks
  Require all granted
</Directory>

```

---
Tags: installation, composer, .htaccess
---


# Question
Title: How to properly restrict node access (including update/delete) based on field value?
I have following requirements:

* Users have (among others) role "tier1", "tier2" or "tier3". Higher value means more permissions and anonymous users are considered "tier0".
* Users from tier2 and tier3 can create certain node type - MyNode. And only these users can update and delete them.
* The node type MyNode contains (my custom) field for restricting access - it's a simple integer. 0 means all users can access it, 1 means users of tier 1-3 can access it, etc.

What's the proper way to implement the node restriction?

**What I tried & longer description of the problem**

After Googling and reading documentation, I found hook\_entity\_access. I simply iterated all fields and if I found my access field type, read the value and handle it. It was working pretty nicely for viewing, editing and deleting. But not for views - they completely ignored that.

After some more googling, I found that hook\_entity\_access/hook\_node\_access are ignored in views as explained on Node access rights. This page also explains that this problem should be solved by using hook\_query\_TAG\_alter, however I can't understand how it should be used. It seems to me I'm missing some bigger picture and failed to google it. But I found another solution - to use hook\_node\_access\_records with hook\_node\_grants. I implemented this solution (with a tutorial help).

So each instance of MyNode provide grant based on field value, e.g. gid 2 means tier 2-3 can access the node. Each user is given grants based on their tier role, e.g. user with tier1 receive grants with gid 1, 2 and 3. This fixed view problem, but caused another one - if I set access of a node to 3, then users of tier 0-2 cannot view it (that's correct), but user of tier 2 can *edit* it (that's problem).

After some testing, it seems like permissions are handled differently for view and update/delete. View grant permissions are AND-ed with basic permission system (/admin/people/permissions), but update/delete permissions are OR-ed. I used the basic permission system to determine which roles can generally create, update and delete MyNode nodes.

So my current solution is merge of both approaches - grant system for views and hook\_node\_access for working with nodes directly. However, it seems to me quite hacky, dirty solution - I practically implemented same thing twice in different systems, because each system can handle only subset of all operations. And so, my question is - what's the proper implementation? What is correct Drupal-way?

Note: of course, I looked at modules to solve this. I rejected most of them, because they're still in alpha/beta/rc phase, while lifetime of D8 is ending. How much time I would have to wait for D9 implementation? Others were imho too bloated for "simple" "compare numeric value with role and accept/reject".

**My system**: Drupal version: 8.8.3

# Answer
> 2 votes
You can implement hook\_node\_access\_records() and hook\_node\_grants() for this.

The idea is that in hook\_node\_access\_records(), you take the node as it is saved, and create a set of rules by which it can be accessed. These are saved as a row in the `{node_access}` records table in the database. Then, when the user tries to access the node, their account is provided, and you then build a set of records explaining the current user's information. These records are then compared with the rules by which the node can be accessed, as set in hook\_node\_access\_records(), and if there is a match, access is granted.

I believe this should get you on your way:

```
/**
 * Implements hook_node_access_records().
 */
function example_node_access_records(\Drupal\node\NodeInterface $node) {
  // Check the content type.
  if ($node->bundle() == 'content_type_with_tier_level') {

    $grants = [];

    // Get the tier level as it has been set on
    // the node.
    $tier_level = (int) $node->get('tier_level')->value;

    // Create access rules based on the tier level.
    switch ($tier_level) {
      // Tier 0.
      case 0:
        // Create a viewing grant for all users
        $grants[] = [
          'realm' => 'tier_view_level',
          // This will be the tier level of the
          // accessing user.
          'gid' => 0,
          'grant_view' => 1,
          'grant_update' => 0,
          'grant_delete' => 0,
        ];
        // Create an admin grant for tier 2 users
        $grants[] = [
          'realm' => 'tier_level_admin',
          // This will be the tier level of the
          // user accessing the node.
          'gid' => 2,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];
        // Create an admin grant for tier 3 users
        $grants[] = [
          'realm' => 'tier_level_admin',
          'gid' => 3,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];

        break;

      // Tier 1.
      case 1:
        // Create a viewing grant for tier 1
        $grants[] = [
          'realm' => 'tier_view_level',
          // This will be the tier level of the
          // accessing user.
          'gid' => 1,
          'grant_view' => 1,
          'grant_update' => 0,
          'grant_delete' => 0,
        ];
        // Create an admin grant for tier 2 users
        $grants[] = [
          'realm' => 'tier_level_admin',
          // This will be the tier level of the
          // user accessing the node.
          'gid' => 2,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];
        // Create an admin grant for tier 3 users
        $grants[] = [
          'realm' => 'tier_level_admin',
          'gid' => 3,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];

        break;

      // Tier 2.
      case 2:
        // Create a viewing grant for tier 2
        $grants[] = [
          'realm' => 'tier_view_level',
          // This will be the tier level of the
          // accessing user.
          'gid' => 2,
          'grant_view' => 1,
          'grant_update' => 0,
          'grant_delete' => 0,
        ];
        // Create an admin grant for tier 2
        $grants[] = [
          'realm' => 'tier_level_admin',
          // This will be the tier level of the
          // user accessing the node.
          'gid' => 2,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];
        // Create an admin grant for tier 3
        $grants[] = [
          'realm' => 'tier_level_admin',
          'gid' => 3,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];

        break;

      // Tier 3.
      case 3:
        // Create a viewing grant for tier 3
        $grants[] = [
          'realm' => 'tier_view_level',
          // This will be the tier level of the
          // accessing user.
          'gid' => 3,
          'grant_view' => 1,
          'grant_update' => 0,
          'grant_delete' => 0,
        ];

        // Create an admin grant for tier 3
        $grants[] = [
          'realm' => 'tier_level_admin',
          'gid' => 3,
          'grant_view' => 1,
          'grant_update' => 1,
          'grant_delete' => 1,
        ];

        break;
    }

    return $grants;
  }
}

/**
 * Implements hook_node_grants().
 */
function example_node_grants(\Drupal\Core\Session\AccountInterface $account, $op) {
  // Build an array of the user's tier levels.
  // All users are allowed to access tier0, so
  // this level is added by default.
  $tier_levels = [0];

  // Add tier 1 to the user's tier levels if they
  // have the tier1 role.
  if ($account->hasRole('tier1')) {
    $tier_levels[] = 1;
  }

  // And so on...
  if ($account->hasRole('tier2')) {
    $tier_levels[] = 2;
  }

  if ($account->hasRole('tier3')) {
    $tier_levels[] = 3;
  }

  // The key is the realm, the value is an array
  // containing one or more GIDs to be compared
  // to the access records. If a matching realm
  // and GID are found, access is granted.
  $grants['tier_view_level'] = $tier_levels;
  $grants['tier_level_admin'] = $tier_levels;

  return $grants;
}

```

# Answer
> 2 votes
> What's the proper way to implement the node restriction?

Don't re-invent the wheel ... The Group module is what you should be looking at. It creates groups as entities, making them fully fieldable, extensible and exportable. For this specific question, you'd enable the `gnode` submodule, and for each group type you would define the appropriate permissions (view, edit, delete, etc) for the various Content Types.

# More info

# Resources

---
Tags: 8
---


# Question
Title: How can I create a GET form with the Form API?
I have been struggling with the Drupal 8 Form API all afternoon. It seems that the API is not meant to create GET forms, while the comments state otherwise. I am trying to build sort of a filter-form that should pass it's parameters to the URL so that it can be bookmarked, etc.

My first problem is that the `FormBuilder->getForm($myForm)` method creates a `FormState` object that defaults to method POST. Even when I set my form's method to 'GET', the `FormState` object will check the request method before the form is even being created and since the requestmethod is GET and the FormState's method is POST it will not process anything at all.

So instead I tried to create my own `FormState` object (which I obviously set to GET) and call `buildForm` instead (that way bypassing the `getForm` logic):

```
$form = new MyForm();
$form_state = new FormState();
$form_state->setMethod('get');
$form = \Drupal::formBuilder()->buildForm($form, $form_state);

```

This seems to work better. However, as soon as I give my form a submit-button it then gets in some sort of redirect loop, which I haven't been able to pinpoint yet. I don't have such problems when using POST.

It's really weird that the API doesn't seem to be able to handle GET forms.

Also: Would I get this to work, the comments in the Form API code state that GET forms do not use a form-ID, however the FormInterface does require a `getFormId` method.

Could someone please clarify what I am doing wrong, or point out some documentation about this?

---

## A proper example

I decided to simplify my testscenario a lot, in order to make sure that I wasn't doing anything weird. So now my testscenario is as follows:

I created a simple module with a hook\_preprocess\_node. There I render my form and add it to the template:

```
<?php

use Drupal\my_module\Form\TestForm;

function my_module_preprocess_node(&$variables) {
    $form = new TestForm();
    $variables['test_form'] = \Drupal::formBuilder()->getForm($form);
}

```

My form is as simple as I could make it:

```
<?php

namespace Drupal\my_module\Form;

use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class TestForm extends FormBase {

  /**
   * @inheritDoc
   */
  public function getFormId()
  {
    return 'test_form';
  }

  /**
   * @inheritDoc
   */
  public function buildForm(array $form, FormStateInterface $form_state)
  {
    $form_state->setMethod('GET');

    $form['test_input'] = [
      '#type' => 'textfield',
    ];

    $form['actions'] = array(
      '#type' => 'actions',
    );

    $form['actions']['submit'] = [
      '#name' => 'test-submit',
      '#id' => Html::getUniqueId('edit-submit-test-form'),
      '#type' => 'submit',
      '#value' => 'Submit it',
    ];

    return $form;
  }

  /**
   * @inheritDoc
   */
  public function validateForm(array &$form, FormStateInterface $form_state)
  {
    // TODO: Implement validateForm() method.
  }

  /**
   * @inheritDoc
   */
  public function submitForm(array &$form, FormStateInterface $form_state)
  {
    // TODO: Implement submitForm() method.
  }

}

```

Now my node template renders a simple form containing an input field and a submit button. When I submit the form it submits using a GET-request and I see the fields appear as GET-parameters. However the Drupal formbuilder does not pick up the form as being submitted. It does not call the validate nor submit methods.

The form contains both `$form_state->setMethod('GET');` and `$form['#method'] = 'GET';` as suggested in the comments.

# Answer
> 3 votes
Here is an example of how to create a pure GET form with the form API, that does not require having to build a form state or create a custom form builder. With this example, the form can be called as any form (in a route, or by FormBuilder::getForm()).

```
namespace Drupal\example\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class TestForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'test_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    // Set the method.
    $form_state->setMethod('GET');

    // GET forms must not be cached, so that the page output responds without
    // caching.
    $form['#cache'] = [
      'max-age' => 0,
    ];

    // The after_build removes elements from GET parameters. See
    // TestForm::afterBuild().
    $form['#after_build'] = ['::afterBuild'];

    // Retrieve the parameter from the URL if it exists.
    if ($name = $this->getRequest()->query->get('name')) {
      // Show the user the submitted value.
      $form['display'] = [
        '#prefix' => '<p>',
        '#suffix' => '</p>',
        '#markup' => $this->t('Your name is @name', ['@name' => $name]),
      ];
    }

    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Say your name'),
      // Set #name to an empty string so it does not get passed to the
      // GET parameters.
      '#name' => '',
    ];

    return $form;
  }

  /**
   * Custom after build to remove elements from being submitted as GET variables.
   */
  public function afterBuild(array $element, FormStateInterface $form_state) {
    // Remove the form_token, form_build_id and form_id from the GET parameters.
    unset($element['form_token']);
    unset($element['form_build_id']);
    unset($element['form_id']);

    return $element;
   }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {}

}

```

# Answer
> 1 votes
I have looked at Views's exposed filters to copy the behaviour I want. Views however manipulates the behaviour in several places. I created my own FormBuilder instead (which wraps around the core's FormBuilder) in order to get the behaviour I want.

```
<?php

namespace Drupal\my_module\Service;

use Drupal\Core\Form\FormBuilder as CoreFormBuilder;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormState;
use Drupal\my_module\Form\AbstractForm;

class FormBuilder {

  /**
   * @var CoreFormBuilder
   */
  private $formBuilder;

  public function __construct(CoreFormBuilder $formBuilder)
  {
    $this->formBuilder = $formBuilder;
  }

  /**
   * @param $form AbstractForm
   * @param $method string GET|POST
   */
  public function getForm(AbstractForm $form) {
    if ($form->getMethod() !== 'GET' && $form->getMethod() !== 'POST') {
      throw new \Exception('Method must be either GET or POST');
    }

    /**
     * Other than core's FormBuilder, we provide a way to set the form's method to GET
     * Note that the getMethod()-method is not a default FormInterface method.
     * It is part of our own AbstractForm which implements both Drupal\Core\Form\FormInterface,
     * plus our own needed interfaces.
     */
    $form_state = new FormState();
    $form_state->setMethod($form->getMethod());

    /**
     * Because we remove the form ID's from the GET request,
     * we must set the form to always process.
     * And as a result of that, we must also disable the redirect,
     * or the submit process will become an endless loop.
     */
    if ($form->getMethod() === 'GET') {
      $form_state
        ->setAlwaysProcess()
        ->disableRedirect();
    }

    // Default behaviour copied from core's FormBuilder
    $args = func_get_args();
    // Remove $form_arg from the arguments.
    unset($args[0], $args[1]);
    $form_state->addBuildInfo('args', array_values($args));
    $build_form = $this->formBuilder->buildForm($form, $form_state);

    // Make sure that the form identifiers do not end up in a GET request
    if ($form->getMethod() === 'GET') {
      $build_form['form_build_id']['#access'] = FALSE;
      $build_form['form_token']['#access'] = FALSE;
      $build_form['form_id']['#access'] = FALSE;
    }

    return $build_form;
  }

}

```

By using this FormBuilder, it will:

* remove `form_id`, `form_build_id` and `form_token` from the rendered GET-form, so that these won't be send to the GET request when the form is being submitted;
* and because those identifiers are not there, the `form_state` will be set to setAlwaysProcess(), so that the form will be processed.

---
Tags: 8, forms
---


# Question
Title: Storing ajax callback variables in PrivateTempStore
I have an issue with changing / obtaining variables in form element's ajax callback function. *(Sorry for typos, I just placed a pieces of whole code)*.

I have form with input field, where user can select how many pieces of each product he want

```
$form['wrapper_amount']['value'] = [
        '#type' => 'number',
        '#prefix' => '<div class="d-flex align-items-end form-element">',
        '#suffix' => '<span class="form-element-unit">pcs</span></div>',
        '#name' => "amount--product-1",
        '#ajax' => [
            'callback' => '::calculatePricePerUnit',
            'event' => 'change',
            'disable-refocus' => TRUE,
            'progress' => [
                'type' => 'fade',
                'message' => NULL,
            ],
        ],
    ];

```

after choosing a number I calculate price using AJAX callback function and using

```
public function calculatePricePerUnit(array &$form, FormStateInterface $form_state)
{
    // ... price calculation for specific product
    // $new_price = (amount * price_per_unit);

    $total_price = (float)$form_state->get('total_price_with_vat') + $new_price;
    $response = new AjaxResponse();
    $response->addCommand(
        new InvokeCommand(
            '#total-price',
            'html', [$form_state->get('total_price_with_vat') . ' €']
        )
    );
}

```

The problem is that when used add amount to second product the `$form_state->get('total_price_with_vat')` is `0` again. It means that I cant store `$total_price` variable in $form\_state, because it's not persistent (I've already read this somewhere, that I can't store variables to $form\_state in AJAX callback function). So I tried to store it to `$form_state->setStorage($my_values)` but it didn't work either.

*Please note that all AjaxResponse commands are working and I only need to find best approach how to store data, not how to re-render form's elements.*

My next step is to store data in **PrivateTempStore**, but question is, if it's good approach? I don't need data on any other Wizard page, neither in Controller or any further step. I just need to calculate `$total_price` and some other data that I need to use multiple times in AJAX callback function, and at the end use webform API to send webform submission results via email.

# Answer
> 0 votes
PrivateTempStore is not the right fit for this. You want to store the value in the $form\_state, but you do not store it in the AJAX callback, you store it in the submit handler, then set the form to rebuild (which will persist the values in the storage. You can set a custom #submit handler on your ajax submit button that is only called when that button is clicked:

```
$form['wrapper_amount']['value'] = [
  '#type' => 'number',
  '#prefix' => '<div class="d-flex align-items-end form-element">',
  '#suffix' => '<span class="form-element-unit">pcs</span></div>',
  // note - #name is commented out, as you should never
  // need to change it in Drupal, and doing so will have
  // unexpected consequences.
  // '#name' => "amount--product-1",
  '#ajax' => [
    'callback' => '::calculatePricePerUnit',
    'event' => 'change',
    'disable-refocus' => TRUE,
    'progress' => [
      'type' => 'fade',
      'message' => NULL,
    ],
  ],
  '#submit' => ['::customSubmit'],
];

```

Then your custom submit will look like this:

```
public function customSubmit(array &$form, FormStateInterface $form_state) {
  $total_price = (float)$form_state->get('total_price_with_vat') + $new_price;
  $form_state->set('total_price', total_price);
  $form_state->setRebuild(TRUE);
}

```

After playing around with this a little, I can see that a submit button is required to be able to call a submit handler where rebuildForm() can be recalled. If you set the #ajax on a non-submit button, ajax is called, but rebuildForm() is not able to be called.

As such, I'd say the hack for this is to create an #ajax submit button as I've shown above, but hide it. Then add some custom JS on the number field, that on blur triggers a click of the hidden submit button.

# Answer
> 0 votes
Ok, according to answers, I updated my question. Can I update **$form\_state** values when triggering AJAX event on form element that is not type of 'submit' / 'button'?

```
$form['wrapper_amount']['value'] = [
    '#type' => 'number',
    '#title' => $this->t('Enter amount of product'),
    '#ajax' => [
        'callback' => '::calculatePricePerUnit',
        'event' => 'change',
        'disable-refocus' => TRUE,
        'progress' => [
        'type' => 'fade',
        'message' => NULL,
        ],
    ],
];

```

This is code for my **input type="number"** and every time user changes amount of product I want to call AJAX and update **$total\_price**. I'm summing up **$total\_price** each time user updates amount of product in form (there are multiple product in form). But I can't update **$total\_price** correctly, because I need to store it somewhere to obtain it next time, when user changes amount of product, so I can sum another price to it.

Is this possible somehow without having user to click every time on button to submit form to calculate price?

---
Tags: 8, forms
---


# Question
Title: Creating a route with a form and some content
i have created a route with a form:

```
    amu_404_redirect_import.admin:
      path: '/admin/config/amu_404_redirect_import/upload'
      defaults:
        _form: '\Drupal\amu_404_redirect_import\Form\Amu404RedirectImportForm'
\Amu404RedirectImportController::content'
        _title: '404 redirect Import'
      requirements:
        _permission: 'administrer AMU 404 redirection import'

```

if now i am creating a controller to display some content to the same page , the form is not displayed anymore

```
amu_404_redirect_import.admin:
  path: '/admin/config/amu_404_redirect_import/upload'
  defaults:
    _form: '\Drupal\amu_404_redirect_import\Form\Amu404RedirectImportForm'
    _controller: '\Drupal\amu_404_redirect_import\Controller\Amu404RedirectImportController::content'
    _title: '404 redirect Import'
  requirements:
    _permission: 'administrer AMU 404 redirection import'

```

how could i have both content displayed ?

# Answer
> 3 votes
As it mentioned in @Hudri answer it's not possible to define `_form` and a `_controller` in the same route.
I think the solution for your use case is to define only route for the controller and embed the form inside it, like the following:

```
amu_404_redirect_import.admin:
  path: '/admin/config/amu_404_redirect_import/upload'
  defaults:
    _controller: '\Drupal\amu_404_redirect_import\Controller\Amu404RedirectImportController::content'
    _title: '404 redirect Import'
  requirements:
    _permission: 'administrer AMU 404 redirection import'

```

and your controller should be something like:

```
namespace Drupal\ amu_404_redirect_import\Controller;

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

class Amu404RedirectImportController extends ControllerBase {

  public function content() {
    $myForm = $this->formBuilder()
      ->getForm('Drupal\d8_api_exp\Form\Amu404RedirectImportForm');
    $renderer = \Drupal::service('renderer');
    $myFormHtml = $renderer->render($myForm);
    // Add other markups here ....
    return [
      '#markup' => Markup::create("
                {$myFormHtml}
            "),
    ];
  }
}

```

# Answer
> 3 votes
As doc states

> defaults (required): Defines the default properties of a route. Provide **one** of the following to specify how the output is generated:
>
> \_controller
> \_form
> \_entity\_view
> \_entity\_list
> \_entity\_form
> \_route

you can't list a `_form` **and** a `_controller` in the same `routing.yml` entry, only one of those keys is allowed. Either append that content via form API to your form, or render the form manually in your controller.

---
Tags: forms, routes, page-controller
---


# Question
Title: How to use custom tokens in view header Drupal 8
I make custom token which i use in view filter but now i want to use in view header.The custom token doesn't show in view header Global: Unfiltered text (Global: Unfiltered text) or how i make "Available global token replacements" to use in view header Global: Unfiltered text (Global: Unfiltered text). Thanks in advance.

# Answer
One possible soliton is to simply when declaring your custom tokens in hook\_token\_info()

use `$info['tokens']['view']`

Ex:

```
$info['tokens'] = [
    'view' => [
       'my-custom-token' => [
          'name' => t('Custom Token'),
          'description' => t('A custom token I created.'),
       ],
       // 'my-second-custom-token' => [...
    ],
];

```
> 1 votes

---
Tags: views
---


# Question
Title: How to set Form API link href to # hashtag
In Form API when creating a link, the output a-anchor will have a prefix of "en/" in front of whatever I set as the href value and if href is set to "#" it will be output with the language prefix and # is escaped and becomes a code something like "en/%23"

this is the code:

```
$element['add_address'] = array(
            '#type' => 'link',
            '#title' => t('Add new address'),
            '#href' => '#',
        );

```

I need that link to not have a href destination value, as it's supposed to react to javascript only. I know I could do a preventDefault() or any of the same resulting bypasses with JS, but I'm curious how to make a empty anchor with the form API.

Thanks,

Alari

# Answer
> 0 votes
As per Clive (https://drupal.stackexchange.com/users/2800/clive) answer in the comments:

```
'#href' => '', '#options' => array('fragment' => ' ', 'external' => TRUE)

```

in the render array solves the issue and removes the pre-processing with the language prefixes.

# Answer
> 1 votes
Not sure if this will work, give this a try

```
'#href' => '&num',  OR  '#href' =>'&#x00023', OR '#href' => '&#35',

```

# Answer
> 0 votes
I would try this to create a link:

```

  l(t('My Anchor Link'), '', array(
     'fragment' => ' ',        // use a space here
     'external' => TRUE,      // this will solve your problem
     'attributes' => array(
        'title' => 'Title description'
   )

```

---
Tags: 7, forms
---


# Question
Title: How to add local task links to referenced entities for a specific content type?
I have a content type with some entity reference fields to another content types. I want to add local task tabs to the node view page, to link those referenced node. However I cannot figure it out how to do it only for the specific content type.

I have created a **my\_module.links.task.yml** file with following contents:

```
my_module.my_content.my_content_type:
  route_name: entity.node.canonical
  title: Overview
  parent_id: entity.node.canonical
  weight: 0
  class: '\Drupal\my_module\Plugin\Menu\MyContentTab'

my_module.my_content.my_referenced_node:
  route_name: entity.node.canonical
  title: Referenced content
  parent_id: entity.node.canonical
  weight: 10
  class: '\Drupal\my_module\Plugin\Menu\MyReferencedContentTab'
# ... More tabs to the other referenced nodes

```

The classes are working as they should, and providing the tabs to the referenced nodes correctly. However the tabs are also showing on all content types.

How can I make them show only on the specific content type?

# Answer
> 4 votes
The reason these tabs show up on all of your content types is that `entity.node.canonical` is the base route for all nodes. Since you're setting `entity.node.canonical` as the **parent\_id**, Drupal thinks you want these tabs displayed on every node page.

The easiest way to achieve your goal is probably to implement hook\_menu\_local\_tasks\_alter() with code similar to this:

```
  if ($route_name === 'entity.node.canonical') {
    /** @var \Drupal\node\Entity\Node $node */
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node->bundle() !== 'my_bundle') {
      $data['tabs']['my_module.my_content.my_content_type']['#access'] = FALSE;
      $data['tabs']['my_module.my_content.my_referenced_node']['#access'] = FALSE;
    }
  }

```

Because Drupal performs upcasting on this route, you can get a reference to the current node directly from `routeMatch()` as a parameter, and then compare its bundle to your custom content type. When they don't match up, we set access to FALSE for those tabs.

I think another approach that would probably work is to override the `getRouteParameters()` method of your LocalTaskDefault classes and use similar logic; if the current node isn't your custom content type, then return an empty array of route parameters.

A third approach might be to create a custom route for your specific content type and then assign that route as the **parent\_id** for these tabs.

---
Tags: 8, navigation
---


# Question
Title: Currency resolver - Cache problem on platform.sh
I'm using currency resolver (commerce) based on cookie to switch currencies in block (have a custom field for usd price in price variant). Locally everything's work fine (apache) but on platform.sh switcher block is not working.I think it has to do with some server caching (internal cache is disabled in drupal). I tried to add some yml config on platform.sh for disabling cache but without result. Did anyone have similar experience with this?

Thanks

# Answer
Solution is to add cookie to routes.yml file in .platform folder and than push it to the platform branch. After that currency resolver will work.
> 0 votes

---
Tags: commerce
---


# Question
Title: Private files get Access Denied for any non-admin role but only on server
Very odd problem. I have a bundle where a user uploads a file to a private file field. When viewing the bundle; they see the file listed and can see it is linked to the file; but when clicking the file, they get Access Denied. This is on a CentOS 7 server.

The part which makes this odd is that the site is version controlled and the same code is running on my local Windows development machine. I just grabbed a copy of the server db and installed on my local. So, technically, the sites should be identical. On my local, the user is able to view the private file.

Normally this would lead me to think it is a server issue; but, anyone with Administrator role can view the file. This suggests it is something controlled by Drupal.

On the server I have created a virgin bundle with only a single new file field; and the problem persists. So it appears to not be bundle or site config related.

# Answer
The issue is due to the File Entity module. This was still enabled on our site even though it has been deprecated. Once it is uninstalled; private files work as expected.
> 0 votes

---
Tags: 8, files
---


title: Returning from ajax callback ruins view

text:
# Question
Title: Returning from ajax callback ruins view
Currently I am hooking into the add to cart form on my website. I added ajax to the edit quantity buttons like :

```
    $form_quantity[$key]['#ajax'] = [
      'callback' => 'update_cart_order',
      'disable-refocus' => FALSE,
      'wrapper' => $form_div_id,
      'event' => 'change',
      'progress' => [
        'type' => 'throbber',
        'message' => t('Updating Cart...'),
      ],
    ];

```

Which works lovely. I will note that `$form_div_id` is an id I'm wrapping the entire form in just above this.
Now I don't think I fully understand what I am supposed to return from my ajax. The view I am hooking into lists the products on one side and the order total on the other.

In my callback I (seem to) successfully update my cart quantities. But returning gets rid of the order total from this form.
I do nothing to edit the form and just `return $form`. All I do is update the order item.

I've looked around and think I may not understand what the ajax return really does but cannot seem to make sense of it. I just want to update my total price without refreshing the whole page.

In 'update\_cart\_order' I am changing the quantities and ending with this :

```
  $order->save();
  $order->recalculateTotalPrice();

  return $form;

```

This causes the total price display to disappear. After refreshing the page to get it back the quantities are properly adjusted.

Please let me know if any more information is needed. :)

# Answer
It sounds like you have your AJAX callback working fine. But you said that the #ajax wrapper is wrapping the entire form. The elements returned from the ajax callback replace everything in the div provided as a wrapper. Since you are wrapping your whole form with the wrapper, everything inside that div (the whole form) is replaced with the elements from the ajax callback.

You'll need to be more selective with your wrapper element. Set it to only wrap the elements that should be replaced.
> 0 votes

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


title: Disable taxonomy pages

text:
# Question
Title: Disable taxonomy pages
Are there any way to disable the taxonomy pages? I saw a question that restricts access to them (Original question).

But I dont want the "access denied" message to be displayed, I want to remove the pages completely.

# Answer
If you don't need taxonomy you can always just disable the module.

If you still need the functionality but don't want the display pages to exist I guess you could implement `hook_menu_alter()` to remove them from the registry:

```
function MYMODULE_menu_alter(&$items) {
  unset($items['taxonomy/term/%taxonomy_term']);
  unset($items['taxonomy/term/%taxonomy_term/view']);
  unset($items['taxonomy/term/%taxonomy_term/feed']); // If you want to hide the feed as well.
}

```

I'd do some thorough testing after doing that though, I'm not sure if it would have any knock-on effects. Also if you're using the default taxonomy View for your taxonomy pages you'll obviously need to disable that as well.
> 8 votes

# Answer
This is an old question, but definitely worth adding another answer to due to Google pointing a lot of questions here.

I believe a great option for this issue would be Disable Term Node Listings module which allows you to 404 or 403 the taxonomy listing pages based on vocabulary.

**EDIT**

Updating my own answer here, the module above does not disable the /feed paths so is useless for those. I'll be utilising a hook\_menu\_alter to kill those.
> 2 votes

# Answer
I found this thread looking for the same functionality, and wanted to post another option I've found:

the Rabbit Hole module

(35k reported installs as of 2020-03), which allows to disable the default pages for nodes, terms, and other entities, with a variety of options, including per bundle and per entity.
> 2 votes

# Answer
So this is slightly more complicated than @Clive's response, but it's a bit more specific and probably more isolated. Basically, the strategy is to use `hook_init()` to redirect to a 404 page.

```
function mymodule_init() {
  $path_requested = explode("/", request_uri());
  if (isset($path_requested[1]) && $path_requested[1] == 'whatever_the_first_part_is') {
    drupal_goto('page-not-found');
  }
}

```

This is assuming you have a generic page not found page. There is a common approach for this that goes like this:

```
function mymodule_menu() {
  $items['page-not-found'] = array(
    'title' => '',
    'page callback' => 'error_handling_page_not_found',
    'access callback' => TRUE,
  );
  return $items;
}

function error_handling_page_not_found() {
  drupal_set_title('404\'d dood!');
  $cust_err = 'Still reticulating splines....';
  return $cust_err;
}

```
> 0 votes

---
Tags: 7, taxonomy-terms
---


title: Blocking access to taxonomy pages

text:
# Question
Title: Blocking access to taxonomy pages
I'd like to block access to all taxonomy pages for anonymous users.

For example I don't want them to be able to view `http://website.org/category/year/2525` or `http://website.org/taxonomy/term/42`.

Is there even some built-in functionality to achieve that? I'm using Drupal 6.

# Answer
> 2 votes
I'm using the Path Access module now. With it I'm blocking the access to the following URLs for anonymous users:

* category/\*
* taxonomy/\*

# Answer
> 4 votes
while `category/year/2525` is an alias for `taxonomy/term/xxx` you should restrict access to `taxonomy/term/*` for all anonymous users.

if you want do this via simple module:

```
function mymodule_init(){
  global $user;
  if(arg(0) == 'taxonomy' && arg(1) == 'term' && !$user->uid) {
     drupal_access_denied();
     exit;
  }
}

```

# Answer
> 1 votes
There are various modules that allow you to do this, e.g.

```
https://www.drupal.org/project/rabbit_hole

```

Personally, I use Page Manager + Panels. If you enable the Taxonomy term template in the main Panels screen, then edit, you can add a Variant and set the Variant Type to HTTP Response. You can then set selection rules to control when that variant will be applied, e.g.

```
This panel will be selected if Term being viewed vocabulary is "Package types",
and NOT (Logged in user has role "authenticated user").

```

This gives you all sorts of control, e.g. per vocabulary, per term, per user role. You could even use this as a way to publish/unpublish term pages by having a boolean field ("Published) and use the value of this field to control whether the term page is accessible.

You can also choose the HTTP response type, such as 301 (redirect someone accessing this to a different page), 403 (resource exists, you don't have access) or 404 (resource doesn't exist).

If you're not already using Panels, I'd probably start with Rabbit Hole and see if it delivers what you want.

# Answer
> 0 votes
You can also do this with hook\_menu\_alter: https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook\_menu\_alter/7

```
/**
 * Implements hook_menu_alter.
 * Check access for menu items.
 */
function mymodule_menu_alter(&$items) {
  $items['taxonomy/term/%taxonomy_term']['access callback'] = '_accesscheck';
}

/**
 * Callback to disallow access for the anonymous user.
 */
 function _accesscheck(){
   global $user;
   return $user->uid;
 }

```

# Answer
> 0 votes
Another option in D7 and D8 is the Rabbit Hole module, which provides a variety of options for how to handle default pages/lists, per bundle and per entity.

---
Tags: taxonomy-terms
---


title: How to show a teaser of the next node?

text:
# Question
Title: How to show a teaser of the next node?
At the bottom of each blog post I need to **show a teaser for the next blog post**. I know there is module to add links to next/prev blog. But I need to show more than a link. I need to show the title and summary. Could someone please suggest a way to achieve this?

# Answer
> 0 votes
I was able to achieve it by using the helper service defined in https://www.drupal.org/project/prev\_next.

---
Tags: nodes
---


# Question
Title: 403 forbidden for all css files located in /modules
My multi site Drupal 7 installation is suddenly unable to load any CSS file located in the /modules folder and subfolders (for example http://example.com/modules/system/system.base.css). I get "Failed to load resource: the server responded with a status of 403 (Forbidden)" in the browser console.

All CSS files for installed custom modules and all custom theme CSS files (inside /sites/all/modules and /sites/all/themes) are loading just fine.

Even more strange: the /modules/ CSS files load fine if I enable "Aggregate and compress CSS files." in Configuration \> Development \> Performance. When I disable "Aggregate..." I get the 403.

I realize that aggregating CSS is recommended in production sites, but I need to figure out what is going on and why the CSS files are not loading (they were loading fine earlier today). I did some changes in permissions earlier today, but I reverted those, with no success.

Any ideas?

PS: I noticed that Drupal adds "?obkukf" after .css - what is this, and does this have anything to do with the problem?

# Answer
> 1 votes
That extra query string are used to control caching. That will change everytime the cached files expired.

As per Dave Reid:

> It's to prevent browsers from caching those files when they change.

See these threads:

https://www.drupal.org/node/346711 https://stackoverflow.com/questions/11362261/appending-query-string-to-all-js-and-css-files-to-prevent-caching

# Answer
> 0 votes
This was likely due to a permissions issue on the module's directory (or a parent directory of the module's directory).

When you enable the setting for "Aggregate and compress CSS files" a new style sheet is created in the Drupal `files` directory (usually at sites/default/files), and the new file -- which contains a compressed copy of was in separate css files before -- is used in place of those separate files.

The Drupal files directory will have different permissions than the code. The Drupal files directory needs to be writable by the webserver, and the code should not be.

---
Tags: 7
---


# Question
Title: Why is my Ajax callback not returning anything?
I'm implementing an ajax callback function whats the issue with my code not returning anything. I'm new to backend

```
  <?php
use Drupal\node\Entity\Node;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\Query\QueryFactory;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;

/**
 * Implements hook_form_alter().
 */
function hook_form_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'webform_submission_go_to_csv_import_add_form') {
    // Choose for "Featured Type" field "N/A" value by default.
    $form['elements']['name']= [
      '#type' => textfield,
      '#title' => 'sammy',
      '#ajax' => [
                'callback' => '::some_ajax_sample',
                'wrapper' => 'edit-name',
                'event' => 'keyup',
                'progress' => [
                  'type' => 'throbber',
                  'message' => 'loading.....',
                ]
              ],
            ];

  }
}

function some_ajax_sample(array &$form, FormStateInterface $form_state) {

  $response = new Response($form['elements']['name']['#title'] = 'Test');
    return $response;
   }

```

# Answer
> 3 votes
there are a few things that could go wrong with this. Ajax callbacks can be a really hard thing to do and often requires a bit of trail and error. Hope this helps.

First of all, when your ajax callback function should not contain the "**::**".
This is only used when you are programming inside a Class, right now you're in a `.module`.
So you can change to.

```
'callback' => 'some_ajax_sample'

```

Furthermore you should check with a breakpoint if you even get inside the function. This should be resolved when removing the **::**.

Second thing you should do is add the wrapper div to your element.
You can do it like this:

```
$form['elements']['name']= [
  '#prefix' => '<div id="edit-name">'
  '#suffix' => '</div>'
  '#type' => textfield,
  '#title' => 'sammy',
  '#ajax' => [
            'callback' => 'some_ajax_sample',
            'wrapper' => 'edit-name',
            'event' => 'keyup',
            'progress' => [
              'type' => 'throbber',
              'message' => 'loading.....',
            ]
          ],
        ];
}

```

When you added the wrapper, Drupal knows which element should be replaced and update.

Last thing you can try is to remove the response and to just return the `$form['elements']['name']`.

Hope this helps.

---
Tags: 8, ajax, webforms
---


# Question
Title: Don't re-apply patches when requiring new module?
I keep running into the issue that, when requiring a new module with composer, existing packages are removed and reinstalled if they have patches defined in `composer.json`. For instance:

```
$ lando composer require drupal/media_entity_browser
    1/2:        https://packages.drupal.org/8/drupal/provider-2019-2$bae9fca7243956d61e44a716bdfb5c872f0f3e1a0b48b1dccfcae53d7e59c86f.json
    2/2:        https://packages.drupal.org/8/drupal/provider-2019-1$25356ca628b704d49a0ea504e6374f921a2b54d845d142aae1708cb94088516f.json
    Finished: success: 2, skipped: 0, failure: 0, total: 2
    1/2:        http://repo.packagist.org/p/provider-latest$56447e2294826167894155c32ceb596c58b3b2af059facd78694060f8a4d8c1c.json
    2/2:        http://repo.packagist.org/p/provider-2019-04$a612146345a708aa360ee61a695dd52d8d0faa79e136de5e075c95860af7c956.json
    Finished: success: 2, skipped: 0, failure: 0, total: 2
Using version ^1.0@beta for drupal/media_entity_browser
./composer.json has been updated
Gathering patches for root package.
Removing package drupal/core so that it can be re-installed and re-patched.
  - Removing drupal/core (8.7.3)
Deleting web/core - deleted
> DrupalProject\composer\ScriptHandler::checkComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
    1/4:        https://ftp.drupal.org/files/projects/media_entity-8.x-1.8.zip
    2/4:        https://ftp.drupal.org/files/projects/entity-8.x-1.0-rc3.zip
    3/4:        https://ftp.drupal.org/files/projects/entity_browser-8.x-2.1.zip
    4/4:        https://ftp.drupal.org/files/projects/media_entity_browser-8.x-1.0-beta3.zip
    Finished: success: 4, skipped: 0, failure: 0, total: 4
Package operations: 5 installs, 0 updates, 0 removals
Gathering patches for root package.
Gathering patches for dependencies. This might take a minute

```

For something like `drupal/core` this is really a problem on my local as it takes a while to download and reinstall the package. I can't seem to find a pattern. Sometimes it seems that the repatched package is a requirement of the one being required, other times they are unrelated or no packages are repatched at all.

Has anybody else come across this? Is there a way around it? Ideally we'd only re-apply patches to a package when it's updated.

Here's my composer.json since it was requested:

```
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "require": {
        "composer/installers": "^1.0.24",
        "cweagans/composer-patches": "^1.6",
        "drupal/address": "^1.4",
        "drupal/addtoany": "^1.10",
        "drupal/admin_toolbar": "^1.26",
        "drupal/antibot": "^1.2",
        "drupal/better_exposed_filters": "^3.0@alpha",
        "drupal/blazy": "^2.0@beta",
        "drupal/ckeditor_media_embed": "^1.3",
        "drupal/color_field": "^2.0",
        "drupal/config_inspector": "^1.0@beta",
        "drupal/config_update": "^1.6",
        "drupal/console": "~1.0",
        "drupal/context": "^4.0@beta",
        "drupal/core": "^8.7.0",
        "drupal/csv_serialization": "^1.4",
        "drupal/ctools": "^3.2",
        "drupal/delete_all": "^1.0",
        "drupal/devel": "^2.0",
        "drupal/draggableviews": "^1.2",
        "drupal/dropzonejs": "^2.0@alpha",
        "drupal/ds": "3.x-dev",
        "drupal/entity_clone": "^1.0@beta",
        "drupal/entity_print": "^2.1",
        "drupal/entity_update": "^1.2@RC",
        "drupal/entity_usage": "^2.0@alpha",
        "drupal/features": "^3.8",
        "drupal/file_mdm": "^1.1",
        "drupal/form_options_attributes": "^1.0",
        "drupal/geocoder": "^2.0",
        "drupal/geofield_map": "^2.23",
        "drupal/google_analytics": "^3.0",
        "drupal/google_tag": "^1.1",
        "drupal/honeypot": "^1.29",
        "drupal/htmlmail": "^3.0@alpha",
        "drupal/imagemagick": "^2.4",
        "drupal/imagick": "^1.2",
        "drupal/imce": "^1.7",
        "drupal/inline_entity_form": "^1.0@RC",
        "drupal/languageicons": "^1.0@beta",
        "drupal/layout_builder_at": "^2.8",
        "drupal/layout_builder_modal": "^1.0@alpha",
        "drupal/layout_builder_restrictions": "^2.2",
        "drupal/media_entity": "^2.0",
        "drupal/media_entity_browser": "2.x-dev",
        "drupal/media_entity_generic": "^1.0@alpha",
        "drupal/media_entity_image_exif": "1.x-dev",
        "drupal/media_entity_video": "^2.0@alpha",
        "drupal/menu_export": "^1.2",
        "drupal/menu_per_role": "^1.0",
        "drupal/metatag": "^1.8",
        "drupal/migrate_plus": "^4.1",
        "drupal/migrate_source_csv": "^2.2",
        "drupal/migrate_tools": "^4.1",
        "drupal/panelbutton": "^1.2",
        "drupal/paragraphs": "^1.5",
        "drupal/path_redirect_import": "^1.0@beta",
        "drupal/pathauto": "^1.3",
        "drupal/permissions_by_term": "^2.10",
        "drupal/recaptcha": "^2.4",
        "drupal/redirect": "^1.3",
        "drupal/redis": "^1.1",
        "drupal/rename_admin_paths": "^1.1",
        "drupal/restrict_ip": "^1.3",
        "drupal/search_api": "^1.12",
        "drupal/search_api_autocomplete": "^1.2",
        "drupal/search_api_page": "^1.0@alpha",
        "drupal/slick": "^2.0@beta",
        "drupal/slick_media": "^2.0@alpha",
        "drupal/slick_paragraphs": "^2.0",
        "drupal/smtp": "^1.0@beta",
        "drupal/stage_file_proxy": "^1.0@alpha",
        "drupal/superfish": "^1.3",
        "drupal/taxonomy_menu": "^3.4",
        "drupal/tmgmt": "^1.7",
        "drupal/twig_tweak": "^2.1",
        "drupal/views_accordion": "^1.2",
        "drupal/views_block_area": "^1.0@beta",
        "drupal/views_bulk_operations": "^2.5",
        "drupal/views_data_export": "^1.0@beta",
        "drupal/webform": "5.1",
        "drupal/weight": "^3.1",
        "drush/drush": "^9.2",
        "league/iso3166": "^2.1",
        "solarium/solarium": "3.8",
        "wikimedia/composer-merge-plugin": "^1.4"
    },
    "require-dev": {
        "webflo/drupal-core-require-dev": "^8.7.0"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "preferred-install": "dist",
        "autoloader-suffix": "Drupal8",
        "sort-packages": true
    },
    "conflict": {
      "doctrine/common": ">2.8"
    },
    "extra": {
        "_readme": [
            "By default Drupal loads the autoloader from ./vendor/autoload.php.",
            "To change the autoloader you can edit ./autoload.php.",
            "This file specifies the packages.drupal.org repository.",
            "You can read more about this composer repository at:",
            "https://www.drupal.org/node/2718229"
        ],
        "installer-paths": {
            "core": ["type:drupal-core"],
            "modules/contrib/{$name}": ["type:drupal-module"],
            "profiles/contrib/{$name}": ["type:drupal-profile"],
            "themes/contrib/{$name}": ["type:drupal-theme"],
            "drush/contrib/{$name}": ["type:drupal-drush"],
            "modules/custom/{$name}": ["type:drupal-custom-module"],
            "themes/custom/{$name}": ["type:drupal-custom-theme"]
        },
        "patches": {
            "drupal/core": {
                "Compatibility with JSON:API": "https://www.drupal.org/files/issues/2018-09-20/2942975-24.patch",
                "Layout builder revisions": "https://www.drupal.org/files/issues/2019-06-06/3033516-8.drupal.Revision-UI-on-Layout-Builder-does-not-function-correctly.patch",
                "Error: Call to a member function getLabel() after enable layout_builder": "https://www.drupal.org/files/issues/2018-07-16/2985882-entityfield-2.patch",
                "media_bundle shim": "patches/295028764_media-bundle-shim.patch"
            },
            "drupal/dropzonejs": {
                "The 'media_bundle' entity type does not exist.": "https://www.drupal.org/files/issues/2019-04-25/2820183-19.patch"
            },
            "drupal/paragraphs": {
                "Paragraphs Translation": "https://www.drupal.org/files/issues/2018-12-14/experimental-widget-asymetric-translation-2904705-47.patch"
            },
            "drupal/entity_reference_revisions": {
                "Fixes broken revisioning on paragraph updates": "https://www.drupal.org/files/issues/2019-01-29/3025709-3.patch"
            },
            "drupal/permissions_by_term": {
                "Use custom 403 destination set by admin form": "https://www.drupal.org/files/issues/2018-11-27/3009470-403-url-settings-ignored-10.patch"
            }
        }
    },
    "autoload": {
        "psr-4": {
            "Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer"
        }
    },
    "scripts": {
        "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump",
        "post-autoload-dump": "Drupal\\Core\\Composer\\Composer::ensureHtaccess",
        "post-package-install": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup",
        "post-package-update": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup",
        "drupal-phpunit-upgrade-check": "Drupal\\Core\\Composer\\Composer::upgradePHPUnit",
        "drupal-phpunit-upgrade": "@composer update phpunit/phpunit --with-dependencies --no-progress",
        "phpcs": "phpcs --standard=core/phpcs.xml.dist --runtime-set installed_paths $($COMPOSER_BINARY config vendor-dir)/drupal/coder/coder_sniffer --",
        "phpcbf": "phpcbf --standard=core/phpcs.xml.dist --runtime-set installed_paths $($COMPOSER_BINARY config vendor-dir)/drupal/coder/coder_sniffer --"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        }
    ]
}

```

# Answer
> 2 votes
The problem is probably caused because one of the core patches that you are trying to apply doesn't exist or couldn't be downloaded.

I have tested with your `composer.json` on a clean Drupal 8 install. When running `composer update` I get the following error:

> Could not apply patch! Skipping. The error was: `The "patches/295028764_media-bundle-shim.patch" file could not be downloaded: failed to open stream: No such file or directory.`

I figured that the `media-bundle-shim.patch` patch is no longer available, so I removed it from `composer.json`. After that everything worked fine and it stopped re-applying the core patches every time.

So all you have to do is to remove the patch from `composer.json`, or replace it with a new one that exists:

```
"drupal/core": {
  "Compatibility with JSON:API": "https://www.drupal.org/files/issues/2018-09-20/2942975-24.patch",
  "Layout builder revisions": "https://www.drupal.org/files/issues/2019-06-06/3033516-8.drupal.Revision-UI-on-Layout-Builder-does-not-function-correctly.patch",
  /* Remove the last comma from this line. */ "Error: Call to a member function getLabel() after enable layout_builder": "https://www.drupal.org/files/issues/2018-07-16/2985882-entityfield-2.patch",
  /* Remove this line. */"media_bundle shim": "patches/295028764_media-bundle-shim.patch"
},

```

**UPDATE:** The `media_bundle` patch could not be applyed for me, because it is a local patch.

I thave two suggestions to why it keeps re-applying the patches:

1. `lando` causes the issue.
2. The issue is caused because the local patch is not applied properly.

Since you mention that the issue was there prior to adding the local patch, it's unlikely that it's because the local patch is not being applied properly. I think the problem is lando, since your `composer.json` file works fine on a clean Drupal install using only Drupal and composer.

I don't know if it is possible to run `composer require` without lando on your site, but if it's possible you can test if lando is the problem by running `composer require` without lando.

If that doesn't work, try to remove the local patch to se if the problem persists. Local patch problems.

Hope this helps you debug further.

# Answer
> 1 votes
I think you may miss 2 `"extra"` settings in your `composer.json`:

```
"enable-patching": true,
"patchLevel": {
    "drupal/core": "-p2"
},

```

**Explanation:**

From the composer-patches documentation:

> If you want your project to accept patches from dependencies, you must have the following in your composer file: `"enable-patching": true`

Also the `drupal/core": "-p2"` avoids things ending up in core/core or core/b. See drupal-project/composer.json and Patch Drupal core without things ending up in core/core or core/b.

---
Tags: 8, composer, version-control
---


# Question
Title: Show the title of the node from an entity reference
i have a content type, which has in it a field which is of type Entity Reference. I now have created a view, where i need to aggregate on the sum of records based on this field. But my problem is that the view does not show the text that the entity reference field points to, it shows just a number. How could i make the view, show the rendered entity instead of this number?

# Answer
> 1 votes
Add a relationship in your view using the field you do the entity reference with. That will expose all of that entity's fields to be used in the view

---
Tags: 7, views
---


# Question
Title: When should I use the Url::fromRoute method instead of "new Url"
I'm finding that these two PHP snippets yield the same result:

```
$arr['query']['confirm'] = 'y';
$text = t('Click here.');
$url = new Url('my_route.import', [], $arr); // Three arguments.
$link = Link::fromTextAndUrl($text, $url)->toString();

```

and

```
$arr['confirm'] = 'y'; // No "query" key.
$text = t('Click here.');
$url = Url::fromRoute('my_route.import', $arr); // Two arguments.
$link = Link::fromTextAndUrl($text, $url)->toString();

```

Is there any reason to prefer one approach over the other? Which is the more typical approach? Is there some general PHP rule of thumb that might apply, such as... always use a method on the class instead of instantiating an object with "new" whenever possible?

# Answer
> 3 votes
From the documentation for the Url class:

> In most cases, use Url::fromRoute() or Url::fromUri() rather than constructing Url objects directly in order to avoid ambiguity and make your code more self-documenting.

So, generating a new **Url** object from a static method is preferred.

---
Tags: uri
---


# Question
Title: Override a node template suggestion with template in custom module
We have a content type that is added to the drupal system Programmatically when we install one of our custom modules. Essentially the module handle incoming property data from a 3rd party and creates a node entity for each property.

The content type created is named `properties` and as such its template suggestion shown in Twig debugging is `node--properties--full.html.twig`, see below:

I am creating a second custom module called `lrg_property_display` and my intention is that this module will handle all the rendering related functionality as I want to keep the API import related functionality separate from the rendering. My module structure is shown below:

I have created my module and followed a couple sites suggestions that I simply create a template file in my module and in the .module file implement the `HOOK_THEME` method, which I have done as shown:

```
function lrg_property_display_theme($existing, $type, $theme, $path)
{
    $theme['node__property_display__full'] = [
        'template' => 'node--property-display--full',
        'base hook' => 'node'
    ];

    return $theme;
}

```

Clearing cache and refreshing the page though is showing that the theme is not been applied.

Where am I going wrong with this please? I basically need the `node--property-display--full.html.twig` template within the module to be used whenever a node of the type `Properties` is viewed.

**UPDATE**

I added the following code to my theme file (Theme name is `white_label`) which seemed to produce an error which suggests it 'almost' works, albiet I'd prefer not having to do a suggestion in the theme but want it in the module. I can live with it though if this works for the short/medium term:

```
function white_label_theme($existing, $type, $theme, $path)
{
    return array(
        'node__properties__full' => array(
            'render element' => 'elements',
            'template' => 'node--property-display--full',
            'base hook' => 'node',
            'path' => drupal_get_path('module', 'lrg_property_display') . '/templates',
        )
    );
}

```

This then looks for the template `node--property-display--full.html.twig` but its looking in the main theme directory not in the module, even with the path specification.

The error returned was:

```
he website encountered an unexpected error. Please try again later.Twig_Error_Loader: Template "themes/custom/white_label/templates/nodes/node--property-display--full.html.twig" is not defined.

```

Reference image for comment in @Leigh's answer

# Answer
> 4 votes
Isn't your array key wrong? It should be:

```
 $theme['node__property__full'] = [
    'template' => 'node--property-display--full',
    'base hook' => 'node'
];

```

If you're wanting to target the "full" display and your content type has a machine name of "property"

I'm doing something similar targetting a node of type "news" and display node "teaser":

```
function mymodule_theme($existing, $type, $theme, $path) {
  return [
   'node__news__teaser' => [
      'template' => 'node--news--teaser',
      'base hook' => 'node'
    ],
  ];
}

```

And my folder structure is:

/modules/custom/mymodule/templates/node--news--teaser.html.twig

# Answer
> 1 votes
This should help

```
function MYMODULE_theme_registry_alter(&$theme_registry) {

        $extension   = '.html.twig';
        $module_path = drupal_get_path('module', 'MYMODULE');
        $files       = file_scan_directory($module_path . '/templates', '/' . preg_quote($extension) . '$/');

        $fs = \Drupal::service('file_system');

        foreach ($files as $file) {
          $template = $fs->basename($file->filename, $extension);
          $theme    = str_replace('-', '_', $template);
          $__expt = explode('__', $theme, 2);
          $base_theme = empty($__expt[0]) ? null : $__expt[0];
          $specific = empty($__expt[1]) ? null : $__expt[1];
          if (!empty($specific) && isset($theme_registry[$base_theme])) {
            $theme_info = array(
              'template'   => $template,
              'path'       => $fs->dirname($file->uri),
              'render element'  => $theme_registry[$base_theme]['render element'],
              'base hook'  => $base_theme,
              'type'       => 'module',
              'theme path' => $module_path,
              'preprocess functions' => $theme_registry[$base_theme]['preprocess functions'],
            );

            $theme_registry[$theme] = $theme_info;
          }
        }
}

```

# Answer
> 0 votes
Have you enabled the theme suggestion?

**MYMODULE.module**:

```
// This first function here.

/**
 ** Implements hook_theme_suggestions_hook().
 **/
function lrg_property_display_theme_suggestions_node(array $variables) {
  return [
    'node__properties'
  ];
}

/**
 ** Implements hook_theme().
 **/
function lrg_property_display_theme($existing, $type, $theme, $path) {
  return [
    'node__properties' => [
      'template' => 'node--properties',
      'base hook' => 'node',
    ],
  ];
}

```

You can also declare a specific template file:

```
function hook_theme_suggestions_hook(array $variables) {
  return [
    'my_very_specific_template'
  ];
}

function hook_theme($existing, $type, $theme, $path) {
  return [
    'my_very_specific_template' => [
      'base hook' => 'node',
    ],
  ];
}

```

---
Tags: 8, theming
---


# Question
Title: Can't run drush from within website folder configured with IIS on Windows Server 2012
I am trying to setup Drupal 8 on Windows Server 2012 on IIS. I have installed PHP7.0 and Composer. Using Composer I then installed Drush globally using `composer global require drush/drush:8.*`. Drush was installed at `C:\Users\Myusername\AppData\Roaming\Composer\vendor\drush\drush`. I have set the Path variable for the user 'Myusername' to include `C:\Users\Myusername\AppData\Roaming\Composer\vendor\bin`.

The problem I have is that if I `cd` into the website folder as configured in IIS, and then run `drush version`, I receive the following error:

```
"C:\\inetpub\\wwwroot\\mysite\\vendor\\bin\\drush.php.bat" is not recognized as an internal or external command, operable program or batch file.

```

If I run the same command outside of the site folder as configured in IIS, then `drush version` executes successfully.

It seems that when run from within the web site folder it is trying to run drush from within the website project instead of using the globally installed drush.

Any suggestions on how to get Drush running for the site?

**Updated**:

After some experimenting it seems that when I run Drush it looks for the closest `vendor\bin` directory. If it is not in the current directory, it works its way up the parent directories until it finds it. If it can’t find it, it uses the globally set one. For example, if I run drush from either `C:\\inetpub`, `C:\\inetpub\\wwwroot` then will get this error:

\`"C:\inetpub\vendor\bin\drush.php.bat" is not recognized as an internal or external command, operable program or batch file.

If I run `drush version` from outsite of `C:\\inetpub` directory then it works correctly.

# Answer
Drush Launcher solved the issue for me.

Step 1 Download drush.phar and put it in project root folder

Step 2 Create drush.bat file in project root folder and put following content (it will run phar in window)

```
@echo off
php "%~dp0\drush.phar" %*

```

Now it will use local drush.
> 2 votes

# Answer
Try to copy `C:\xampp\htdocs\drupalDrush\vendor\bin\drush.bat` -\> `C:\xampp\htdocs\drupalDrush\vendor\bin\drush.php.bat`
> 2 votes

# Answer
Your global drush version was not compatible with the site specific drush version or the site specific version of drush was broken. As you indicated, when you run `drush version` from outside your site the command works but not when the site specific version takes priority.

In my case the global drush version was drush 8.1 and the site specific version was 9.0 beta. To fix the problem I removed the site specific 9.0 beta version and relied on the global version.
> 0 votes

---
Tags: 8, drush, composer
---


title: Nonexistent route breaks the site

text:
# Question
Title: Nonexistent route breaks the site
I'm new to Drupal and have been using a few modules to build a site. I've installed link icon and have used it to make a block type and a block which I have then deleted. Then an error like this showed up: `Symfony\Component\Routing\Exception\RouteNotFoundException: Route "linkicon.settings" does not exist. in Drupal\Core\Routing\RouteProvider->getRouteByName() (line 208 of core\lib\Drupal\Core\Routing\RouteProvider.php).`

Drupal\Core\Routing\UrlGenerator->getPathFromRoute('linkicon.settings', Array) (Line: 68)
Drupal\Core\Render\MetadataBubblingUrlGenerator->getPathFromRoute('linkicon.settings', Array) (Line: 791)
Drupal\Core\Url->getInternalPath() (Line: 135)
Drupal\Core\Utility\LinkGenerator->generate('Linkicon', Object) (Line: 95)
Drupal\Core\Render\Element\Link::preRenderLink(Array)
call_user_func_array(Array, Array) (Line: 100)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. Support for this callback implementation is deprecated in 8.8.0 and will be removed in Drupal 9.0.0. See https://www.drupal.org/node/2966725', 'silenced_deprecation', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 781)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 372)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 117)
__TwigTemplate_a4627177b33000f8b0aa8b107c9f0ef6178614c89b6a7100401a3236a6320938->getmenu_links(Array, Object, 1) (Line: 124)
__TwigTemplate_a4627177b33000f8b0aa8b107c9f0ef6178614c89b6a7100401a3236a6320938->getmenu_links(Array, Object, 0) (Line: 60)
__TwigTemplate_a4627177b33000f8b0aa8b107c9f0ef6178614c89b6a7100401a3236a6320938->doDisplay(Array, Array) (Line: 455)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 422)
Twig\Template->display(Array) (Line: 434)
Twig\Template->render(Array) (Line: 64)
twig_render_template('core/themes/stable/templates/navigation/menu--toolbar.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('menu__toolbar', Array) (Line: 431)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 200)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 156)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 157)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 115)
Drupal\toolbar\Controller\ToolbarController::preRenderGetRenderedSubtrees(Array)
call_user_func_array(Array, Array) (Line: 100)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. Support for this callback implementation is deprecated in 8.8.0 and will be removed in Drupal 9.0.0. See https://www.drupal.org/node/2966725', 'silenced_deprecation', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 781)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 372)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 200)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 156)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 157)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 299)
toolbar_get_rendered_subtrees() (Line: 324)
_toolbar_get_subtrees_hash() (Line: 167)
toolbar_toolbar()
call_user_func_array('toolbar_toolbar', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('toolbar') (Line: 81)
Drupal\toolbar\Element\Toolbar::preRenderToolbar(Array)
call_user_func_array(Array, Array) (Line: 100)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. Support for this callback implementation is deprecated in 8.8.0 and will be removed in Drupal 9.0.0. See https://www.drupal.org/node/2966725', 'silenced_deprecation', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 781)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 372)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 444)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 96)
__TwigTemplate_36b55b2cdf160af87a66085795ed11cacb844fa1a6a61aab58232c38ca9b0c0e->doDisplay(Array, Array) (Line: 455)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 422)
Twig\Template->display(Array) (Line: 434)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/contrib/news_zymphonies_theme/templates/layout/html.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('html', Array) (Line: 431)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 148)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 694)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)```

# Answer
> 0 votes
The route exists in the module code:

https://git.drupalcode.org/project/linkicon/-/blob/8.x-1.x/linkicon.routing.yml

Check to make sure you have that file on your system. Clear your registry. If that doesn't work, then you should reinstall the module.

---
Tags: 8
---


# Question
Title: Large amount of entity revision cleaning leads to connection abortion
I am trying to remove revisions from each entity type which has the revision feature via drush command. The amount of entities are quite a lot: around 10K nodes, 2k paragraphs.

On localhost everything is fine. But in the cloud the drush\_print($log) successfully runs and the following error appears:

```
 [warning] PDO::beginTransaction(): MySQL server has gone away Connection.php:1165
 [warning] PDO::beginTransaction(): Error reading result set's header Connection.php:1165

In Connection.php line 1165:

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

```

The two environments are close to identical. Any suggestions where could I start to investigate?

# Answer
> 0 votes
It turned out what the real issue was. I didn't mention (thought it's not important) that this was actually a Drush command pointing to another multi site.

The actions took "too long" on the other site and by the time it returned with success, the default Mysql connection was timed out and couldn't write to the database anymore. (even tho the corresponding Mysql timeout settings were way higher than the actual amount of time that was spent on the other site)

We solved with with

```
$process = proc_open($command, [STDIN, STDOUT, STDERR], $pipes);
if (!is_resource($process)) {
  throw new \InvalidArgumentException("Could not execute `{$command}`.");
}
while (($status = proc_get_status($process)) && ($status['running'])) {
  $this->entityStorage->getQuery()->count()->execute();
  sleep(5);
}
proc_close($process);

```

---
Tags: 8, entities
---


# Question
Title: Can "Demonstrate block regions" use a specific template?
The theme .info file look like this.

```
name = xxx
description = xxxxx
core = 7.x
engine = phptemplate
stylesheets[all][] = css/css.css
regions[banner] = Banner
regions[header] = Header
regions[leftcolumn] = Left Column
regions[content] = Content Column
regions[rightcolumn] = Right Column
regions[footer] = Footer

```

The page.tpl.php template contains these regions: *banner*, *header*, *left column*, *content column*, and *footer*.

The page--front.tpl.php template is for the front page and contains these regions: *banner*, *header*, *left column*, *content column*, *right column*, and *footer*.

The website works perfectly. It shows content as it should do, but when I click on the *Demonstrate block regions* link, it shows the page.tpl.php template. (I have checked that with devel\_themer.) I can see the *banner*, *header*, *left column*, *content column*, and *footer* regions; the *right column* region is missing.

I wish it was the page--front.tpl.php template to be used, instead of page.tpl.php, so I could see all the regions.

Is it possible to change the template used to show the regions to page--front.tpl.php?

# Answer
> 0 votes
In order for a region to show up on the demonstration block, you need to define it in your theme's .info file and print the region in page.tpl.php (or the overrided version). The following could be the issue

1. Cache is not cleared (i.e. drush cc theme-registry if you are using drush)
2. Theme's .info file has not listed the new region
3. Page template is not overrided properly
4. The region is not printed properly in .tpl.php file

I would say, have a look into guide on how to override a template file prpperly here https://www.drupal.org/node/1089656 and https://www.drupal.org/node/223440#custom-suggestions.

If you would like a region to ***NOT*** show up on the front page, you can simply do not supply content to it and Drupal will not render it.

If you would like to add an extra region, then google for some tutorials on how to create custom regions.

Install Devel related modules.

devel\_themer module, make it very easy to do themeing in Drupal, specially if you are new.

If you have devel\_themer installed and enabled, then you can click on the page and see which template file is being used to render the page. You can click on regions, blocks and elements and it will give you details on how it is rendered and which template/function being used.

Hope this general answer help you.

# Answer
> 0 votes
Some base themes like Omega provide an option to always show regions. If you're not using one of these you can always create one block per region with some lorem ipsum content for example.

# Answer
> 0 votes
Basically what you're asking is: "Is it possible to 'demonstrate block regions' using a specific theme template that you've created?"

For this, I think you can use `hook_preprocess_page()` (to edit the page before it gets displayed), and then provide a 'theme\_hook\_suggestion' for your template. So Drupal would see the suggestion and use your template for the 'admin/structure/block/demo/\[theme\]' path.

The accepted answer on the "Change templates based on path alias" question describes how this works nicely.

# Answer
> 0 votes
Drupal takes specific template file for the page if present. page--front.tpl.php will be used only for the home page (or front page). If you want a specific template for your page with all the regions as in page--front.tpl.php, copy front page template and rename it to page--{page-path}.tpl.php. Clear the cache. Now the page you want will display all the regions.

---
Tags: theming
---


# Question
Title: How to set a new value in a paragraph field on submit?
In an edit form for a content with paragraphs, I set errors on the paragraph specific field with this particular syntax:

```

$form_state->setErrorByName('field_paragraphs][' . $key . '][subform][field_sharepoint_file_url][' . $key2, t('Invalid URL'));

```

*(see the missing square brackets at the beginning and at the end, solution found here)*

**This** is working well.

**However**, I also need to register a different value on this field, and I can't seem to find the right way to do so.

I've tried to do this in a submit callback:

```
$form_state->setValue('field_sharepoint_file_url', $data->alias);

```

Or by retrieving the paragraph object in the hook\_ENTITY\_TYPE\_presave:

```
/*
 * Implements hook_ENTITY_TYPE_presave()
 */
function mymodule_node_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getType() == 'page') {
    $result = $entity->get('field_paragraphs')->referencedEntities();
    if (!empty($result)) {
      foreach ($result as $paragraph) {
        /* @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
        if($paragraph->getType() == 'sharepoint_file') {
          /* @var \Drupal\Core\Field\FieldItemList $url */
          $urls = $paragraph->get('field_sharepoint_file_url');
          /* @var \Drupal\Core\Field\Plugin\Field\FieldType\StringItem $url */
          foreach ($urls as $url) {
            // [...]
            $paragraph->set('field_sharepoint_file_url', $data->alias);
          }
        }
        $paragraph->save();
      }
    }
  }
}

```

But the new value is never registered in database.

Thanks for any tip on this.

# Answer
> 1 votes
I'd imagine the first didn't work because your custom submit handler is run after the form default submit handler so it's too late (You didn't provide this code so can't be certain). You'd need to make sure your submit handler is run before any other submit handlers. To do that in the array of submit handlers your needs to be first in the array

Similarly for the 2nd option you've tried, you're in hook\_presave so you're changing things but then when the normal entity save function happens after this any changes you made are overwritten

---
Tags: 8, forms, paragraphs
---


# Question
Title: View page not filtering content according to its language
I used devel to generate dummy content for a content type named recipe, and at the moment I have 10 recipes. 5 in English and 5 in Portuguese. I create a view(page view) that shows all the recipes when the user goes to /recipes, and select it to render only the recipes in English.

When I visit the url: domainname/recipes I see all the recipes including the ones in Portuguese.

Below is my configuration:

How do I filter out the recipes that are not in English?

UPDATED: How can I add a menu to that same view?

# Answer
Click "Add" on "Filter Criteria" on the left column. Then add a filter called `Content: Translation language` and set it to `Content language selected for page`
> 2 votes

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


# Question
Title: How to re-publish nodes after unpublishing with hook_cron?
Good morning,

I'm running some tests with hook\_cron in Drupal 8. My goal is to unpublish nodes of a specific content type ('event'), and once I enabled my module, I was able to accomplish this. However, after setting $node-\>setPublished to 'true,' I was unable to accomplish publishing said nodes again after running cron, running Drush CR, and restarting Apache.

Anyone know of any good hooks to resolve this?

```
function scheduler_publish_cron() {
  $nids = \Drupal::entityQuery("node")
    ->condition('type', 'event')
    ->execute();
$storage_handler = \Drupal::entityTypeManager()->getStorage("node");
$nodes = $storage_handler->loadMultiple($nids);
foreach ($nodes as $node) {
// Unpublish nodes
// $node->setPublished(false);
 // Publish nodes
$node->setPublished(true);
    $node->save();
  }
}

```

# Answer
Try to disable access checking in the second run, because after unpublishing the node you might no longer have access to them (depending on the user account the code runs with):

```
$nids = \Drupal::entityQuery('node')
  ->condition('type', 'event')
  ->accessCheck(FALSE)
  ->execute();

```
> 1 votes

---
Tags: cron
---