# Question
Title: Content Encoding Error - The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression
Drupal 7.56, PHP 5, PHP-FPM, multi-site Ubuntu 14.04.1 LTS server

EDIT: it's *NOT* only when I'm logged in to my site do I get this error:

> Content Encoding Error
>
> The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.

It happens 1/3 of the time I try to load a page. If I click "try again" twice or refresh the page twice it will load. I have followed these steps from the accepted answer on Content encoding error after enabling cache, aggregation and compression

```
$conf = array(
'cache' => '0',
'preprocess_css' => '0',
'preprocess_js' => '0',
'block_cache' => '0',
'page_compression' => '0',
);

```

I have also checked php.ini, per other resolutions, and error reporting is off.

I checked for PHP error reporting per https://www.drupaleasy.com/quicktips/browser-fail-unsupported-form-compression-related-php-notice and https://www.drupal.org/node/373101 and when I ran the wget command there was no PHP error up top.

The behavior does not change at all after clearing my browser's cache.

FWIW I've tested by disabling every module I could (I'm fighting AddThis right now). I also had to increase the memory limit from 128M to 1000M because I kept getting 500 errors too. See my note on 500 Internal Server Error after logging in

I also had to update a theme.inc file based on this error:

> /e modifier is no longer supported, use preg\_replace\_callback instead in…

as seen at https://stackoverflow.com/questions/38067166/replace-preg-replace-with-preg-replace-callback-still-failing?noredirect=1&lq=1

UPDATE: the 500 error seems to have been fixed with a permissions reset. I put the memory\_limit back to 128M after the permissions reset and no more 500 errors. I got one from Chrome at first but maybe it was a cached thing? Now no more.

Also, per Anson W Han in the comments, I have tried reverting my change to the theme file with no success. And the theme is supposed to be best with PHP 5.2-5.6 and I am running PHP 5.5.9

UPDATE: the 500 error is NOT resolved after all

# Answer
Looking in the log file there were some FastCGI references, but in ISPConfig I had PHP-FPM selected. Once it was switched to MOD-PHP all of my problems disappeared. I can't even.
> 0 votes

---
Tags: 7
---


# Question
Title: How to render entity id in views when showing entities not fields
How can I include the entity id in views output when rendering entities? I have a jQuery script that further processes each entity, but for doing so, I need to know the entity id. So I need to include it somehow in the rendered output. How can this be done?

# Answer
> 0 votes
In case of field display:

* an field "node\_id" that takes node id value ( you can hide the output ).
* an field that can use "Rewrite the output of this field" with an output like: `<div class="entity_{{ nid }}">something</div>`

In case of entity display:

* override node--yourcontenttype–teaser.html.twig, and replace `{{ content }}` with: `<div class="entity_{{ entity.id.value }}">{{ content }}</div>`

Then you can use jquery to handle the div with respective class or id.

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


# Question
Title: How do you make entity fields appear in Rules when converting a Webform submission to node?
Steps to reproduce this use case:

1. \[Rule event\] Submit data on a specific Webform (new submission)
2. \[Rule action\] Create content node by type
3. \[Rule condition\] Use 'content is of type' condition
4. \[Rule action\] Access Webform submission data to set node content fields

How can 3 & 4 above be executed in this order and allow for access to both the created entity and webform submission? i.e. - by passing arguments or otherwise.

Related articles which get some of the way there but did not answer my question entirely:

# Answer
> 2 votes
Assuming you are using Webform Rules, you should move 3 and 4 to a Rules Component, but unfortunately Webform Rules does not allow to expose webform data (transfer submission between rules and components) without the patch from here https://www.drupal.org/node/2020149 Without it the data is only available using tokens, and you can not even set the webform data to the variable.

There is another solution, you can extract the Webform SID (\[data:sid\]) and send it to your Component together with newly created entity and webform itself, then inside your component you can convert received \[data:sid\] to integer and fetch the submission (Rule Action: Fetch Webform Submissions) and access it using PHP. You will also be able to use Entity:has field inside your component to access all the fields from your newly created entity.

Something like that (component):

The component parameters has:

# Answer
> 1 votes
I assume your issue is to keep the order of the steps and run a Rule Condition (#3) after a Rule action (#2) within the same rule. @No Sssweat's solution is a possible way to do this. In the past I've use Conditional Rules to create conditions within the action portion of the Rules interface. This has allowed me to bring entities to scope without the need of creating additional Rules Components.

# Answer
> 0 votes
To achieve your goal (= "... make entity fields appear in Rules when converting a Webform submission to node ...", as in your question title), you can use a technique similar to what is described in my answer to "How to do a data comparison to submitted webform data when using the Rules module?". For short:

* Add an extra Rules Action to `Add a variable` (for each of the Webform components to transpose the information across, with a value assigned to it equal to your `[data:ComponentName-value-raw]` (and with a data type which equals the data type of your Webform component).
* In your subsequent Rules Actions you can refer to the value of these variables you just added (that's the clue!).

# Demo

### Webform components

Assume a webform with `form_id=191` and with these Webform Components:

* Label = Title, Machine name = `demoform_title`, Data type = Textfield.
* Label = Text, Machine name = `demoform_text`, Data type = Textarea.
* Label = Number, Machine name = `demoform_number`, Data type = Number.
* Label = Option, Machine name = `demoform_option`, Data type = Select options (single value).

### Article content type

Assume an Article content type with these fields:

* Label = Title, Machine name = `title`, Field type = Node module element.
* Label = Body, Machine name = `body`, Field type = Long text and summary.
* Label = Free Format Nr, Machine name = `field_free_format_nr`, Field type = Integer.
* Label = OptionList, Machine name = `field_optionlist`, Field type = List(text).

### Custom Rule

Here is a custom rule (in Rules export format), which will create a new node (of type `Article`), and which will use the data included in the above mentioned Webform components:

```
{ "rules_create_a_node_from_webform_data" : {
    "LABEL" : "Create a node from webform data",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "webform_rules", "rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "IF" : [
      { "webform_has_id" : {
          "form_id" : [ "form_id" ],
          "selected_webform" : { "value" : { "webform-client-form-191" : "webform-client-form-191" } }
        }
      }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "The webform submitted contains these fields:\r\n\u003C\/ul\u003E\r\n\u003Cli\u003Ethe field labeled \u0022[data:demoform_title-title]\u0022 which has value \u0022[data:demoform_title-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_text-title]\u0022 which has value \u0022[data:demoform_text-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_number-title]\u0022 which has value \u0022[data:demoform_number-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_option-title]\u0022 which has value \u0022[data:demoform_option-value-raw]\u0022.\u003C\/li\u003E\r\n\u003C\/ul\u003E" } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_text-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_text" : "Form variable text" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_number-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_number_text" : "Form variable number text" } }
        }
      },
      { "data_convert" : {
          "USING" : { "type" : "integer", "value" : [ "var-demoform-number-text" ] },
          "PROVIDE" : { "conversion_result" : { "var_demoformvar_number" : "Form variable number" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_option-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_option" : " Form variable option" } }
        }
      },
      { "entity_create" : {
          "USING" : {
            "type" : "node",
            "param_type" : "article",
            "param_title" : "[data:demoform_title-value-raw]",
            "param_author" : [ "user" ]
          },
          "PROVIDE" : { "entity_created" : { "article_created" : "Created article" } }
        }
      },
      { "data_set" : {
          "data" : [ "article-created:body:value" ],
          "value" : [ "var-demoform-text" ]
        }
      },
      { "data_set" : {
          "data" : [ "article-created:field-free-format-nr" ],
          "value" : [ "var-demoformvar-number" ]
        }
      },
      { "data_set" : {
          "data" : [ "article-created:field-optionlist" ],
          "value" : [ "var-demoform-option" ]
        }
      },
      { "data_set" : { "data" : [ "article-created:comment" ], "value" : "0" } },
      { "entity_save" : { "data" : [ "article-created" ], "immediate" : "1" } },
      { "drupal_message" : { "message" : "A new article got created, with nid=[article-created:nid] and url=[article-created:url]" } }
    ]
  }
}

```

Some more details about the Rules Actions that were added:

* **`Show a message on the site`**: This is just for debugging/demo purposes (remove it you don't want/need it anymore). Here is a sample message that gets displayed after submitting a webform:

> The webform submitted contains these fields:
>
> + the field labeled "Title" which has value "Some interesting title of my webform".
>     + the field labeled "Text" which has value "Just some text, with some additional text and yet another line and another one".
>     + the field labeled "Number" which has value "842316".
>     + the field labeled "Option" which has value "A".
* **`Add a variable`** (twice): To make the value of the Webform components `demoform_number` and `demoform_option` available in subsequent Rules Actions. Note that for `demoform_number` an additional Rules Action **`Convert data type`** is needed to get it to work.
* **`Set a data value`** (3 times): To populate the node's body and the 2 node fields, using the variables created in a preceeding Rules Action.
* **`Set a data value`**: To set "Comments closed" for the node being created (this is an optional Rules Action, just an illustration of other things you can do with such node being created).
* **`Save entity`**: To actually save the node.
* **`Show a message on the site`**: This is just for debugging/demo purposes (remove it you don't want/need it anymore). Here is a sample message that gets displayed after submitting a webform:

> A new article got created, with nid=123 and url=http://www.example.com/node/123

### Final result

After submitting the webform with data as in the sample above, a new article (with node id = `123`) got created, and with these details about that node:

* **Title**: Some interesting title of my webform
* **Body**:

> Just some text,
>
> with some additional text
>
> and yet another line
>
> and another one
* **Free Format Nr**: 842316
* **OptionList**: Advanced (the label corresponding to key-value "`A`")

### Notes

* The custom rule in this answer does not require the (dangerous) PHP filter to be enabled (as opposed to what is mentioned in the currently *accepted* answer). Nor does it require the patch mentioned in the currently *accepted* answer.
* This answer should address your "Step 4" (in your question). While it seems to me that you don't need "Step 3" (in your question). Unless you want to create multiple types of nodes, e.g. based on some value specified in any of your webform components. If that's the case, all you need to do is to further improve the set of the Rules Actions in my sample rule, by also using the Conditional Rules module.

---
Tags: 7, rules, webforms
---


# Question
Title: How do I postpone an already postponed deletion
I made a site in which users can publish content and also postpone the deletion time. Now I want the users to be able to postpone a deletion that have been already been postponed. So I want to consider the remaining time do so.

How can reach this goal?

# Answer
First an educated (wild) guess ... Since Drupal, out-of-the-box, does not come with some "postpone" facility, I'm going to assume that you implemented that by using the Rules Scheduler to schedule the execution of a Rules Component, which does nothing but delete some content (node).

Have a look at my answer to the question "How can I set a reminder for a specific user to be triggered on a specific date?". Obviously, that is not the same question as yours here. But the "specific date" there appears to correspond to your "postponed date".

With that, you could just trigger a rule each time that the content is edited, and then verify the relevant data of your content to decide if you need to do either of these:

* no more need to postpone the deletion of content "later on", so just DELETE the scheduled execution of the Rule to delete content.
* (re-)schedule the execution of the Rule to delete content.

PS: from revision 1 of your question, I understand it is about D7 ...
> 0 votes

---
Tags: rules
---


# Question
Title: Why running cron tasks would hit a REST service endpoint?
I can't run cron jobs from a single module or from core anymore. Somehow Drush hits a REST service endpoint.

I have configured some service endpoints for views, but why would cron jobs hit that? I cannot explain that myself.

The error message I get from Drush is the following one.

> Services Endpoint "rest" has been setup successfully. Drush command terminated abnormally due to an unrecoverable error.

# Answer
It's impossible to answer the question directly because we'd have to speculate about the all the possible states of your Drupal installation where `rest_server_server()` is hit in a a cron context.

However, since you know where the notification message is being produced, and you can trigger it in a Drush command, what you can do is insert something like `debug_print_backtrace()` in the `rest_server_server()` function then re-run the Drush command to get an idea of what module/configuration is causing that to occur and if it's causing cron to die on you.
> 2 votes

---
Tags: 7, drush, cron
---


# Question
Title: How to import Webform configuration using the Webform configuration YAML file
I have exported the configuration of a webform 8.x in YAML format. Now I want to import the configuration file to a webform in a different website as there is no import feature in the Webform.

Any guidance on how to do this?

# Answer
There are PIs available to help import submission data but you will have to write some custom code.

Below is a very general example of using `WebformSubmissionForm::submitValues` method to import submission data.

```
// Get submission values and data.
$values = array(
  'webform_id' => 'contact',
  'entity_type' => NULL,
  'entity_id' => NULL,
  'in_draft' => FALSE,
  'uid' => '1',
  'langcode' => 'en',
  'token' => 'wmL3nKDgMh91nSTt0ZyohpfgPNITzM_xHvYl_MQQwj4',
  'uri' => '/webform/contact/api',
  'remote_addr' => '::1',
  'data' => array(
    'name' => 'Loremipsum',
    'email' => 'example@example.com',
    'subject' => 'Testing contact webform from Webform Demo Site',
    'message' => 'Please ignore this email.',
  ),
);

// Check that the webform is open.
$webform = \Drupal\webform\entity\Webform::load('contact');
$is_open = \Drupal\webform\WebformSubmissionForm::isOpen($webform);
if ($is_open === TRUE) {
  // Validate webform submission values.
  $errors = \Drupal\webform\WebformSubmissionForm::validateValues($values);

  // Submit webform submission values.
  if (empty($errors)) {
    $webform_submission = \Drupal\webform\WebformSubmissionForm::submitValues($values);
  }
}

```

If you enable the webform\_devel.module and there will be API tab displayed with every webform's 'Test' tab which will generate the need to PHP code snippet.
> 1 votes

---
Tags: webforms, 8
---


# Question
Title: How can I create a node in a PHPUnit Test without having to create the node type in PHPUnit
I have a node type already created on my site. I want to create a node with this node type in my PHP Unit test since I am using my database but I am getting errors. It seems like I may have to recreate the node type in the PHP Unit test first and then create it.

Is it possible to create a node without creating the node type in PHP Unit?

Here is the command I am running to run a PHP Unit test:

```
php ./core/scripts/run-tests.sh --verbose --php /usr/local/bin/php —-dburl mysql://drupal:drupal@mariadb/drupal --url http://nginx --class "Drupal\my_module\Tests\ExpenseTest"

```

This is the error:

```
    Status    Group      Filename          Line Function
    --------------------------------------------------------------------------------
    Fail      Completion ExpenseTest.php     64 Drupal\my_module\Tests\ExpenseTes
        The test did not complete due to a fatal error.
    Pass      Other      ExpenseTest.php     55 Drupal\my_module\Tests\ExpenseTes
        Enabled modules: node, paragraphs
    Fail      run-tests. Unknown              0 Unknown
        FATAL Drupal\my_module\Tests\ExpenseTest: test runner returned a non-zero
        error code (255).
    Fail      Fatal erro Unknown              0 Unknown
        [17-Feb-2018 17:36:34 Australia/Sydney] PHP Fatal error:  Uncaught Error:
        Call to a member function referencedEntities() on null in
        /var/www/html/web/modules/custom/my_module/src/Expense.php:116
    Fail      Fatal erro Unknown              0 Unknown
        Stack trace:
    Fail      Fatal erro Unknown              0 Unknown
        #0
        /var/www/html/web/modules/custom/my_module/src/Tests/ExpenseTest.php(65):
        Drupal\my_module\Expense->__construct(Object(Drupal\node\Entity\Node))
    Fail      Fatal erro Unknown              0 Unknown
        #1 /var/www/html/web/core/modules/simpletest/src/TestBase.php(963):
        Drupal\my_module\Tests\ExpenseTest->testValidation()
    Fail      Fatal erro Unknown              0 Unknown
        #2 /var/www/html/web/core/scripts/run-tests.sh(804):
        Drupal\simpletest\TestBase->run(Array)
    Fail      Fatal erro Unknown              0 Unknown
        #3 /var/www/html/web/core/scripts/run-tests.sh(67):
        simpletest_script_run_one_test('44', 'Drupal\\reo_expe...')
    Fail      Fatal erro Unknown              0 Unknown
        #4 {main}
    Fail      Fatal erro Unknown              0 Unknown
        thrown in /var/www/html/web/modules/custom/my_module/src/Expense.php on
        line 116
    /var/www/html/web $

```

This is my code:

```
<?php

namespace Drupal\my_module\Tests;

use Drupal\simpletest\WebTestBase;
use Drupal\node\Entity\Node;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\my_module\Expense;

/**
 * Tests views contextual links on nodes.
 *
 * @group reo_expense
 */
class ExpenseTest extends WebTestBase {

  /**
   * Node object
   *
   * @var /Drupal\node\Entity\Node
   */
  protected $node;

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['node', 'paragraphs'];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();

    $this->node = $this->createMyNode();
  }

  /**
   * Tests contextual links.
   */
  public function testValidation() {
    $expense = new Expense($this->node);
    $this->assertEqual($expense->getRegionId(), 4);
  }

  /**
   * Create Expense node.
   */
  public function createMyNode() {
    // Populate defaults array.
    $settings = [
      'title' => 'asdfasdf',
      'type' => 'expense',
      'uid' => \Drupal::currentUser()->id(),
    ];
    $node = Node::create($settings);
    return $node;
  }
}

```

# Answer
> 2 votes
When you create a node, you need to reference a bundle that already exists. In your case, you are referencing a bundle (*expense*) that is created from a custom module, but that module is not installed.

If you look at the tests for the Node module, you will notice they always install the Node module. In the test classes that expand the `NodeTestBase` class, that is done from that class. In other test classes, for example the `NodeFieldAccessTest` class (a Kernel test), that is done directly by that test class.

In your case, changing the list of modules to install to the following one would solve the issue.

```
  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['node', 'paragraphs', 'my_module'];

```

From the error messages, I take the machine name of the module creating the content type is *my\_module*. If that is not correct, replace *my\_module* with the correct machine name.

---
Tags: testing
---


# Question
Title: How to add a menu item to main menu: hook_menu() or menu_link_save()?
I just want to programmatically add some menu items to the main menu, but none of the answers I found worked. Some answers suggest using `hook_menu()`, others suggest using `menu_link_save()`. I followed what reported in Can I add a custom link to "Main Menu" via hook\_menu? but it just doesn't work. There's no new item added, neither in the UI nor in the database.

```
function mymodule_menu() {
  $items['my/path'] = array(
    'title' => 'Title',
    'page callback' => 'page_creator_function',
    'access callback' => TRUE,
    'menu_name' => 'main-menu',
    'type' => MENU_NORMAL_ITEM,
  );

  return $items;
}

```

Also I found How and where do I programmatically add a menu to the Navigation menu?. Answer #2 says that using `menu_link_save()` is the way to go, but I could not get it to work. Do I have to place the code in a certain location or a special hook?

```
$item = array(
  'link_path' => 'my_path',
  'link_title' => 'Title',
  'menu_name' => 'main-menu',
  'weight' => 0,
  'language' => 'en',
  'plid' => 0,
  'module' => 'menu',
);
menu_link_save($item);

```

Since both answers didn't work out, it seems that I am missing a crucial point. Could anyone say what's going on here?

# Answer
> 0 votes
After a hard time I figured out what hampered the execution of the above code: clearing caches isn't enough to see the results. I had to use devels menu reset (/devel/menu/reset). Using drush's `drush eval 'menu_rebuild();'` as mentioned at How do I call the menu\_rebuild function in Drupal 7? somehow does not work. I do not know why.

---
Tags: 7, hooks, navigation
---


# Question
Title: Why is a content type's node twig template being used by taxonomy term?
New to Drupal (using drupal 8) .. please bear with me.. I 've tried to find an answer, but I couldn't...

I have created a content type, say 'course' that holds info about a particular course. I have successfully created and placed a twig template, node--course.html.twig and through there I can control the layout of all dynamically created courses.

So far so good .. However, that course is linked to a simple taxonomy (entity reference) which has only two terms, say 'theoretical' and 'classical'. Say that this value is held within field\_course\_direction.

Now the problem .. When I output any course I use my node--course.html.twig and somewhere I have something like:

```
Direction: {{ content.field_course_direction }}

```

So I get the appropriate value (say 'classical') as a link, which points to a view of all courses under 'classical'.

The problem is - that page which is something like 'my-site.com/taxonomy/term/37' for me, **again uses the node--course.html.twig template**, and as a result comes up really weird with some HTML stuff I dont want there.

I have enabled twig debug, and in the HTML source I indeed see the 'X' next to the template .. But why is that happening? What does this have to do with my 'course' content type? Why is that template being picked up? Is it because of the relationship between them? ...

I 'm quite confused .. Obviously I haven't understood how templates should be named and used, but still I can't get why that view has anything to do with a specific template such as node--MY\_CONTENT\_TYPE.html.twig ....

Thanks a lot for your patience and time ..

PS - I could replace my code with something like:

```
Direction: {{ node.field_course_direction.entity.label }}

```

and thus get only the 'raw' value, in this case a simple string saying 'Classical' without the link, but this is not what I want/ask .. I ask why is that template being picked up by a page that seems completely irrelevant to me ...

# Answer
A view can show content or fields. The taxonomy term view shows content and this means it renders each node in a node template. If you don't want that the template of the full node display is picked up by the view use different view modes, which you can append to the template name:

```
node--course--full.html twig
node--course--teaser.html.twig

```

`teaser` is the view mode the taxonomy term view uses by default. You can change this to a custom view mode if you want to style the nodes displayed here in a different way than in the front page view which uses `teaser` as well.
> 0 votes

---
Tags: theming
---


# Question
Title: How can I calculate product price based on product attributes?
I would like to calculate prices for all of my products based on value of the length or weight attribute multiplied by price per meter/g of the material selected for the product.

What is the best way to do this?

I have created content type material which has price per unit attribute. Each product when created is a assigned a material and length/weight.

When I tried to use the pricing rules i discovered I can only do simple things to the existing price and not calculate a brand new price :(

Once I have solution to this I want to be able to allow the user to select the weight/length and for the price to update accordingly.

Best Regards, Atta

# Answer
> 0 votes
The pricing rules give you the basic mathematical functions to manipulate a price (add, subtract, multiply), but they also give you the ability to set it to a specific amount. The rub just comes in calculating that amount you want to set it to first. : )

Rules allows you to calculate a value and then use that in subsequent actions, so that would be the course of action you might take ... you could, for example, ensure the rule knows about the fields you need to access on the product to make the calculation, multiply it out into a calculated value, and then set the price amount to that calculated amount.

However, this is a scenario where I'd typically expect a custom action to be created. Complex mathematical operations should be handled in code where they can be tracked, tested, etc.

---
Tags: commerce
---


# Question
Title: How to call a controller of custom module when a node is published?
I am planning to make a module whose controller is called or method in that controller executes when a node is published. The module should be able to get the title and other properties of article that is set to published. Here is controller:

```
namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;

class myController extends ControllerBase
{
    //Function that should be executed when a specific node is published
    public function publish()
    {
     //here I should get title and other properties of the published node
    }
}

```

I am new to drupal, I have looked into web and found that the solution is related to hooks but I don't know how to use them. Any help regarding the issue will be appreciated.

# Answer
The purpose of controllers is just providing output for a route, not implementing hooks. If you need to write code that is invoked when a node is published, you need to implement one of the following hooks:

`hook_node_presave()`, `hook_node_update()`, and `hook_node_insert()` get a `Node` object as parameter, so obtaining the body value is pretty easy.

```
use Drupal\node\Entity\Node;

function mymodule_node_presave(Node $node) {
  $body = $node->get('body')->value;
  $summary = $node->get('body')->summary;
}

```

Getting the taxonomy term from a reference field of a node can be achieved with code similar to the following one.

```
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;

function mymodule_node_presave(Node $node) {
  $term = Term::load($node->get('field_tags')->target_id);
}

```

To that, you need to add the code to verify the node has been published.

```
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;

function mymodule_node_presave(Node $node) {
  if ($node->status()) {
    // The node has been published.
    $body = $node->get('body')->value;
    $summary = $node->get('body')->summary;
    $term = Term::load($node->get('field_tags')->target_id);
    $term_name = $term->getName();
  }
}

```

If the taxonomy reference field is not *field\_tags*, replace *field\_tags* with the right machine name of the field.
> 0 votes

---
Tags: 8, nodes
---


# Question
Title: Functional test throws SQLSTATE[HY000] [2002] Connection refused
I have a phpunit.xml file which works for me for Kernel Base tests and which allows me to connect to a SQLite database. I want to use it for Functional tests also. I am new to Functional tests. My phpunit.xml file looks like this:

```
<phpunit bootstrap="./core/tests/bootstrap.php" colors="true"
         beStrictAboutTestsThatDoNotTestAnything="true"
         beStrictAboutOutputDuringTests="true"
         beStrictAboutChangesToGlobalState="true"
         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter">

  <env name="PHP_IDE_CONFIG" value="PHPSTORM"/>

  <php>
    <!-- Set error reporting to E_ALL. -->
    <ini name="error_reporting" value="32767"/>
    <!-- Do not limit the amount of memory tests take to run. -->
    <ini name="memory_limit" value="-1"/>
    <!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
    <env name="SIMPLETEST_BASE_URL" value="http://intellipass:8888/"/>
    <!--Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix -->
    <env name="SIMPLETEST_DB" value="sqlite://localhost//sites/default/files/db.sqlite"/>
    <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
    <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/tmp"/>
  </php>

  <testsuites>
    <testsuite name="Intellipass Functional Test Suite">
      <directory>./modules/custom/intellipass/tests/src/Functional</directory>
    </testsuite>
  </testsuites>

</phpunit>

```

And my Functional test class looks like this:

```
<?php

namespace Drupal\Tests\intellipass\Functional;

use Drupal\Tests\BrowserTestBase;

class EncryptionSecretTest extends BrowserTestBase {

  /**
   * Modules to install.
   *
   * @var array
   */
  public static $modules = ['system', 'intellipass'];

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

  /**
   * Tests comments in book export.
   */
  public function testRedirect() {
    $authenticatedUser = $this->drupalCreateUser();
    $this->drupalLogin($authenticatedUser);
  }

}

```

I am execution the test by the following command:

```
./phpunit-4.8.9.phar --testsuite="Intellipass Functional Test Suite"

```

Then I am getting this error:

```
peter@NB32 intellipass (master) $ ./phpunit-4.8.9.phar --testsuite="Intellipass Functional Test Suite"
PHPUnit 4.8.9 by Sebastian Bergmann and contributors.

E

Time: 3.73 seconds, Memory: 10.00Mb

There was 1 error:

1) Drupal\Tests\intellipass\Functional\EncryptionSecretTest::testRedirect
Exception: PDOException: SQLSTATE[HY000] [2002] Connection refused
Drupal\Component\DependencyInjection\PhpArrayContainer->createService()() (Line: 79)

/Users/peter/DevPrivat/intellipass/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php:44
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:203
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:156
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/TaskQueue.php:47
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:246
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:223
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:267
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:225
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/promises/src/Promise.php:62
/Users/peter/DevPrivat/intellipass/vendor/guzzlehttp/guzzle/src/Client.php:131
/Users/peter/DevPrivat/intellipass/vendor/fabpot/goutte/Goutte/Client.php:155
/Users/peter/DevPrivat/intellipass/vendor/symfony/browser-kit/Client.php:312
/Users/peter/DevPrivat/intellipass/vendor/behat/mink-browserkit-driver/src/BrowserKitDriver.php:144
/Users/peter/DevPrivat/intellipass/vendor/behat/mink/src/Session.php:148
/Users/peter/DevPrivat/intellipass/core/tests/Drupal/Tests/BrowserTestBase.php:333
/Users/peter/DevPrivat/intellipass/core/tests/Drupal/Tests/BrowserTestBase.php:472
/Users/peter/DevPrivat/intellipass/modules/custom/intellipass/tests/src/Functional/EncryptionSecretTest.php:17
/Users/peter/DevPrivat/intellipass/vendor/phpunit/phpunit/src/Framework/TestCase.php:764
/Users/peter/DevPrivat/intellipass/vendor/phpunit/phpunit/src/Framework/TestResult.php:612
/Users/peter/DevPrivat/intellipass/vendor/phpunit/phpunit/src/Framework/TestCase.php:724

FAILURES!
Tests: 1, Assertions: 1, Errors: 1.

```

The SQLite file definitely exists. I have tried the relative and absolute path.

How can I fix this

> Exception: PDOException: SQLSTATE\[HY000\] \[2002\] Connection refused

error?

# Answer
> 1 votes
I have found the solution. Drupal tries to use my default DB connection at first. This connection does not work for the test. Therefor I have placed an if-case around my DB-connection in my settings.php file. Then the DB connection in my phpunit.xml file will be used.

I have extended the testing documentation at https://www.drupal.org/docs/8/phpunit/phpunit-browser-test-tutorial for this (scroll down to the SQLite headline).

---
Tags: 8, testing
---


# Question
Title: Display the size and format of a file attached to an article
I'm trying to display the format and size of a file attached to an article. Its system name is *field\_file*.

So far, I've succeeded to load an article in my *my\_theme*.theme file and the *field\_file* field attached to it:

`$article = Node::load($article_nid);
$variables['file'] = $article->get('field_file');`

then use its uri in a twig file: `{{file_url(file.entity.fileuri)}}`

Now I'm trying to display its format and size. I tried `{{file.entity.format}}` and `{{file.entity.filesize}}` without success.

Does anyone have a clue how to do it? I'm still new to Drupal plugins and entities.

# Answer
Try getSize and getMimeType in your *my\_theme.theme* as in the example below

```
function my_theme_preprocess_node(&$vars) {
  $node = $vars['node'];
  $type = $node->getType();
  if( $type == "article" && $node->hasField('field_file')){
      //next gets FieldItemList
      //$file = $node->get('field_file');

      //you need get the file entity
      $file = $node->get('field_file')->entity;
      $vars["size"] = $file->getSize();
      $vars["type"] = $file->getMimeType();
  }
}

```
> 3 votes

---
Tags: 8, files
---


# Question
Title: Views, if image field exists show it, else show this
I was wondering if this this possible using Views with Views conditional.

I need to check whether an image field has content, and if not just show some html + a token from a computed field.

Which condition should I use in Views Conditions? And is it possible. Thanks guys

# Answer
> 0 votes
You can use "Rewrite the output of this field", can put an token inside the output and if I'm not wrong there's an check-mark "if the field has values".

# Answer
> 0 votes
The "NO RESULTS BEHAVIOR" gives you a text box where you can enter something like "No image."

You can also set up the field in your content type so that there is a default image. That way, if no image has been included, your default image will show up in your view automatically, and you won't have to use "REWRITE RESULTS" or "NO RESULTS BEHAVIOR."

---
Tags: 7, views
---


title: Change target site

text:
# Question
Title: Change target site
I installed Drupal 7 manually and later installed Drush 5. That works fine. When I use command **drush config** it shows the path to my site. Now I have installed a second instance of Drupal 7 in another site location. How do I change the drush installation to point to the new site rather than the old one? I have spend an hour searching documentation but I can't find how to do this.

# Answer
> 0 votes
Drush is detecting site location automatically based on the current working directory and site alias. Just move to the site directory or use `--root` option to point the desired site to operate.

Also, note that Drush 5 is very outdated version. For Drupal 7 you should install Drush 8.

---
Tags: drush
---


# Question
Title: How do I display data basing on the permissions a user has within a group?
In a custom module I wrote, I implemented `hook_og_permission()` to define a new group permission.

```
/**
 * Implements hook_og_permission().
 */
function logic_board_og_permission() {
  return array(
    'rulesprm' => array(
      'title' => t('Rules Form Perm'),
      'description' => t("Allow og user to fill form"),
    ),
  );
}

```

I then use the following code to verify the user has that permission, to show some data.

```
if (user_access('rulesprm')) {
  // …
}

```

The code doesn't work. Even if the user has that permission, the code inside the `if()` block isn't executed. Why does this happen?

# Answer
> 1 votes
`user_access()` is for core permissions, those added through `hook_permission()`. For organic groups own permissions hook, you need to use the complementary `og_user_access()`.

```
if (og_user_access($group_type, $gid, 'rulesprm')) {
  // …
}

```

See the documentation comment for `hook_og_access()` given in the *og.api.php* file, which states:

> Permissions are checked using `og_user_access()`.

---
Tags: 7, organic-groups
---


# Question
Title: How to change the saving order of field_collection fields
I have a node with field1 and field2 (field\_collection)

I am using hook\_entity\_presave($entity, $type) like this:

```
function txs_entity_presave($entity, $type)
{
    if ($type == 'field_collection_item') {
      ...do some stuff
    }
}

```

For now, this hook is called firstly for field1 and, only after field1 is saved, this hook is called for field2.

I would like the opposite because I need to retrieve the value of field2 to handle the "field1\_presave".

Here are the details:

Here is the code inside the hook\_entity\_presave, when field1 is being presaved. This code is showing why I need that field2 must be saved before field1

```
if ($entity->field_name == 'field1'){
    $entity_w = entity_metadata_wrapper('field_collection_item', $entity);
    $node = $entity_w->host_entity->value();
    $node_w = entity_metadata_wrapper('node', $node);

    //HERE I NEED THAT field2 was already saved...
    //This is not the case...
    //the following line does not works in all cases
    $used_value=node_w->field2[0]->myfield->value();
    //as field2 is not yet saved, $used_value could be wrong
    if ($used_value=='something'){
        ...change something in field1
    }
}

```

# Answer
> 0 votes
The only way I could solve my problem was to handle the logic in the form\_validate function. Unfortunately, I couldn't update the field collection from there... this is why I added a validation function for my field collection:

```
/**
 * Implements hook_field_widget_form_alter().
 */
function MYMODULE_field_widget_form_alter(&$element, &$form_state, $context) {
  // Add custom validation hooks for Field Collections.
  if ($context['field']['field_name'] == 'field1') {
    array_unshift($element['#element_validate'],
'MYMODULE_field1_validate');
  }
}

```

Then I could insert my logic there:

```
/**
 * Custom validate function for field_assignments.
 *
 *  @see MYMODULE_field_widget_form_alter()
 */
 function MYMODULE_field1_validate($element, &$form_state, $form) {
    if (...){
       form_set_value($form["field1"][LANGUAGE_NONE][0]['field_to_change'], array(LANGUAGE_NONE => array(0 => array('value' => 123.456))), $form_state);
    }
  }

```

---
Tags: 7, hooks, entities
---


# Question
Title: Can't get fid of the saved file after file_save_data
I have been trying to get the fid of the file which my custom module is saving and every time I end up getting the error "Trying to get property of non-object in report()". I have tried file\_object-\>id() and file\_object-\> fid -\>value but neither are working. This is my code in .module file:

```
function file_write($source , $name) {

$uri =  file_default_scheme() . '://'.$name.'.txt';

$file_object = file_save_data($source, $uri, FILE_EXISTS_REPLACE);
return $file_object;
}

```

And this is where how I call it and try to get fid:

```
$file_object = file_write($source, $name);
$fid = $file_object->fid->value;

```

Is there anything wrong with the code? I also tried using other methods, but no luck so far.

# Answer
> 0 votes
In Drupal 7, `$file_object->fid` should work.

Looking at the code you have tried (`$file_object->fid->value`, `file_object->id()`), I guess you have been mixing up Drupal 8 and Drupal 7 documentation.

---
Tags: 7, files
---


# Question
Title: Can we use the same path for a different route?
Are we allowed to use the same path for two different routes? For example, can I use the following code?

```
function mymodule_menu() {
  $items['myUrl/dboperation'] = array(
    'title' => 'some custom db operation for insert',
    'page callback' => 'mydboperation1',
    'access callback' => TRUE,
    'file' => 'my_dboperation.inc',
  );

  $items['myUrl/dboperation'] = array(
    'title' => 'some custom db operation for delete',
    'page callback' => 'mydboperation2',
    'access callback' => TRUE,
    'file' => 'my_dboperation.inc',
  );

  return $items;
}

```

The code doesn't work. It works when I change the second path.

I was searching for the answer and came across How should I implement hook\_menu()? but it doesn't explain what to use for the route path.

Why doesn't my code work? What should I instead use to make it work?

# Answer
The short answer is NO.
Your would ether make a different path to each function or send an argument to a single function through the url.
eg. different path:

```
function mymodule_menu() {

    $items['myUrl/dboperation/insert'] = array(
        'title' => 'some custom db operation for insert',
        'page callback' => 'mydboperation1',
        'access callback' => TRUE,
        'file' => 'my_dboperation.inc',
    );

    $items['myUrl/dboperation/delete'] = array(
        'title' => 'some custom db operation for delete',
        'page callback' => 'mydboperation2',
        'access callback' => TRUE,
        'file' => 'my_dboperation.inc',
    );

    return $items;
}

```

See the hook\_menu docs for how to send an argument if you choose to do it that way.
> 1 votes

# Answer
The answer for this question is very simple

When we create 2 menus with same path and different function then the menu taken later will override the first one if they have the same weight.

It is same like when we create an array with same key and assign different values to it then the array taken at the second position override the value of first one if they have the same weight

```
<?php
$ar = array();
$ar['name'] = 'Raj'; //same like first menu
$ar['name'] = 'Thakur';  //second menu

print $ar['name']; //It will print **Thakur**
?>

```

Same concept is used for menus if they have the same weight, however you can give more priority to any menu using 'weight' parameter.

You can override any menu by its weight

```
<?php
 $items['myUrl/dboperation'] = array(
        'title' => 'some custom db operation for insert',
        'page callback' => 'mydboperation1',
        'access callback' => TRUE,
        'file' => 'my_dboperation.inc',
        'weight'=>2

    );

    $items['myUrl/dboperation'] = array(
        'title' => 'some custom db operation for delete',
        'page callback' => 'mydboperation2',
        'access callback' => TRUE,
        'file' => 'my_dboperation.inc',
         'weight'=1

    );
?>

```

This menu second menu can take the higher priority over the first one.

And any change in menu need to clear cache.

Hope it will answer your question.
> 0 votes

# Answer
Weight is used to arrange menu items in menu. You can use hook\_menu\_alter to alter your menu items functionality.

https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook\_menu\_alter/7
> 0 votes

# Answer
The reason why the code doesn't work is that the same array index is being set twice. In that case, only the last value set is kept. That code is exactly equivalent to the following one.

```
function mymodule_menu() {
  $items['myUrl/dboperation'] = array(
    'title' => 'some custom db operation for delete',
    'page callback' => 'mydboperation2',
    'access callback' => TRUE,
    'file' => 'my_dboperation.inc',
  );

  return $items;
}

```

If you want to make it work, you have two possibilities: Define two different paths, or use wildcard arguments.

In the first case, you need to make the code similar to the following one.

```
function mymodule_menu() {
  $items['myUrl/dboperation/insert'] = array(
    'title' => 'Insert data in the database',
    'page callback' => 'mymodule_database_insert',
    'access callback' => TRUE,
    'file' => 'my_dboperation.inc',
  );

  $items['myUrl/dboperation/delete'] = array(
    'title' => 'Delete data from the database',
    'page callback' => 'mymodule_database_delete',
    'access callback' => TRUE,
    'file' => 'my_dboperation.inc',
  );

  return $items;
}

```

I changed the callback names because in Drupal it is preferable that functions implemented by a module are prefixed with the machine name of the module, to avoid conflicts with other modules.

The second alternative is using wildcard arguments, which allows to pass arguments to the page callback, making it more helpful. It also make extending the code easier, and less error-prone, since there isn't the need to add a new route for new operations. In the following code, I am using the first argument to decide the operation that must be done on the database, while the second argument is a generic one, and it could be used to decide on which data the operation must be performed.

```
function mymodule_menu() {
  $items['myUrl/dboperation/%/%'] = array(
    'title' => 'Change data in the database',
    'page callback' => 'mymodule_database_operation',
    'page arguments' => array(2,3),
    'access callback' => TRUE,
    'file' => 'my_dboperation.inc',
  );
  return $items;
}

function mymodule_database_operation($op, $arg) {
  switch $op {
    case 'insert':
      // Insert data.
      break;
    case 'delete':
      // Delete data.
      break;
  }
}

```
> 0 votes

---
Tags: 7, hooks, routes
---


title: How do I migrate images?

text:
# Question
Title: How do I migrate images?
I have to migrate my blogs (Drupal 7) to Drupal 8. I tried and succeed in field migration but I am not able to migrate my image field. I have tried by process plugin, nothing happened. Files migration already been done.

This is configuration file

```
id: custom_blogs
label: Custom Blogs Migration

source:
  plugin: custom_blogs

destination:
  plugin: entity:node

process:
  # Field mappings and transformations will go here. We will get to this in a minute.
  nid: nid
  type:
    plugin: default_value
    default_value: ct_blogs
  langcode:
    plugin: static_map
    bypass: true
    source: language
    map:
      und: en
  title: title
  uid: uid
  status: status
  'body/value': body_value
  'body/format':
    plugin: static_map
    bypass: true
    source: body_format
    map:
      1: plain_text
      2: basic_html
      3: full_html
  'body/summary': teaser
  'field_ct_blog_image_caption/value': field_blog_image_caption_value
  'field_ct_blog_image_caption/format':
    plugin: static_map
    bypass: true
    source: field_blog_image_caption_format
    map:
      1: plain_text
      2: basic_html
      3: full_html
      4: filtered_html
  'field_ct_blog_image_caption/summary': field_blog_image_caption_teaser
  field_ct_blogs_tags: tags
  field_ct_blogs_image: # Image field name in Drupal 8 site
    plugin: iterator
    source: field_image # Image field name in Drupal 7 site
    process:
      target_id:
        plugin: migration
        migration: custom_blogs_images
        source: fid
      alt: field_image_alt
      title: field_image_alt
      width: field_image_width
      height: field_image_height

```

This is process plugin

```
<?php
/**
 * @file
 * Contains \Drupal\migrate_custom\Plugin\migrate\source\Blogs.
 */

namespace Drupal\custom_migration\Plugin\migrate\source;

use Drupal\migrate\Row;
use Drupal\migrate\Plugin\migrate\source\SqlBase;

/**
 * Extract users from Drupal 7 database.
 *
 * @MigrateSource(
 *   id = "custom_blogs"
 * )
 */
class Blogs extends SqlBase {

  /**
   * {@inheritdoc}
   */
  public function query() {
    $query = $this->select('node', 'n')
      ->condition('n.type', 'blog')
      ->fields('n', array(
        'nid',
        'vid',
        'type',
        'language',
        'title',
        'uid',
        'status',
        'created',
        'changed',
        'promote',
        'sticky',
      ));

    $query->orderBy('nid');
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function fields() {
    return [
      'nid' => $this->t('Node ID'),
      'vid' => $this->t('Version ID'),
      'type' => $this->t('Type'),
      'title' => $this->t('Title'),
      'format' => $this->t('Format'),
      'teaser' => $this->t('Teaser'),
      'uid' => $this->t('Authored by (uid)'),
      'created' => $this->t('Created timestamp'),
      'changed' => $this->t('Modified timestamp'),
      'status' => $this->t('Published'),
      'promote' => $this->t('Promoted to front page'),
      'sticky' => $this->t('Sticky at top of lists'),
      'language' => $this->t('Language (fr, en, ...)'),
      'body/value' => $this->t('Value of body'),
      'body/format' => $this->t('Format of body'),
      'body/summary' => $this->t('Summary of body'),
      'field_blog_image_caption/value' => $this->t('Value of Image Caption'),
      'field_blog_image_caption/format' => $this->t('Format of Image Caption'),
      'field_blog_image_caption/summary' => $this->t('Summary of Image Caption'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {
    // Find parents for this row.
    $nid = $row->getSourceProperty('nid');

    $result = $this->getDatabase()->query('
      SELECT
        fld.body_value,
        fld.body_format,
        fld.body_summary
      FROM
        {field_data_body} fld
      WHERE
        fld.entity_id = :nid
    ', array(':nid' => $nid));
    foreach ($result as $record) {
      $row->setSourceProperty('body_value', $record->body_value );
      $row->setSourceProperty('body_format', $record->body_format );
      $row->setSourceProperty('teaser', $record->body_summary );
    }

    // Image Caption
    $result = $this->getDatabase()->query('
      SELECT
        fld.field_blog_image_caption_value,
        fld.field_blog_image_caption_format,
        fld.field_blog_image_caption_summary
      FROM
        {field_data_field_blog_image_caption} fld
      WHERE
        fld.entity_id = :nid
    ', array(':nid' => $nid));
    foreach ($result as $record) {
      $row->setSourceProperty('field_blog_image_caption_value', $record->field_blog_image_caption_value );
      $row->setSourceProperty('field_blog_image_caption_format', $record->field_blog_image_caption_format );
      $row->setSourceProperty('field_blog_image_caption_teaser', $record->field_blog_image_caption_summary );
    }

    // Images
    $result = $this->getDatabase()->query('
      SELECT
        -- fld.field_image_fid,
        fld.field_image_alt,
        fld.field_image_title,
        fld.field_image_width,
        fld.field_image_height
      FROM
        {field_data_field_image} fld
      WHERE
        fld.entity_id = :nid
    ', array(':nid' => $nid));
    // Create an associative array for each row in the result. The keys
    // here match the last part of the column name in the field table.
    $images = [];
    foreach ($result as $record) {
      $images[] = [
        // 'target_id' => $record->field_files_fid,
        'field_image_alt' => $record->field_image_alt,
        'field_image_title' => $record->field_image_title,
        'field_image_width' => $record->field_image_width,
        'field_image_height' => $record->field_image_height,
      ];
    }
    $row->setSourceProperty('field_image', $images);

    // Tags
    $result = $this->getDatabase()->query('
      SELECT
        GROUP_CONCAT(fld.field_tags_tid) as tids
      FROM
        {field_data_field_tags} fld
      WHERE
        fld.entity_id = :nid
    ', array(':nid' => $nid));
    foreach ($result as $record) {
      if (!is_null($record->tids)) {
        $row->setSourceProperty('tags', explode(',', $record->tids) );
      }
    }

    return parent::prepareRow($row);
  }

  /**
   * {@inheritdoc}
   */
  public function getIds() {
    $ids['nid']['type'] = 'integer';
    $ids['nid']['alias'] = 'n';
    return $ids;
  }
}

```

Any idea about what I am doing wrong?

# Answer
> 6 votes
You might try using 'migration\_lookup' instead of 'migration' as your process plugin. Here's what I used to migrate into an image field 'field\_image'.

```
  field_image:
    plugin: iterator
    source: field_image
    process:
      target_id:
        plugin: migration_lookup
        migration: id_of_file_migration
        source: fid
      alt: alt
      title: title
      height: height
      width: width

```

# Answer
> 5 votes
There is a example project at https://github.com/jigarius/drupal-migration-example/ that can help you fixing your problem.

This example module is explained in Drupal 8 Migration: Migrating Files / Images (Part 3). This is an important part that you need to knoww:

> First we need to create file entities for each file. This is because Drupal treats files as file entities which have their own ID. Then Drupal treats node-file associations as entity references, referring to the file entities with their IDs.

---
Tags: 8, migrations
---


# Question
Title: How do I deploy/manage similar sites from an unique profile, without dumps?
I do not like the "**cloning** website" solutions which implies **dumping** a database and importing this dump in another environment. This does not look like a *real world* way of deploying several instances of the same website (staging/prod/dev/etc).

With D7 we usually used custom profiles and used drush to install websites from these profiles (and maybe using features for later site synchronisations). This provided us with fresh installations, no test content, but sharing important settings. Common content synchronisation would be done with migrate, for example.

I tried to manage several D8 instances sharing the same install profiles. Where the final goal would be to share and sync site configurations. And every installation has a different site UUID. I have no success in enforcing the `system.site uuid` config variable at install time (of course I can alter the value later, but it seems to me that this is too late, and all objects are already created with different UUIDs, which makes the first synchronisation a **nightmare**, where some default contents must be deleted, or default language crashing the sync because it cannot be removed, etc.).

To enforce this UUID I tried using a generated settings.php file with a `$config['system.site']['uuid']` value inside, big fail (the setting was completely ignored, even after site installation).

I've also looked at configuration installer profile, which I do not completely understand, especially the way to mix this solution with another install profile.

So the question is, what is the best way of deploying fresh sites from an install profile:

* without "cloning websites" and manipulating SQL dumps at site creation (like in what are cloned sites question ).
* with a fresh clean install (without developers content garbage), using the exported configuration and code **only**
* which can manage both install configuration defaults and later synchronisations

# Answer
> 3 votes
Features can help bypassing the UUID problem. It's still buggy, which prevents us from fully automating the process, but we can at least shift and maintain configuration manually.

Features still creates modules, it exports the configuration into the config/install directory of the given features module. This will be picked up when you install the feature, and you can continue to update your site config (similarly to what the old drush features-revert did) as your features export changes.

You can also import configuration directly via drush, make sure to use the --partial flag, to avoid overriding configuration *not* in the config folder. Using --source you can also define a custom configuration folder location, so you can do something like `drush cim --partial --source=docroot/modules/features/myfeature/config/install`.

# Answer
> 1 votes
Another option:

```
drush config-set system.site uuid 56974bf2-68c2-3453-a211-de8bc754cc23

```

# Answer
> 1 votes
Based on @Ivan Jaros hint, you can set certain configuration options upon installing a profile. Obviously, this only works on installation and not once a site is already installed.

In the .install file of your profile, you can add in default configuration settings in `hook_install()`:

```
\Drupal::configFactory()
  ->getEditable('system.site')
  ->set('uuid', 'this is my new uuid')
  ->save(TRUE);

```

I have tried this locally and it does work. I was able to pull config from another site into a freshly installed local site using the code above (with the proper UUID set) without using `drush cset` to change the site UUID.

Presumably, you could set your UUID to be taken from a file on your environment somewhere, or an environment variable, or service, and thus they would all be the same on any site with that profile installed.

I hoped to do a similar thing from `settings.php` but the `ConfigFactory` class isn't available at that point and as you point out in your question setting it via `$config` in `settings.php` has no effect.

---
Tags: 8, configuration, deployment
---


# Question
Title: Run KernelEvents::REQUEST event before hook_node_access?
I'm doing some central static variable setup for the request and was hoping to use `KernelEvents::REQUEST` to run first and set the variables.

However, I've found that while the documentation states:

> The REQUEST event occurs at the very beginning of request dispatching.

`hook_node_access` actually runs before the `KernelEvents::REQUEST` event handler:

```
  /**
   * The subscribed events.
   */
  public static function getSubscribedEvents() {
    $events = [];
    $events[KernelEvents::REQUEST][] = ['onKernelRequest', 1];
    return $events;
  }

```

then in the event listener:

```
  public function onKernelRequest(GetResponseEvent $event) {
    drupal_set_message(__FUNCTION__ . ': ' . microtime());
  }

```

and in `hook_node_access`

then in the event listener:

```
  public function mymodule_node_accesss(NodeInterface $node, $op, AccountInterface $account) {
    drupal_set_message(__FUNCTION__ . ': ' . microtime());
  }

```

Output:

```
mymodule_node_access: 0.76379200 1518995630
onKernelRequest: 0.77758400 1518995630

```

As we can see from microtime order, `hook_node_access` runs first. Anyway to make it run after the `KernelEvents::REQUEST` event handler? thanks.

# Answer
OK, after a bit more digging, I found the solution.

The "weight" param for `['onKernelRequest', 1]` is sort DESC, so the higher weight number will run first.

Adjusting the event listener with weight `1000` as follows means it runs before the `hook_node_access` invoking listener

```
  /**
   * The subscribed events.
   */
  public static function getSubscribedEvents() {
    $events = [];
    $events[KernelEvents::REQUEST][] = ['onKernelRequest', 1000];
    return $events;
  }

```
> 5 votes

---
Tags: 8, event-subscribers
---


# Question
Title: How to create a list of untranslated content in views?
I want to create a list of all nodes that has not been translated into a specific language - how do I do that?

I'm using Drupal 8.

# Answer
> 0 votes
You can use the Translation Views module.

# Answer
> -2 votes
I assume you have enabled core module `language` and `content translation` and added a 2nd language in `admin/config/regional/language` and you should also have `enable translation` and probably `language selection` for a specific content type lets say `basic page`

content translation core has a views filter for the purpose of finding the nodes that need translation or ones that need to REVISE their translation (that are outdated)

create a view `untranslated` and add 2 filters `Content: Default translation (= True)` `Content: Revision translation affected (!= False)`

NOTE: this will originally show you all untranslated but if a translation flags other translations as `flag other translations as outdated` then those SOURCE nodes will also be included in the list

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


# Question
Title: How can I have the nodes grouped in descending order and the nodes in ascending order?
I have a view listing articles grouped by year (on the post date) which returns me a HTML list like this.

```
2018

- Article Feb 01, 2018
- Article Jan 05, 2018

2017

- Article Dec 01, 2017
- Article Nov 05, 2017
- Article Oct 03, 2017
- Article Sep 05, 2017

```

The years are correctly sorted in descending order, but I would like to have the nodes of each year sorted in ascending order, as in the following list.

```
2018
- Article Jan 05, 2018
- Article Feb 01, 2018

2017
- Article Jan 10, 2017
- Article Oct 03, 2017
- Article Nov 05, 2017
- Article Dec 01, 2017

```

I have tried to apply an ascending sort on the content, but it also affects the years.

I have also checked Views: how to ASC sort the grouping field #1 and sort DESC its content?, but I don't want to add an extra field for the year.

I have also tried the solution posted on Views, Group By, can't specify order? but it didn't work for me.

How can I achieve it?

# Answer
> 0 votes
You can use hook\_views\_query\_alter

```

function MODULENAME_views_query_alter(&$view, &$query) {
   //print_r($view->query->orderby);
  if ($view->name == 'VIEWNAME') {
  // check the position on the orderBy function in the query
  // For this you can check the values with print_r() function.
   $view->query->orderby[0]['direction'] = "ASC";
  }
}

```

---
Tags: 7, views
---


# Question
Title: How to add css depending on a field value?
I have a field attached to a node which contains an image or not.

If there is an image I should load a specific css(sass).

How can I do this?

# Answer
> 2 votes
Basically you need to drupal\_add\_css in your template\_preprocess\_node in your `template.php` after checking the condition that image exists in a manner similar to

```
$field = field_get_items('node', $node, 'field_image');
if ($field) {
   //Do something with the field
}
else{
   //There are no results
}

```

---
Tags: 7, theming
---


# Question
Title: How can I handle the user access to specific taxonomy terms?
There is a node form with a term reference field which's terms list I want to filter based on users/ permissions.

I've tried several modules in which I can grant access either user- or role-based for individual terms. Unfortunately, these settings are ignored by "Views: Filter by an entity reference view" when the views list is built.

So, whats the right way? How do I globally set per-term permissions that are also respected by views listings?

I've thought about changing the term controller but I don't see an access function there. Do I have to use a query alteration? Is there a hook?

# Answer
> 1 votes
You may want to try to add your own access checking in your view. A possible way to do so, is to use the Views Access Callback module, which you can yuse in a custom module to make your view perform whatever access check you want. Some more details about this Views Access Callback module (from its project page):

> Provides callback-based access control for Views.
>
> Available callback functions are defined by modules using `hook_views_access_callbacks()` function (in the same way as in `hook_perm()`), then could be set in in view's "Access restrictions" configuration.

The Community documentation for this module provides some extra details to get you going with this module.

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


# Question
Title: BrowserTest on a multisite gives an error
My sites directory looks like this:

default, site1, site2, site3.

The default directory is empty. I want to run tests against my site1 database. So I have put its details in phpunit.xml

Here is my phpunit.xml set up.

```
  <php>
    <!-- Set error reporting to E_ALL. -->
    <ini name="error_reporting" value="32767"/>
    <!-- Do not limit the amount of memory tests take to run. -->
    <ini name="memory_limit" value="-1"/>
    <!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
    <env name="SIMPLETEST_BASE_URL" value="http://d8.site1.dev"/>
    <!-- Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix -->
    <env name="SIMPLETEST_DB" value="mysql://site1:site1@localhost/site1"/>
    <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
    <env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>
  </php>

```

And then my actual test:

```
<?php

namespace Drupal\Tests\my_module\Functional;

use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;

/**
 * Simple test to ensure that main page loads with module enabled.
 *
 * @group my_module_tests
 */
class LoadTest extends BrowserTestBase {

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['my_module'];

  /**
   * A user with permission to administer site configuration.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $user;

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->user = $this->drupalCreateUser(['administer site configuration']);
    $this->drupalLogin($this->user);
  }

  /**
   * Tests that the home page loads with a 200 response.
   */
  public function testLoad() {
    $this->drupalGet('node/add/product_list_page');
    $this->assertResponse(200);
  }

}

```

Then from the core directory of Drupal I run:

```
../../vendor/bin/phpunit --group my_module_group

```

Then I get this error:

1) Drupal\Tests\my\_module\Functional\LoadTest::testLoad copy(/var/www/site/docroot/sites/default/default.settings.php): failed to open stream: No such file or directory

Why is it looking in my empty default directory and not site1 for this file?

# Answer
> 0 votes
It is possible to have a multisite directory setup with PHP Unit.

Since your default directory is empty, I suggest creating a symbolic link from the default directory to the site1 directory. You can do that by using commands similar to this one from sites directory.

```
ln -s sites1 default

```

Not sure, but you may also need to adjust the `$sites` variable in sites.php.

Also, make sure you specify a printerClass like this in the last line.

```
<phpunit bootstrap="tests/bootstrap.php" colors="true"
         beStrictAboutTestsThatDoNotTestAnything="true"
         beStrictAboutOutputDuringTests="true"
         beStrictAboutChangesToGlobalState="true"
         checkForUnintentionallyCoveredCode="false"
         printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter">

```

Here is what my php tag looks like in `phpunit.xml` (I use SQLite though and specify an output directory.) You may need to adjust directory permissions so that it is writable. I test on my remote machine with a FQDN, not sure if that is ideal though.

```
<php>
    <!-- Set error reporting to E_ALL. -->
    <ini name="error_reporting" value="32767"/>
    <!-- Do not limit the amount of memory tests take to run. -->
    <ini name="memory_limit" value="-1"/>
    <!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
    <env name="SIMPLETEST_BASE_URL" value="https://dev.example.com"/>
    <!-- Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix -->
    <env name="SIMPLETEST_DB" value="sqlite://dev.example.com/sites/dev.example.com/files/.ht.sqlite"/>
    <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
    <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/path/to/document/root/sites/dev.example.com/files/simpletest/browser_output"/>
</php>

```

Also, I run the phpunit command from the Drupal core directory like this (I do not use group ID but I know it may be possible.

```
sudo -u www-data ../vendor/bin/phpunit ../modules/contrib/example/tests/src/Functional/ExampleHomepageTest.php

```

Here is what my test looks like. It will need the correct directory structure and classname.

```
<?php

namespace Drupal\Tests\example\Functional;

use Drupal\Tests\BrowserTestBase;

/**
 * Tests to ensure Example.com Homepage is reachable
 *
 * @group example_ui
 */
class ExampleHomepageTest extends BrowserTestBase {

/**
 * Modules to enable.
 *
 * @var array
 */
protected static $modules = ['node', 'user'];

protected $profile = 'standard';

/**
 * {@inheritdoc}
 */
public function setUp() {
parent::setUp();

}

/**
  * Tests that the reaction rule listing page works.
  */
public function testHomepage() {

  $account = $this->drupalCreateUser(array('administer site configuration'));
  $this->drupalLogin($account);

  $this->drupalGet('<front>');
  $this->assertSession()->statusCodeEquals(200);
  $this->assertSession()->pageTextContains('cleaning');
 }
}

```

This page will be useful: https://www.drupal.org/docs/8/phpunit

---
Tags: 8, testing
---


# Question
Title: Why isn't submission handler I add with hook_form_alter() called?
The submission handler I add in `hook_form_alter()` isn't invoked. I tried the following code, but it doesn't work.

```
use Drupal\Core\Form\FormStateInterface;

function MODULENAME_form_alter(&$form,$form_state, $form_id) {
  if ($form_id == 'FORMID') {
    $form['actions']['submit']['#submit'][] = 'MODULENAME_form_submit';
  }
}

function MODULENAME_form_submit($form, FormStateInterface $form_state) {
  print_r($form_state);
}

```

How do I add a submission handler to a webform?

# Answer
> 0 votes
Maybe you can try this :

```
  function MODULENAME_form_alter(&$form,$form_state, $form_id) {
    if ($form_id == 'FORMID') {
      foreach (array_keys($form['actions']) as $action) {
        if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
          $form['actions'][$action]['#submit'][] = 'MODULENAME_form_submit';
        }
      }
    }
  }

  function MODULENAME_form_submit($form, FormStateInterface $form_state) {
    kint($form_state);
  }

```

---
Tags: 8, webforms
---


# Question
Title: Print rendered field in views-view.html.twig
I try to render a custom node field in a views-view.html.twig and it works, the only thing is that i get the machine name and not the formatted name. Please can somebody describe me what i am doing wrong?

I have tried several ways like:

```
{{ view.field.field_my_field.value(view.result[0]) | render }}

```

or

```
{{ view.field.field_my_field.value(view.result[0]) }}

```

Thanks for helping!

# Answer
this does get the value

```
{{ view.field.field_my_field.value(view.result[0]) }}

```
> 0 votes

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


# Question
Title: I cannot create a directory when installing a module
I have a clean install of Drupal 8 on a new Centos 7 server. This is the first module I have attempted to install. I'm using the built in update manager. I get the following error.

> File Transfer failed, reason: Cannot create directory /var/www/html/modules/somemodule

This seems like a common enough permissions problem but no answers I've found on similar questions have worked. The webserver user is *apache* (not *www-data*) and it owns the modules directory. I have confirmed this with `ps aux | grep -i 'www\|apache\|nginx'`.

These are the current permissions.

```
drwxr-xr-x.  2 apache apache    24 Jan  3 13:27 modules

```

I have chowned and chmodded until I'm blue in face, but it hasn't changed anything since the apache user already owns the directory and should be able to write it.

/admin/reports/status shows all green including FILE SYSTEM Writable (*public* download method).

What could be wrong? How can I further troubleshoot?

I am using PHP 7.1.14, Apache httpd-2.4.6-67.el7.centos.6.x86\_64, and Drupal 8.4.4.

Update:

I have tried chmod -R 777 as a test and receive the same error. I have also tried creating the directory for the module manually but the update manager is still unable to copy files to it.

Update 2:

I have downgraded to php 7.1 to be fully compliant with Drupal 8 requirements but this has not solved the issue or changed the behavior.

# Answer
> 0 votes
This turned out to be an SELinux issue. SELinux is enabled and running in *enforcing* (strictest) mode by default in Centos 7 and this will prevent the web user from being able to write to /modules or /files (or anywhere) regardless of the file permissions set.

To see if you may be having the same problem:

```
more /etc/selinux/config

```

This will display the SELinux config file and let you know if it is enabled and what mode it is in.

The issue can be corrected with the following commands:

```
sudo chcon -Rt httpd_sys_content_t /var/www/html
sudo chcon -Rt httpd_sys_rw_content_t /var/www/html/sites/default/files
sudo chcon -Rt httpd_sys_rw_content_t /var/www/html/modules
sudo chcon -Rt httpd_sys_rw_content_t /var/www/html/vendor

```

This will correct the context of the directories you want to grant write permissions on so that Drupal will work without disabling SELinux. For more information see the man pages for selinux and chcon.

---
Tags: 8
---


# Question
Title: How do I test the methods or hooks implemented in .module file using PHPUnit?
PHPUnit testing in Drupal 8 works for functionality which are written in class files.

How do I test the methods or hooks implemented in a .module file using PHPUnit in Drupal 8?

# Answer
> 1 votes
No, PHPUnit is not for testing functionalities written in class files. Quite the opposite, PHPUnit in Drupal can be used to test hooks, functions, and classes implemented from modules.
Drupal core itself has tests for hooks, for example the `InfoAlterTest` class that tests `hook_system_info_alter()`.

How to write tests is described in Automated tests. Without a specific use-case, I cannot give more details on testing hooks, except saying that functional tests that do not test web output, which is the case for most of the hook tests, the test class needs to extend `\Drupal\KernelTests\KernelTestBase`.

### References

---
Tags: testing
---


# Question
Title: How to add a custom function in a Drupal theme?
At WordPress there is a well-known way to add a custom function for the theme and hook the code to the like this:

```
function add_customcode_header(){
    if(ICL_LANGUAGE_CODE == 'en')
      {
        echo '<link rel="stylesheet" type="text/css" href="/cookie-consent/cookieconsent.min.css" />
<script src="/cookie-consent/cookieconsent.min.js"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
  "palette": {
    "popup": {
      "background": "#000000"
    },
    "button": {
      "background": "#ffffff"
    }
  },
  "showLink": false,
  "position": "bottom-left",
  "content": {
    "message": "This website uses cookies to give you the best, most relevant experience. Using this website means you are Ok with this. However, if you would like to, you can change your cookie settings at any time.",
    "dismiss": "Got it!",
    "link": "Learn more"
  }
})});
</script>';
    }
      else
      {
        echo '<link rel="stylesheet" type="text/css" href="/cookie-consent/cookieconsent.min.css" />
<script src="/cookie-consent/cookieconsent.min.js"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
  "palette": {
    "popup": {
      "background": "#000000"
    },
    "button": {
      "background": "#ffffff"
    }
  },
  "showLink": false,
  "position": "bottom-left",
  "content": {
    "message": "This website uses cookies to give you the best, most relevant experience. Using this website means you are Ok with this. However, if you would like to, you can change your cookie settings at any time.",
    "dismiss": "Got it!",
    "link": "Learn more"
  }
})});
</script>';
      }
    }
    add_action('wp_head', 'add_customcode_header');

```

How to adjust this code to work on Drupal 7 theme? I need to place the code on all front-end pages header according to the language. Where do I put it?

**Edit:** Sorry, I that did not provided enough information. I need to add this code to the `<head></head>` section of every page:

```
<link rel="stylesheet" type="text/css" href="/cookie-consent/cookieconsent.min.css" />
<script src="/cookie-consent/cookieconsent.min.js"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
  "palette": {
    "popup": {
      "background": "#000000"
    },
    "button": {
      "background": "#ffffff"
    }
  },
  "showLink": false,
  "position": "bottom-left",
  "content": {
    "message": "This website uses cookies to give you the best, most relevant experience. Using this website means you are Ok with this. However, if you would like to, you can change your cookie settings at any time.",
    "dismiss": "Got it!",
    "link": "Learn more"
  }
})});
</script>

```

There are 3 languages on the website and I need to place a separate code for each of the language.

# Answer
Since `add_action('wp_head', 'add_customcode_header')` would add the output of `add_customcode_header()` to the `<head>` tag, the Drupal 7 equivalent is implementing a preprocess function for the HTML output.

Supposing that *mytheme* is the machine name of the theme, and I want to add a `<link>` tag for Google's Font API inclusion, this the code I would use.

```
function mytheme_preprocess_html(&$variables) {
  if ($variables['language']->language == 'en') {
    // The page is using English.
    $element = array(
      '#tag' => 'link',
      '#attributes' => array(
        'href' => 'http://fonts.googleapis.com/css?family=Cardo&subset=latin',
        'rel' => 'stylesheet',
        'type' => 'text/css',
      ),
    );
    drupal_add_html_head($element, 'google_font_cardo');
  }
}

```

This would add `<link href="http://fonts.googleapis.com/css?family=Cardo&subset=latin" rel="stylesheet" type="text/css" />` inside the `<head>` tag when the language used for the page is English.
> 1 votes

# Answer
There's a number of ways you can do this, but I would look into creating a custom block. Your logic that acts on the language would be in the block's output code, and you'd simply use the Block Manager to put it in the correct place in the header. This is a blog I've used before which should be useful (I'm not the author)

http://redcrackle.com/blog/how-create-block-drupal-7

In the tutorial where you see this line:

```
$block['content'] = t('Hello World!');

```

You'd instead call a function that returns the content as applicable based on the language.
> 0 votes

---
Tags: theming
---


# Question
Title: Prevent sites from receiving modules installed by other sites in a multi-site instance
Can I prevent a site from receiving modules installed by a different site in a multi-site instance? In other words, can site A in a multi-site instance not receive a module installed by site B?

* I am aware that in a multi-site instance, modules that are installed for one site is installed for other sites. For other sites to use said module, it must be enabled in its respective site. In my scenario, I do not want a module to appear at all for a given site, even if it was installed by a different site.
* I am aware that configuration can take place to install site-specific modules. My question is the reverse: preventing modules for a specific site rather than installing modules for a specific site.

# Answer
Yes, the multisite system can do that out of the box. From the *Site-specific modules and themes* section of the multisite docs:

> Each site configuration can have its own site-specific modules and themes in addition to those installed in the standard 'modules' and 'themes' directories. To use site-specific modules or themes, simply create a 'modules' or 'themes' directory within the site configuration directory. For example, if sub.example.com has a custom theme and a custom module that should not be accessible to other sites, the setup would look like this:
>
> sites/sub.example.com/settings.php
> sites/sub.example.com/themes/custom\_theme
> sites/sub.example.com/modules/custom\_module

So just make sure you don't put modules that shouldn't be shared in /sites/all/modules; put them in /sites/SITE/modules instead.

> Can site A can "block" (for lack of a better term) a module installed by site B, in which site B installs to sites/all/modules?

You could implement `hook_system_info_alter` in site-exclusive modules to prevent certain ones from ever being displayed to the user on those sites, but as there's no record anywhere of what site downloaded/installed a module to /sites/all/modules, you'd have to keep those modules up to date manually. Unless you supplement that with an API exposed from each site that let each other site know what it had installed and what should/shouldn't be available to install.

> Is best practice to configure specific modules per site rather than trying to prevent the transposition?

I think it's fair to say an inclusive rather than exclusive approach is better practice here, any other approach is a bit awkward. It gets more complicated the more automated/robust you want an exclusive approach to be, whereas doing it the other way round just works.
> 1 votes

---
Tags: 7, multi-sites
---


# Question
Title: How to deal with 'internal:' in your link->uri?
I have a link field, which I can populate with both internal and external links:

> /node/123

I'm building an API that parses the node and returns the URL from the link field:

`$node->my_field->uri`

Which returns `internal:/node/123` which makes this URL useless.

If I try using `use Drupal\Core\Url;` and `Url::fromUri($node->my_field->uri)`, I get a 500 error!

So what is the correct approach for getting a formatted URL, that can parse both internal and external links?

# Answer
> 2 votes
just kidding. To help future devs with this issue, check the logs \*duh and you'll see this:

> PHP message: Uncaught PHP Exception InvalidArgumentException: "The URI '' is invalid.

So, check for the uri value first!

`$node->my_field->uri ? Url::fromUri($node->my_field->uri)->toString() : null,`

---
Tags: 8, navigation
---


# Question
Title: Possible to turn off Twig debug mode for a specific template?
I have overridden a Twig template for an image field, which uses Image URL Formatter in order to remove the surrounding Div's.

Here is my Twig template for the field (`field--media--field-image--image.twig.html`):

```
{% for item in items %}
    {{ item.content }}
    {% if loop.length > 1 and not loop.last  %}
        {{ ', ' }}
    {% endif %}
{% endfor %}

```

The field is output to the src tag in the Twig template for my Media Bundle (`media--image.twig.html`):

```
<div class="allstar-image-wrap">
    {% if href is not empty %}
        <a {{ href }} {{ target }}>
    {% endif %}
        <img src="{{ content.field_image }}" {{ alt }} {{ title }} />
    {% if href is not empty %}
        </a>
    {% endif %}
</div>

```

However, the twig debug information outputs as part of the image URL:

Is there any way to turn off twig debug for a specific template? Or any other way around this?

# Answer
> 3 votes
For my use case, which was a to add a background image to a div, I needed to add spaceless, escape, and striptags as depicted here:

```
<div class="videoPoster js-videoPoster" style="background-image:url('{% spaceless %}{{ img_url|escape|striptags('<!-- -->') }}{% endspaceless %}');">Hello World</div>

```

# Answer
> 7 votes
There is also this alternative found here and here where you can do something like this using the triple filter `|render|striptags|trim` :

```
<img src="{{ url_image }}" alt="{{ title|render|striptags|trim }}" />

```

It worked perfectly in my case (`|escape` didn't work)

# Answer
> 0 votes
This is more of a workaround than a solution but I decided to grab the image URL from a preprocess function and pass to my Twig template for the media bundle (`media--image.twig.html`). This circumvents the need for overriding the image field template.

**mytheme.theme**

```
/**
 * Implements hook_preprocess_media().
 */
function mytheme_preprocess_media(&$variables) {
  $media = $variables['elements']['#media'];

  if($media->bundle() == 'image') {
    $image = $media->get('field_image')->getValue();

    if(isset($image[0]['target_id'])) {
      // Load the file entity object.
      $imageObject = entity_load('file', $image[0]['target_id']);
      $variables['image_url'] = $imageObject->url();
    }
  }
}

```

**media--image.twig.html**

```
{# Build the markup. #}
<div class="allstar-image-wrap">
    {% if href is not empty %}
        <a {{ href }} {{ target }}>
    {% endif %}
        <img src="{{ image_url }}" {{ alt }} {{ title }} />
    {% if href is not empty %}
        </a>
    {% endif %}
</div>

```

# Answer
> 0 votes
I had the same problem with the `title` var used for the `alt` attribute of an image:

`<img src="{{ url_image }}" alt="{{ title }}" />`

I finally used the `escape` filter like this:

`<img src="{{ url_image }}" alt="{{ title|escape }}" />`

or shorter:

`<img src="{{ url_image }}" alt="{{ title|e }}" />`

*(`url_image` is a custom var)*

# Answer
> 0 votes
Another solution uses the Twig Clean Debug module:

> Provides a filter for use in twig templates to clean away twig debugging output (mostly html comments describing template suggestions etc).
>
> When in twig debug mode the html comments can interfere with development. This filter cleans away the suggestions using regex.
>
> Usage Must be used in conjunction with the |raw filter otherwise output will be double escaped, e.g.:
>
> {{ content.field\_image|clean\_debug|raw }}
>
> Warning: this will throw an exeption if the site is not in twig debug mode.

---
Tags: theming, 8
---


title: Display nodes even if it untranslated

text:
# Question
Title: Display nodes even if it untranslated
I've using default translate module. I enabled 2 languages, setted translation in nodetype. So now if i will setup view like this:

It will display only translated nodes. If I set all languages, it will show all nodes, but with duplicates (first and second languages).

How to set in this way: display translated nodes, but if some are not translated, display untranslated?

# Answer
> 5 votes
The trick is the combination of two things:

1. Instead of translation language, use the filter "Default translation", so that you only get the original/default/source translation for each node.
2. Then, in Language below Pager, for "Rendering Language", select "Interface text language selected for page". That will select the best available translation for the current language, just like accessing node/1.

---
Tags: views, 8
---


title: Add a field in node metadata

text:
# Question
Title: Add a field in node metadata
I am trying to make a module that has two parts:

> 1) It calls an API when article is set to published. The API returns a work id.
>
> 2) The workid must be saved to the articles metadata or something similar so that another function uses that id to display specific html in that article.

I am done with the first part. Now I want to know how to save workid in the metadata, is there any option for that in drupal? because I have done this kind of work in joomla.

# Answer
> 1 votes
There no such thing as "node metadata", there are just fields.

So the easiest thing to do is to create a field (in the UI for example, you can then also export the configuration into your module), field\_work\_id or something, and in put in there with `$node->set('field_work_id', $work_id)`.

You can do that in `hook_node_presave()`, but then you might not have an node ID yet for a node that is just being created and is already published. You could also use `hook_node_insert()`/`hook_node_update()`, but then you need resave the node and make sure you don't trigger a loop.

You can also save the work ID in your own table, or you can store the node together with the work ID in a way that allows you to do a lookup with a query.

---
Tags: 8, nodes, meta-tags
---


# Question
Title: drupal login not working offline because of reCAPTCHA
I have installed a drupal site completely offline on my local machine I have it running on mysql and apache2. When I got to the localhost/user/login to edit changes because I want to do it on my machine and not on the actual site. I get a recaptcha error because the site key isn't registered for localhost. Is there anyway I can bypass recaptcha so I can login and make changes?

Thank you

edit: As suggested below I have tried using drush when I run the drush pmu recaptcha command I get the below error:

```
The drush command 'pmu recaptcha' could not be found.  Run `drush cache-clear drush` to clear the commandfile cache if you have installed new extensions

```

I have tried running:

```
sudo drush cache-clear drush

```

as they suggest but it does nothing.

# Answer
uninstall recaptcha, can easily be done with drush

```
cd path/to/project
drush pmu recaptcha

```

drush is a command line utility for drupal and can be easily installed following this guide's setup drush section I can't backup my website on a shared server because memory runs out. What can I do?
> 0 votes

---
Tags: database
---


title: How to group fields in views

text:
# Question
Title: How to group fields in views
Newbie here!

I have created a view with some fields and i want to group some of the fields in one wrapper and remaining in another wrapper and also want to change the structure i.e. adding own wrappers and classes.

Thanks.

# Answer
To add and then group fields in views, you can do the following (if not using a view mode/template).

1. Add all the fields you need, and mark each of them "Exclude from display".
2. Add another field of type 'Custom text'. DO NOT exclude this one.
3. Click on the 'Custom text' field to open its options.
4. Inside the textarea there, you can input custom html using the tokens from the fields above to populate it. You can find the values you'll need for replacement if you click on the "Replacement patterns" dropdown just below the textarea.
> 7 votes

# Answer
You don't need templates for grouping fields in views. If you have other question, please provide more details.

Example:

Add the fields Title and Changed, hide Title by checking "Exclude from display". Go in the last field of the group Changed, open REWRITE RESULTS, check "Override the output of this field with custom text" and put in the text box:

```
<div class="myclass">{{ title }} was changed at {{ changed }}</div>

```

This is the result:

> *Title* was changed at 08/18/2016 - 13:50
> 3 votes

# Answer
If you want to use a twig template instead of rewriting the results in a view, you just need to:

1. Figure out what template you need to override by using the debug setting in settings.php and looking at the HTML code for the template name.
2. Create a copy of the template in your custom theme, and perhaps rename it according to the template naming conventions, for example `views-view-fields--our_team--page_1.html.twig`, where `our_team` is the machine name of the view and `page_1` is the display machine name.
3. Edit the template as needed. You may want to use Devel and kint() to figure out what variables you have to work with. One example might be `{{ fields.field_staff_photo.content }}` but that will change depending on the names of your fields.

Using the rewrite results option in a view is probably quicker and clearer to work with, but if you want to keep all your markup in files, that could be a good reason to go with a template.
> 2 votes

# Answer
If anyone is just looking to group results from a Drupal view **by a field**, here are answers from a similar thread. I often use the top answer there when I have categorical data to organize.
> 1 votes

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


# Question
Title: How to install new drupal packages on local apache server
I have a drupal site set up on a local mysql and a local apache server. I am trying to install a new module the problem is it brings me to the login for server ftp. I'm not sure what credentials it wants or how to do it exactly is there some way to enable apache ftp or what am I supppsed to be doing.

Thank you for any help.

# Answer
Looks like this is a permission issue. You might want to make `sites` directory owned by the apache user and the themes or modules folder is writable as well.

```
$ chown -R www-data sites # Change owner sites directory

```

If that doesn't work, you might try setting modules and theme dir writable.

```
$ chmod -R 777 sites/all

```

Ref: https://www.drupal.org/forum/support/post-installation/2011-01-22/module-installation-requires-ftp-access
> 0 votes

---
Tags: installation
---


# Question
Title: Highlight Field Errors with an Ajax Form
I'm using a number of Ajax form, and while the I can get the error validation to work, and present the error message using the following:

```
  if (null !== form_get_errors()):
    return array(
      '#type' => 'ajax',
      '#commands' => array(
        ajax_command_remove('.alert-dismissable'),
        ajax_command_prepend('#myErrorDiv', theme('status_messages')),
      ),
    );
  endif;

```

However, I am unsure how to highlight the specific fields (usually done by adding a 'error' class to the form item.)

What the best way to achieve this, or is there a better way to handle the form errors that does not take over the normal error highlighting and message display?

# Answer
Not as hard as I thought, but for anyone else trying to solve the same issue, you need to get all the relevant fields from `form_get_errors()` and add the `error` class to the same - note I also clear the previous errors:

```
if (null !== form_get_errors()):
  $commands[] = ajax_command_invoke('#myFormDiv .form-item.error', 'removeClass', array('error'));
  $commands[] = ajax_command_remove('.alert-dismissable');
  $commands[] = ajax_command_prepend('#myErrorDiv', theme('status_messages'));
  foreach (form_get_errors() as $field => $message) :
    $commands[] = ajax_command_invoke('.form-item-'.$field, 'addClass', array('error'));
  endforeach;
  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
endif;

```

Note that your `$field` will be dependent in what you've set in your validation function, so you might need to do some funky things to make sure `'.form-item-'.$field` is finding the right div.
> 1 votes

---
Tags: forms, ajax
---


# Question
Title: Adding multiple users to a field using user/autocomplete
I have the following code to add a field to my custom module to add in users. But I can only add in one user using the user/autocomplete feature.

```
$form['usershare'] = array(
  '#title' => t('Share Collection with:'),
  '#type' => 'textfield',
  '#autocomplete_path' => 'user/autocomplete'
);

```

How do I enable multiple users? These users should be separated by a comma on the back end for me to process it.

# Answer
> 1 votes
as @Geat said:

Your form should be like below.

```
    $form['usershare'] = array(
      '#title' => t('Share Collection with:'),
      '#type' => 'textfield',
      '#autocomplete_path' => 'user/autocomplete',
      '#multiple' => TRUE,
    );

    // Implemenbts hook_menu() for user/autocomplete path.
    function module_name_menu() {
      $items['user/autocomplete'] = array(
        'page callback' => '_user_autocomplete',
        'access arguments' => array('access user autocomplete'),
        'type' => MENU_CALLBACK
      );
      return $items;
    }

    // Implements callback function to get users in autocomplete with comma seperated
    function _user_autocomplete($string) {
      if ($string) {
        $items = array_map('trim', explode(',', $string));
        $last_item = array_pop($items);
        $prefix = implode(', ', $items);
        $result = db_select('users')->fields('users', array('name'))->condition('name', '%' . db_like($last_item) . '%', 'LIKE')->range(0, 10)->execute();
        foreach ($result as $user) {
          $value = !empty($prefix) ? $prefix . ', ' . $user->name : $user->name;
          $matches[$value] = check_plain($value);
        }
      }
    // return output in JSON format.
    drupal_json_output($matches);
}

```

---
Tags: 7, entities, users
---