# Question
Title: Protecting original images (D7, watermark, imagecache)
My goal is to have watermarked images and protected originals for a node image field in D7.

How to add a watermark to images has already been explained: add watermark to all images uploaded in the site

What I'm missing is how to protect the original images! These are still available via direct url.

Someone solved the problem for D5: http://drupal.org/node/424068 but the mentioned rights are not present in D7 anymore.

An other approach is presented in the comments of this page: http://drupal.org/documentation/modules/file

* Create a private filesystem
* Change the field's filesystem to the private one
* Use the content access module to protect the node (a), or
* create a custom module and use the file\_download() hook to prevent access (b).

Possibility (a) doesn't work for me as I don't want to protect the access to nodes, but only to the plain original image files. Possibility (b) hides the imagecached images as well.

# Answer
You can try using an .htaccess to protect the directory containing the original images as mentioned at http://drupal.org/node/424068#comment-3149994
> 5 votes

# Answer
You can write an API that retrieves images, via the Services module, and then in the "src" attribute of your image tags, as well as the URL for images in your CSS, you use an image retrieving API call. If you use the REST Server, then your image API calls look pretty much like any other url, just lacking an extension.

In your image API routine written in the Services framework, you capture all image requests and are able to get images from outside your web root. Just set your open\_basedir so your php can reach outside of the web root, and the images are totally protected. Only your API call can retrieve them.

An interesting benefit of this is that you can optionally require image requests to include authentication. When a user is logged into a Drupal site, any API references in their page markup automatically carries their authenticated status, and your API routine will serve the images to the page being viewed by that user. However, if someone were to copy an image link and post that somewhere, the image won't load because that web page over there does not carry authenticated status for your site, and your API routine does not even get called because it failed authentication. Nifty. :)

(Also, to make it harder for people to even link to your images, embed them as a background image to a div in your CSS. That way, the user has to 'view source' and hunt down your image API call, because a context-menu click will not "show image".)

I use this API for images technique on a few sites, and it works quite well. In my image API, the REST API call looks like:

```
  www.mysite.com/api_version/imageContainerName/fileId/imageCachePreset

```

Which gives me contol to have different API versions for testing, different image containers for different user roles, and finally any image cache preset already defined.
> 1 votes

# Answer
This is an issue that you no doubt have spent a lot of time on and we have looked into it also. Its a very difficult issue. The problem is that you are serving a web page, and cannot avoid the fact that the images and content on the page are downloaded into a visitor's /temp folder when they visit your web page. Using firebug to inspect the DOM of your site can be a good way to understand the challenge of the exercise, when you see the way in which the component parts of a web page are downloadable.

You say you will have watermarked images, which is what you want, but will this present the right impression to visitors. For our designs, we felt it wouldn't.

Also anyone can simply press the 'print-screen' button and they have a copy of your image.

We've looked at this issue also and have sought the advice of others, many of whom said its impossible to prevent people copying your images, however you can make it difficult for them. There is some Javascript that prevents users right clicking on images then choosing 'download', but the general consensus is that this is very irritating for the visitor. And a determined person will just use something like Firebug/Inspector to get past this.

When we create image nodes that are used elsewhere, say in a view, we redirect the URL of the image node to the page with the view, in any event the image node is not normally used as a page. We also make sure that any thumbnails do not link through to the full image node, thereby avoiding a redirect loop. In this way you prevent the full image node from being accessed using URL Redirects.

Regards,
> 0 votes

# Answer
This is an answer attempt and doesn't work. I just put it here as a reference.

The cached image styles of private images are saved in the private filesystem as well in a "style" subfolder. Therefore in the file\_download one must check if an original image is requested or an image style. The fast way (could be made more elegantly by adding some permission checks as in http://drupal.org/documentation/modules/file#comment-4104464):

```
function modulename_file_download($uri) {
    if (substr($uri, 0, 17) ==  'private://styles/') {
        return 1;
    } else {
        return -1;
    }
}

```

The problem with this solution is that drupal first checks whether the original can be downloaded (which is not the case) and if not it directly forbids access to the cached styled image as well, without using this function. Somehow drupal doesn't want you to make only styled images accessible to the public :s
> 0 votes

# Answer
I just ran into this on Pantheon and am not sure if it is the same for all setups (they use Nginx) but what is working for me is is to set the imagefield path to private but set the download method to public. This way it actually puts the image file in the private protected directory but Drupal does not try to intercept the path request when the original image is requested. This means the protected directory permissions will work as they should. This is a fragile approach but it works and still lets imagestyles (imagecache) do it's work.

If you do this you can never link to the original image in "manage display" which is what you want of course but just so you don't think something is broken, remember to set an image style.
> 0 votes

# Answer
1. Use subfolder in path for images you want to protect (configurable per-field in image field settings) eg "protected" so your uploaded images will land in "sites/\[default\]/files/protected" directory.
2. Put regular Drupal's private path .htaccess within that directory:

> ```
> # Deny all requests from Apache 2.4+.
> <IfModule mod_authz_core.c>
>   Require all denied
> </IfModule>
>
> # Deny all requests from Apache 2.0-2.2.
> <IfModule !mod_authz_core.c>
>   Deny from all
> </IfModule>
>
> # Turn off all options we don't need.
> Options None
> Options +FollowSymLinks
>
> # Set the catch-all handler to prevent scripts from being executed.
> SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
> <Files *>
>   # Override the handler again if we're run later in the evaluation list.
>   SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
> </Files>
>
> # If we know how to do it safely, disable the PHP engine entirely.
> <IfModule mod_php5.c>
>   php_flag engine off
> </IfModule>
>
> ```
3. Users are still able to access images through styled directory eg. "sites/default/styles/protected/1.jpg" but won't be able to access original files.
> 0 votes

---
Tags: 7, media
---


title: Add cache context to altered links

text:
# Question
Title: Add cache context to altered links
I am using hook\_link\_alter(&$variables) to alter links depending on the user's role. I'm doing this for links in the main menu as well as for custom links shown on entities. This works good except caching. If I change a user's role still the previous behaviour of the altered links is shown. If I clear all caches, it works fine again.

I thought of adding cache context user.roles. But hook\_link\_alter seems not to support to add caching meta data to $variables see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21menu.api.php/function/hook\_link\_alter/8.5.x. (Or I'm doing it wrong.)

What can I do to make caching of my altered links aware of the user's roles?

My code looks like in hook\_link\_alter(&$variables)

```
$roles = \Drupal::currentUser()->getRoles();

if(!in_array('member_gold', $roles)) {

  $url = $variables['url'];

  if (($url->isRouted() && $url->getRouteName() === 'view.my_content.page') OR ... ) {

    $url = Url::fromRoute('myModule.ajax_callback', ['op' => 'do_action']);
    $token = \Drupal::service('csrf_token')->get($url->getInternalPath());

    $variables['url'] = $url;
    $variables['options']['query']['token'] = $token;
    $variables['options']['attributes']['class'][] = 'use-ajax';

  }

}

```

## **Update:**

The links that I alter are in a) the main menu, b) in pseudo fields and c) by other modules. I succeeded adding some cache context to a) and b) and skipped c). It seems to work, but I don't know why, it was more or less trial and error:

For the menu links: function mymodule\_preprocess\_menu(&$variables) {

```
if(isset($variables['menu_name']) && $variables['menu_name'] == 'main') {

  $variables['#cache']['contexts'][] = 'user.roles';
  $renderer = \Drupal::service('renderer');
  $renderer->addCacheableDependency($variables, \Drupal\user\Entity\User::load(\Drupal::currentUser()->id()));
}

```

In my pseudo fields:

```
$build['action_my_action'] = [
    ...
    '#cache' => [
      'contexts' => ['user.roles'],
    ],
  ];

  $renderer = \Drupal::service('renderer');
  $renderer->addCacheableDependency($build, \Drupal\user\Entity\User::load(\Drupal::currentUser()->id()));

```

I don't understand why this works. I initially only tried adding the cache context, but this did not work. Only if I add the dependency to the current user. However I don't know whether this is correct, as I don't want to vary by user but by role.

Would be great if someone can explain me if this is right and why it works?

# Answer
Since you can't have the role sensitivity reliably in the links themselves, I'd tackle this differently by using an intermediary routing function.

So if you have a link you want to point to `mypath/role_1`, `mypath/role_2` etc, you might point it to `role_route/somekey` defined in `mymodule.routing.yml` like so:

```
mymodule.role_route:
 path: 'role_route/{key}'
 defaults:
  _controller: '\Drupal\mymodule\Controller\RoleRouteController::route'
 requirements:
   _permission: 'access role paths'

```

The `route` function of the controller might be something like:

```
function route($key) {
  $current_user = \Drupal::currentUser();
  $roles = $current_user->getRoles();
  // logic to process roles and key to get wanted route
  ...
  $role_route_name = ... ;
  return new RedirectResponse( Url::fromRoute($role_route_name);
}

```
> 1 votes

# Answer
You need to add the cache context to the actual element's render array, not to the overall $variables array. So you need something like:

```
$variables['my_link_element']['#cache']['contexts'] = ['user.role'];

```

Instead of what you're currently doing now which I'm guessing is something like:

```
$variables['#cache']['contexts'] = ['user.role'];

```
> 0 votes

---
Tags: 8, caching
---


# Question
Title: Performing an HTML substitution from AjaxResponse rather than using a wrapper
I have an autocomplete textfield whose autocomplete\_route\_parameters is updated on the `onChange` event of a textfield, which is filled by a jQuery UI datepicker. Everything works, but after the update of the list the datepicker, which was closed after the selection of the date, shows up again. So I thought, well, I'll just use jquery to close it again.

This means that the ajax callback cannot simply return a renderable array, but rather an `AjaxResponse`; the problem is that I don't understand how to use a form element inside a `ReplaceCommand`. If before the change I had

```
function seduta_senato_form_datetime_changed(array &$form, FormStateInterface $form_state) {
  return $form['struttura-input'] ;
}

```

now I should say something along the lines of

```
function seduta_senato_form_datetime_changed(array &$form, FormStateInterface $form_state) {
  $response = new AjaxResponse() ;
  $response
  ->addCommand(new ReplaceCommand('#ajax-wrapper', "<div id='ajax-wrapper'>" . $form['struttura-input']->??? . '</div>'))
  return $response ;
}

```

but the form element has to be rendered somehow, otherwise it will simply appear in the HTML as Array.

I thought this would be simple, since for sure the functionality that renders the changed element is already there, but the research I made gave me only rather intricate solutions. Any help or hint would be greatly appreciated!

# Answer
So, I *used the source*, and I found out that `Drupal\Core\Ajax\ReplaceCommand` calls `getRenderedContent()`, I found an implementation in `CommandWithAttachedAssetsTrait` where I saw that it expects an array, as I should have well known. So I ended up with the following calls:

```
$response
  ->addCommand(new RemoveCommand('label[for^="edit-struttura-input"]'))
  ->addCommand(new ReplaceCommand('input[id^="edit-struttura-input"]', array( $form['struttura-input'] )))
  ->addCommand(new InvokeCommand('#edit-field-next-field-to-edit', 'focus')  )

```

Note that I removed the wrapper, as suggested by @4k4, but then I had to select on a match on the start of the ID of the element, and to remove the label, since it is added by each new rendering. As a command to get rid of the datepicker I simply moved the focus to the next element to edit, which is very convenient to the user.
> 0 votes

---
Tags: ajax
---


title: I can't find product types UI

text:
# Question
Title: I can't find product types UI
I'm trying to add a new product type, but I can't find the tab for the product types.

In Manage product structure, it is very clear where that tab is, but I cannot find it.

I'm using Drupal 7.59 and Commerce Kickstart 2 with demo.

# Answer
> 0 votes
https://docs.drupalcommerce.org/commerce2/user-guide/products/manage-product-structure contains documentation for Commerce 2.x, which is based on Drupal 8.

You're using Drupal 7, which is Commerce 1.x, so you need to find and follow the Drupal 7 documentation. That should be as simple as clicking "Commerce 1.x" in the left-hand navigation panel.

---
Tags: commerce
---


title: Trigger on selected field change

text:
# Question
Title: Trigger on selected field change
So I have a Drupal 7 Workflow rule where an email is sent out when a select field on a comment is set to "Approved'.

This works fine with the exception being if I then add an additional comment to the form, the email is then re-sent. the reason being is that I'm just checking the select field value and triggering the email based on the value.

I just want the email to be sent when the select field is initially set to "Approved".

Here is the export of the rule in question:

```
{ "rules_notify_status_approved_test" : {
"LABEL" : "Notify - Status Approved TEST",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"ON" : { "node_update--request_ad_match" : { "bundle" : "request_ad_match" }     },
"IF" : [
  { "node_is_of_type" : {
      "node" : [ "node" ],
      "type" : { "value" : { "request_ad_match" : "request_ad_match" } }
    }
  },
  { "user_has_role" : {
      "account" : [ "site:current-user" ],
      "roles" : { "value" : { "4" : "4" } }
    }
  },
  { "data_is" : { "data" : [ "node:field-request-status" ], "value" : "74" }     },
  { "AND" : [] }
],
"DO" : [
  { "variable_add" : {
      "USING" : { "type" : "user", "value" : [ "node:author" ] },
      "PROVIDE" : { "variable_added" : { "node_author" : "node author" } }
    }
  },
  { "mail" : {
      "to" : "email@email.com",
      "subject" : "request has been approved",
      "message" : "request has been approved",
      "language" : [ "" ]
    }
  }
]
}
}

```

Any direction is appreciated.

Thanks!

# Answer
> 1 votes
It seems that to get it to work, you should at least add yet another Rules Conditions, in which you compare the value of your `field-request-status` field, for both the original value (before editing the field) and the (new) updated value, to verify if they are different.

For a variation of your question, with way more details on this, refer to the accepted answer (disclosure: it's mine ...) to "How to send an email using Rules when a node's boolean field is changed?".

---
Tags: 7, rules, workflows
---


title: Disable blocks for certain pages

text:
# Question
Title: Disable blocks for certain pages
How can I disable blocks (e.g., the menu block or the search block) from a custom module?

Concretely I have an access to my clients managed by a custom module, and I don't want anything appears on their access page except my company's logo.

# Answer
> 2 votes
If you don't want to install another module to achieve this you might want to disable blocks in `hook_preprocess_page` similar to this

```
function THEMENAME_preprocess_page(&$vars) {
  if ( /* custom logic */ ) {
    unset($vars['page']['REGION-NAME']['BLOCK-MACHINE-NAME']);
  }
}

```

It can certainly be used in your THEMENAME.theme file but I believe it can be used in a module as well

# Answer
> 1 votes
If you want to change the visibility of many blocks at the same time, this module would be perfect:

https://www.drupal.org/project/block\_visibility\_groups

> Block Visibility Groups allows the site administrator to easily manage complex visibility settings that apply to any block placed in a visibility group. The visibility settings for all blocks in the group can be edited on one administration form.
>
> This modules works in conjunction with the Drupal 8 core's block administration system. It is a simpler alternative to modules like Panels.

Even you want to code this yourself, you can use this module as a starting point. The author of this module has a 2 hour video how this code was built.

# Answer
> 0 votes
You can try to specify pages in visibility option field in block settings. Or try to use https://www.drupal.org/project/extended\_block\_visibility if you need specific access rules which placed in custom module

# Answer
> 0 votes
I've used hook\_block\_view() to do something like this. I defined conditions for my block to appear in the function. My block was a form, so I could assign $blocks\['content'\] to a drupal\_get\_form() call, and return my $blocks if my conditions were met.

---
Tags: 8
---


# Question
Title: How can I set a custom CKEditor on only one field?
I'm using Drupal 8.

I have a field that can only allow for specific styles, so I created a custom CKEditor and set the field to use it.

Now when I go to the field on the content edit form, I see the custom editor as the default, as well as a select menu to specify which editor I want to use to enter content.

When editing this field, I do not want to show any other editor options and I only want the editor to be used for this field.

What is the best way to implement this functionality?

# Answer
> 1 votes
The Allowed Formats does this (and nothing else). And has a stable release for D8 :)

# Answer
> 1 votes
I believe the module you want to add is Better Formats. This will let you specify format options for a field, if you only want to show one (even if the role has access to multiple).

Edit, because it is not clear from the project page:

```
composer require drupal/better_formats:1.x-dev

```

---
Tags: nodes, forms, wysiwyg
---


title: Page region CSS class not applied

text:
# Question
Title: Page region CSS class not applied
I am working with Drupal 8.5-x, I am trying to render HTML with bootstrap classes, but I am having trouble. Here is my problem:

I have highlighted (region) and content (region). I am trying to add a `<section class="col-sm-12 col-md-12">` with highlighted region but to no avail.

I have:

```
{# Highlighted #}
  {%
    set highlighted_classes = [
      page.sidebar_first and page.sidebar_second ? 'col-sm-6',
      page.sidebar_first and page.sidebar_second is empty ? 'col-sm-9 col-md-8',
      page.sidebar_second and page.sidebar_first is empty ? 'col-sm-12',
      page.sidebar_first is empty and page.sidebar_second is empty ? 'col-sm-12'
    ]
  %}

{# Content #}
  {%
    set content_classes = [
      page.sidebar_first and page.sidebar_second ? 'col-sm-6',
      page.sidebar_first and page.sidebar_second is empty ? 'col-sm-12 col-md-12',
      page.sidebar_second and page.sidebar_first is empty ? 'col-sm-12',
      page.sidebar_first is empty and page.sidebar_second is empty ? 'col-sm-12'
    ]
  %}

  <section {{ highlighted_attributes.addClass(highlighted_classes) }}>
  <section {{ content_attributes.addClass(content_classes) }}>

```

when rendered, I get

```
<section>
<section class="col-sm-12 col-md-12>

```

but I was expecting

```
<section class="col-sm-12 col-md-12">
<section class="col-sm-12 col-md-12">

```

I am lost as to where I could have gone wrong. My info file is as follows:

```
    regions:
  navigation: 'Navigation'
  navigation_collapsible: 'Navigation (Collapsible)'
  header: 'Top Bar'
  highlighted: 'Highlighted'
  help: 'Help'
  content: 'Content'
  sidebar_first: 'Primary'
  sidebar_second: 'Secondary'
  footer_first: 'First Footer'
  footer_second: 'Second Footer'
  footer_third: 'Third Footer'
  footer_fourth: 'Fourth Footer'
  footer_fifth: 'Fifth Footer'
  page_top: 'Page top'
  page_bottom: 'Page bottom'

```

Any help?

# Answer
Nevermind I read on attributes: https://www.drupal.org/docs/8/theming-drupal-8/using-attributes-in-templates

The attribute I was referencing 'highlighted\_attributes' was blank. I just added a simpler solution, by referecing to the example of the API:

```
{% set classes = [ 'red', 'green', 'blue' ] %}

<div{{ attributes.addClass(classes) }}></div>

```
> 1 votes

---
Tags: theming
---


# Question
Title: How to access session variables in Twig template?
In a custom module I specified in the `hook_preprocess_page` function the following session variable:

```
if (isset($blockNameState) && $blockNameState == 'open') {
   $tempstore->set($blockNameState, 'close');
}
else {
   $tempstore->set($blockNameState, 'open');
}

```

Let's assume the above code ran with `$blockNameState = 'block1_state'` and there is key/value pair 'block1\_state/open' in the `$tempstore`.

How do I access the key/value pair in a Twig template?

Can't run the following PHP command in Twig:

```
$blockNameState = $tempstore->get($blockNameState);

```

# Answer
You can inject new variables into templates by using the appropriate preprocess hook in your theme:

```
function mytheme_preprocess_page(&$variables) {
  // code to get value...
  $variables['myvariable'] = $value;
}

```

Then in the corresponding template:

`{{ myvariable }}`

You might have caching issues with this though.
> 1 votes

---
Tags: theming, sessions
---


# Question
Title: Rules: use a View's result as a condition?
How can I use the results of a view as a condition in a rule?

I have rule that fires off a *daily digest* email with contents from a view (using Views Rules). The view simply returns nodes that have a specific field value. When the view doesn't return any nodes, the rule still fires off what is essentially an empty email. I want to prevent this. I need a condition like "View has no results" (negated)… but I don't see anything like that. What's the workaround?

# Answer
> 1 votes
Even though your own answer is indeed a way to solve your question, it doesn't say that for this to work, it requires the Conditional Rules module to be enabled (without that, you cannot add a Rules Condition as an extra rules Action).

An alternative solution to solve your question, is to use the Views Bulk Operations (VBO) module to transform your view into a VBO view, so that you can use a Rules Condition "***Check number of results returned by a VBO View***" in which you can perfectly construct the Rules Condition you're looking for.

Have a look at "this answer" for an illustration of how this specific Rules Condition is used.

PS: I'm assuming this question is about D7.

# Answer
> 0 votes
I was eventually able to pull this off by adding a condition to the *Actions* section, as opposed to the (more logical) *Conditions* section. Here's what I did:

1. Added a *conditional* to the Actions section
2. Added an *if* to the conditional
3. Added the *Data value is empty* condition and negated it
4. The *Data to check* is one of the fields from my view, in my case `[created:0]`
5. Added the action (in my case, *Send mail to all users of a role*) and nested it under this new condition

While this does seem to work, it feels like more of a workaround than a solution. But, hey, if it works, it works. Anyway, I'm open to more direct approaches if they're out there.

---
Tags: views, rules
---


# Question
Title: What is public static function create() in plugins for?
Sometimes I encounter a public static function `create()` in plugin classes, for the example in the code show in Tutorial on Using Drupal 8 Plugin Derivatives Effectively.

```
public static function create(ContainerInterface $container, $base_plugin_id) {
  return new static(
    $container->get('entity.manager')->getStorage('node')
  );
}

```

Could you clarify me what the purpose of that function is, for example what it should do and where it's used?

# Answer
create() is a factory method for dependency injection.

Plugins which implement `ContainerFactoryPluginInterface` are instantiated by `create()` of the plugin class:

*ContainerFactory::createInstance*

```
public function createInstance($plugin_id, array $configuration = []) {
  ...
  // If the plugin provides a factory method, pass the container to it.
  if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
    return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
  }

  // Otherwise, create the plugin directly.
  return new $plugin_class($configuration, $plugin_id, $plugin_definition);
}

```
> 11 votes

# Answer
It's the static method Drupal core uses to create the plugin. (See, for example, the documentation for `SystemMenuBlock::create()`.)

Drupal core doesn't instantiate a plugin with `new PluginClass()`, but `PluginClass::create()`. This allows the class implementing the plugin to return an instance previously created.
The other *pro* is that the signature of the plugin constructors can vary without giving problems to Drupal, which just requires the `create()` method of a class of plugins to always have the same signature.

It is the same pattern used for Drupal services.
> 6 votes

---
Tags: 8, dependency-injection
---


# Question
Title: How to stop users from flagging other users if they have a custom taxonomy term?
I'm working on a project where users vote other users using the Flag module. Each user has a department term reference field. I would like to stop a user from flagging another user if they have the same department. Is it possible? Please help! Thanks in advanced!

# Answer
Finally I managed to solve my problem by creating a Rule. Here are the steps you can follow to achieve this:

1. Create a new Rule and select as the Event "A user has been flagged, under 'your flag'";
2. Add a condition "Entity has field" and select "flagging-user" as the entity and your field as the "Field";
3. Add a new condition "List contains item" and select as a list your created field but it must be like this "flagging-user:field-your-field";
4. Now at the same condition select as the item one of your field value;
5. Add a AND condition;
6. Add two more conditions exactly like you did at step 2, 3 and 4 but change "flagging-user" to "flagged-user".
7. Finally, add an action with "Unflag a User" and select your flag first, then at the User select "flagged-user", at the "User on whose behalf to flag" select "flagging-user" and at "Skip permission check" check "True".

That's it. Hope I helped someone else.

As requested here's an exported code of the actual Rule:

```
{ "rules_nu_poate_vota_manager" : {
"LABEL" : "Nu poate vota manager",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules", "flag" ],
"ON" : { "flag_flagged_apreciere" : [] },
"IF" : [
  { "entity_has_field" : { "entity" : [ "flagging-user" ], "field" : "field_raion" } },
  { "list_contains" : { "list" : [ "flagging-user:field-raion" ], "item" : "18" } },
  { "AND" : [] },
  { "entity_has_field" : { "entity" : [ "flagged-user" ], "field" : "field_raion" } },
  { "list_contains" : { "list" : [ "flagged-user:field-raion" ], "item" : "18" } }
],
"DO" : [
  { "flag_unflaguser" : {
      "flag" : "apreciere",
      "user" : [ "flagged-user" ],
      "flagging_user" : [ "flagging_user" ],
      "permission_check" : "1"
    }
  },
  { "drupal_message" : {
      "message" : "Nu po\u0163i aprecia colegii de echip\u0103!",
      "type" : "warning"
    }
  }
]

```

} }
> 1 votes

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


# Question
Title: Custom field - Object could be converted to string
I have a very simple custom field/widget/formatter set.

**YoutubeLink.php (custom field):**

```
<?php
namespace Drupal\ad_general\Plugin\FIeld\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
/**
 * Defines the 'boolean' entity field type.
 *
 * @FieldType(
 *   id = "youtube",
 *   label = @Translation("Youtube link"),
 *   description = @Translation("Youtube link field."),
 *   default_widget = "youtube_default",
 *   default_formatter = "youtube_default",
 * )
 */
class YoutubeLink extends FieldItemBase {

  public function isEmpty() {
    $value = $this->get('value')->getValue();
    return $value === NULL || $value === '';
  }

  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('string')->setLabel(t('Youtube link'));
    return $properties;
  }

  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return [
      'columns' => [
        'value' => [
          'type' => 'varchar',
          'length' => 255,
        ],
      ],
    ];
  }
}

```

**YoutubeLinkWidget.php (custom widget):**

```
<?php

namespace Drupal\ad_general\Plugin\FIeld\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'text_textarea' widget.
 *
 * @FieldWidget(
 *   id = "youtube_default",
 *   label = @Translation("Youtube default"),
 *   field_types = {
 *     "youtube"
 *   }
 * )
 */
class YoutubeLinkWidget extends WidgetBase {

  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $elements = [];

    $elements['value'] = [
      '#type' => 'textfield',
      '#title' => 'Enter Youtube video link.',
    ];

    return $elements;
  }
}

```

**YoutubeLinkFormatter.php (custom formatter):**

```
<?php

namespace Drupal\ad_general\Plugin\FIeld\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;

/**
 * @FieldFormatter(
 *   id = "youtube_default",
 *   label = @Translation("Youtube link"),
 *   description = @Translation("Display a link to the video."),
 *   field_types = {
 *     "youtube"
 *   }
 * )
 */
class YoutubeLinkFormatter extends FormatterBase {

  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];
    foreach ($items as $delta => $item) {
      $elements[$delta] = [
        '#type' => 'markup',
        '#markup' => $item,
      ];
    }

    return $elements;
  }
}

```

I added this field to a content type. Whenever I want to add new content of this type, I now get the following error:

> Youtube link The website encountered an unexpected error. Please try again later. Recoverable fatal error: Object of class Drupal\ad\_general\Plugin\FIeld\FieldType\YoutubeLink could not be converted to string in Drupal\Component\Utility\Xss::filter() (line 67 of core/lib/Drupal/Component/Utility/Xss.php). Drupal\Component\Utility\Xss::filter(Object, Array) (Line: 753) Drupal\Core\Render\Renderer-\>ensureMarkupIsSafe(Array) (Line: 384) Drupal\Core\Render\Renderer-\>doRender(Array, ) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array) (Line: 490) Drupal\Core\Template\TwigExtension-\>escapeFilter(Object, Array, 'html', NULL, 1) (Line: 128) \__TwigTemplate\_5b03bca200df2d5ba1ca47d2e222b86347639abbdcd0d8d587ebad065efba4c8-\>doDisplay(Array, Array) (Line: 432) Twig\_Template-\>displayWithErrorHandling(Array, Array) (Line: 403) Twig\_Template-\>display(Array) (Line: 411) Twig\_Template-\>render(Array) (Line: 64) twig\_render\_template('core/themes/classy/templates/field/field.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager-\>render('field', Array) (Line: 437) Drupal\Core\Render\Renderer-\>doRender(Array, ) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array) (Line: 490) Drupal\Core\Template\TwigExtension-\>escapeFilter(Object, Array, 'html', NULL, 1) (Line: 87) \__TwigTemplate\_427ceffeef7118469d7753956e2b0d458f0c2f44d3b385e4ec36128cfc86801f-\>block\_content(Array, Array) (Line: 215) Twig\_Template-\>displayBlock('content', Array, Array) (Line: 72) \__TwigTemplate\_427ceffeef7118469d7753956e2b0d458f0c2f44d3b385e4ec36128cfc86801f-\>doDisplay(Array, Array) (Line: 432) Twig\_Template-\>displayWithErrorHandling(Array, Array) (Line: 403) Twig\_Template-\>display(Array) (Line: 411) Twig\_Template-\>render(Array) (Line: 64) twig\_render\_template('core/themes/bartik/templates/block.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager-\>render('block', Array) (Line: 437) Drupal\Core\Render\Renderer-\>doRender(Array) (Line: 450) Drupal\Core\Render\Renderer-\>doRender(Array, ) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array) (Line: 490) Drupal\Core\Template\TwigExtension-\>escapeFilter(Object, Array, 'html', NULL, 1) (Line: 56) \__TwigTemplate\_6bc2c2a4be03937decaa4eb1c0d39af747b44d5c7e30912d8db85c3fa5c28de6-\>doDisplay(Array, Array) (Line: 432) Twig\_Template-\>displayWithErrorHandling(Array, Array) (Line: 403) Twig\_Template-\>display(Array) (Line: 411) Twig\_Template-\>render(Array) (Line: 64) twig\_render\_template('core/themes/stable/templates/layout/layout--onecol.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager-\>render('layout\__onecol', Array) (Line: 437) Drupal\Core\Render\Renderer-\>doRender(Array) (Line: 450) Drupal\Core\Render\Renderer-\>doRender(Array) (Line: 450) Drupal\Core\Render\Renderer-\>doRender(Array, ) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array) (Line: 490) Drupal\Core\Template\TwigExtension-\>escapeFilter(Object, Array, 'html', NULL, 1) (Line: 114) \__TwigTemplate\_4ae59022820823361d314fdb0db03eda142ac3295eb1399a7323e963e3d3bf5a-\>doDisplay(Array, Array) (Line: 432) Twig\_Template-\>displayWithErrorHandling(Array, Array) (Line: 403) Twig\_Template-\>display(Array) (Line: 411) Twig\_Template-\>render(Array) (Line: 64) twig\_render\_template('core/themes/bartik/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager-\>render('node', Array) (Line: 437) Drupal\Core\Render\Renderer-\>doRender(Array, ) (Line: 195) Drupal\Core\Render\Renderer-\>render(Array, ) (Line: 226) Drupal\Core\Render\MainContent\HtmlRenderer-\>Drupal\Core\Render\MainContent{closure}() (Line: 582) Drupal\Core\Render\Renderer-\>executeInRenderContext(Object, Object) (Line: 227) Drupal\Core\Render\MainContent\HtmlRenderer-\>prepare(Array, Object, Object) (Line: 117) Drupal\Core\Render\MainContent\HtmlRenderer-\>renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber-\>onViewRenderArray(Object, 'kernel.view', Object) call\_user\_func(Array, Object, 'kernel.view', Object) (Line: 111) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher-\>dispatch('kernel.view', Object) (Line: 156) Symfony\Component\HttpKernel\HttpKernel-\>handleRaw(Object, 1) (Line: 68) Symfony\Component\HttpKernel\HttpKernel-\>handle(Object, 1, 1) (Line: 57) Drupal\Core\StackMiddleware\Session-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\KernelPreHandle-\>handle(Object, 1, 1) (Line: 99) Drupal\page\_cache\StackMiddleware\PageCache-\>pass(Object, 1, 1) (Line: 78) Drupal\page\_cache\StackMiddleware\PageCache-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\ReverseProxyMiddleware-\>handle(Object, 1, 1) (Line: 52) Drupal\Core\StackMiddleware\NegotiationMiddleware-\>handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel-\>handle(Object, 1, 1) (Line: 666) Drupal\Core\DrupalKernel-\>handle(Object) (Line: 19)

Does anyone have an idea what is causing this issue? Thank you very much for any sort of help.

# Answer
The problem was with the `#markup` property of the formatter - `$item` is indeed just an object, so I had to convert it to a string by using the `getString()` method (as an example).
> 0 votes

---
Tags: plugins
---


title: Message contextual filtering

text:
# Question
Title: Message contextual filtering
I have been trying out the Message module. I am using it to send notifications to users' profiles whenever a node of a certain content type is added (a simple `hook_node_insert()` in combination with `Message::create()`). These notifications are displayed in a view block on the user's profile page (this block is an alteration of the base Message View. Let's say these are nodes whose content type is *Event*, and each of these nodes has a taxonomy term reference field called *Event type* (e.g. Sports, Conference, Concert, etc.).

Let's say that a user only wants to be notified about events for which the value of the *Event type* field is *Concert*. In the user form, I have provided a field which contains checkboxes for all of the different event types (its a list of all of the terms that come from the *Event type* vocabulary). Whenever a user visits their profile page, they should only see notifications for the event types they've selected.

I haven't been able to find a solution for how to implement this either at message creation or through some sort of view block hook. I am now trying to do it through Views filters/relationships.

To make the long story short, my view block contains a list of Message type entities, each with an *event\_type* field that references a single taxonomy term. Every user entity on the page has a *event\_notification\_preferences* field which is basically an array of taxonomy terms selected by the user.

What I would like to do can be explained through an example. Let's say the view contains three messages, each with a different *event\_type* field (Sports, Conference, Concert). The currently logged in user's *event\_notification\_preferences* array contains only one reference (to the Concert term).

How can I filter the view to display only those messages whose *event\_type* field is relevant (i.e., it has a corresponding match in the event\_notification\_preferences array, in this case *Concert*)? Is this possible?

# Answer
> 0 votes
In case it helps someone - I solved the issue by creating a view block of Messages, then I:

* Added a relationship with the Taxonomy term referenced from the *event\_type* field.
* Added a relationship with the User using the *event\_notification\_preferences* field.
* Added a contextual filter for **User: User ID** and got the default value from the currently logged in user.

---
Tags: views, blocks, message-subscribe
---


# Question
Title: Can I target a specific node type in page.tpl.php
I just created a template `page--article.tpl.php` to apply ton nodes of the `[article] type`. It works when declared in the `template.php` file.
My problem is that there is a very slight change compared to the generic `page.tpl.php`, nothing worth having another file.

I was wondering if I could place the adde part between a condition, just as I could do with `if $is_front` Something like:

```
<?php if ($node->type == 'article')
  // render my thingees
?>

```

I would be glad if someone could tell me.

--- Edit, to answer Kiwimind ---

I did the test with the 'page' content type, so I didn't have to skip my `page--article.tpl.php` file. I checked that 'page' was the actual machine name and 'nature' is my theme's actual name, it works on other functions.
I wrote in `template.php`

```
/**
 * Détection du type de contenu pour affecter le template page
 * https://drupal.stackexchange.com/questions/264550/can-i-target-a-specific-node-type-in-page-tpl-php
 */

function nature_preprocess_page(&$variables, $hook) {
  $variables['is_page'] = false;
  if (isset($variables['node']) && $variables['node']->type == 'page') {
    $variables['is_page'] = true;
  }
}

```

Then in `page.tpl.php`

```
<?php if ($is_page) : ?>
    <h1>This is a “page” content</h1>
<?php endif; ?>

```

Nothing more, nothing less. Do you see any missing (or unnecessary) character, that could trigger a parse error? For I still get a whole blank page when clearing the cache.

# Answer
As shown on Variable to check if the page is of some other Content Type, you can drop into template.php something like the following:

```
function THEMENAME_preprocess_page(&$variables, $hook) {
  $variables['print_extra_header'] = false;
  if (isset($variables['node']) && $variables['node']->type == 'product') {
    $variables['print_extra_header'] = true;
  }
}

```

then in your template, add in

```
<?php if ($print_extra_header) : ?> <h1>THIS GETS PRINTED</h1> <?php endif; ?>

```

So effectively you're checking on the node type in a preprocess page, to pass a custom variable to the template for you to act on.
> 3 votes

# Answer
You can set variable as per your condition on your module file and get this variable from your .tpl file after that set your condition.
> 0 votes

---
Tags: 7, theming
---


title: REST for nested paragraphs

text:
# Question
Title: REST for nested paragraphs
I need to create a rest service that delivers the current data:

```
getNode(nid)
-> all node fields
   -> if field is entity reference (like file, human readable urls)
       -> include subfields
   -> if field is type of paragraph, include sub fields again in human readable form

```

It seems that Drupal is not yet ready for Rest without having to create new requests for every peace of content that is referenced with an id.

For example I have a Pinterest wall kind of output. Each item is created by using a paragraph element (sometimes with other references like taxonomy etc)

I want a clean, json list. Structured correctly without missing nested elements like paragraphs, file or taxonomy references. In this moment I just get the id's of the referenced elements.

Do I have to call now 100+ requests to collect all data for this wall?

1) Or should I make one request for collecting the node:

2) Another request to collect all 1st level entity references. Afterwards to store them in an array.

3) Afterwards making request for 2nd level entity references.

This seems horrible to me when it comes to questions about overhead and time.

Of course I have checked out some modules that should help with this issue:

* rest\_export\_nested module which does not work with paragraphs entity types
* rest\_views does seem to output the fields as html instead of json. There is no real solution so far.

So what to do? Another way could be to create a view of paragraphs with target id of \[NODE\_ID\]. But this would work just for 1st level paragraphs. The problem would still exist for nested paragraphs.

Is really the only way to create a custom module that creates it's own rest service?

Is the JSON API maybe another solution I haven't looked at so far?

Any input is appreciated. Thanks.

# Answer
> 1 votes
No. Core REST & REST Views aren't the right solution here. You don't need a custom module for this.

As you mentioned, JSON API module supports inclusion of entity references in a single resource request. Each entity requested has a property called `relationships` which are references to other entities that can be included with via the `include` parameter. References, within references (e.g. a node referencing a media entity, that references a file entity) are supported too, albeit with some work to follow references (e.g. when you a request inclusion via the `include` property you're given an array property, `included`, which you still have to sort through via id).

If you're looking for a Drupal API that follows entity references *within* returned entity objects, you should use the GraphQL module as it will allow you to define your own data spec that can expand entity references as you see fit.

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


# Question
Title: Site is redirecting to old domain on button submission, files are linking to old domain
I have a D7 site at `www.example.com`, an old one, not updated since 2012 (Drupal version 7.34). I made a clone copy with separate clone database under `dev.example.com`

All files like CSS are still linking to `www.example.com` (while they are available at `dev.example.com`).

And most important, on `/admin/` backend when under `dev.example.com` if you click any `Submit` button in any page, it redirects to the `www.example.com` website. So if I submitted any operation at `dev.example.com/admin/*` it redirects to same page at `www.example.com/admin/*`

I've cloned websites million times, I never had this behavior. How do I prevent redirects for files and on submissions?

**update:** I found in `settings.php` I have `$base_url = www.example.com` enabled, can somebody confirm this is the reason?

# Answer
Yes, you have to edit it to dev.example.com. In the Drupal code, the modules use a function who returns the base URL. So if this URL is the old site... it resolves to the old site.

It's also used to protect your website against XSS.
> 1 votes

---
Tags: 7, files, redirection
---


# Question
Title: How to check the value of a field within the current node?
In order to display a block only above certain nodes of Article content type, I created a boolean field with two values : On / Off

The goal is to display the block only above the articles that have the Off value

After enabling the PHP filter module, the block gives me this option : "Pages on which this PHP code returns TRUE (experts only)" but i haven't been able to figure out the php code that returns TRUE

( Can the context module achieve this without PHP ? )

Any help is help

# Answer
I think you should be able to do this with the (https://www.drupal.org/project/rules\_block\_visibility) module.
> 0 votes

---
Tags: 7, blocks
---


# Question
Title: Activate or DeActivate requirement status of field based on another field
I want to alter a form in my drupal 7 project. I want to **activate or deactivate** **requirement status** of a field **programmatically** based on another field value.

if field value is male , military status field must be **required** but if it is female, military status is not required and also it must be **hide**.

Please guide me in this issue.

# Answer
What you could do is make the military field not required. Then add your own validate function to the form with:

```
$form['#validate'][] = 'my_function_name';

```

Then in your function you can do a check e.g.

```
function my_function_name*$form, &$form_state){
  if($form_state['values']['my_gender_field'] == 'male' && empty($form_state['values']['my_military_field'])){
     form_set_error('my_military_field', 'Military field is required');
  }
}

```

Or you could try using #states from the form API which has a 'required' option: https://api.drupal.org/api/drupal/developer!topics!forms\_api\_reference.html/7.x#states
> 1 votes

# Answer
In order to test a solution to your needs I've used a form alter for the *article*. I've added few comments in the code, I hope they will be enough.

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_module_form_article_node_form_alter(&$form, &$form_state) {
  $form['gender'] = [
    '#type' => 'select',
    '#title' => t('Gender'),
    '#options' => [
      '_none' => t('Please select gender'),
      'm' => t('Male'),
      'f' => t('Female'),
    ],
    '#default_value' => '_none',
    // Ajax info:
    '#ajax' => [
      // This method returns an array of ajax commands or a form element already prepared.
      'callback' => 'my_module_ajax_responder',
      // This will tell wich dom id will be replaced with the response.data
      'wrapper' => 'military_status_dom_id',
      // pretty obiouvs
      'method' => 'replace',
      'effect' => 'fade',
    ],
  ];

  // Required property has been set to FALSE as default because no gender has been selected yet
  $required = FALSE;
  // this if will be ignored on page load, it means no submit has been done yet.
  if (!empty($form_state['triggering_element']) && $form_state['triggering_element']['#name'] === 'gender') {
    // but if user selects a gender, there will be an ajax submit and this will change
    // the required property of the military_status texfield element that is going to be
    // rebuilt
    $required = $form_state['triggering_element']['#value'] === 'm';
  }
  // now the actual military_status texfield element.
  $form['military_status'] = [
    '#prefix' => '<div id="military_status_dom_id">',
    '#suffix' => '</div>',
    '#type' => 'textfield',
    '#title' => t('Military status'),
    '#required' => $required,
  ];
}

/**
 * Ajax responder.
 */
function my_module_ajax_responder($form, &$form_state) {
  // after submit and form rebuild, ajax knows that it has to call this method
  // to recover a response data.
  // This data will be used to be a replacement (in this case) for the wrapper
  // specified in the $form['gender'] element.
  return $form['military_status'];
}

```

Here some more explatanation:

* Form will be built and then altered, therefore your alter function will be called
* there is an *if* to check if this is a phase of build during the page load or during the ajax submit
* in this case we tell to drupal that as soon as a user select a gender it has to submit their choice and let us check it, checnge the required property of the military\_status field and finally call the "callback" function to retrieve the modified element that will be replaced
> 1 votes

---
Tags: forms
---


title: Workflow with per page permissions

text:
# Question
Title: Workflow with per page permissions
I am creating a site for a complex organization of authors, editors, and publishers. Basically, each author is responsible for 1-5 pages and can only create drafts of these pages. Similarly, editors can only edit and approve pages to which they are assigned. There are max 5 publishers who are tasked with editing, publishing, creating new pages and navigation items, and assigning authors and editors.

If we have about 50 authors and 50 editors, how do we set up permissions and workflow for this site on Drupal 8?

One solution is to have Workbench Access set up to work on Taxonomy where each page is tagged with an author term and an editor term. We would then have to set up one term for every user and two fields on each page. Is there a more direct approach?

# Answer
You can use Business Rules module to check if the page has the is on the specific workflow state and if the user has the correct rule to view or edit it.
> 0 votes

---
Tags: 8, workflows
---


# Question
Title: Pass data to hook_preprocess_html from custom module
I'm trying to create a custom Drupal 7 module where it renders a custom page template. I want the data on /animals and /animals/getanimal to be in a custom HTML template.

After much searching and few successes, I've found that hook\_preprocess\_html works and that I can stop Drupal from loading the default template, but I'm struggling to pass data to my templates from the menu hook.

Is there a way to pass data from the menu hook to hook\_preprocess\_html, or is there another way where I can load my own custom template from the URLs in my custom module?

```
/**
 * Implements hook_menu()
 * @return mixed
 */
function animal_farm_menu() {

  $items['animals'] = array(
    'title'           => 'Discover animals',
    'page callback'   => 'getDiscover',
    'page arguments'  => array(),
    'access callback' => TRUE,
    'type'            => MENU_NORMAL_ITEM,
    'menu_name'       => 'main-menu',
  );

  $items['animals/getanimal'] = array(
    'title'           => 'all animals',
    'page callback'   => 'getAnimal',
    'page arguments'  => array(),
    'access callback' => TRUE,
    'type'            => MENU_NORMAL_ITEM,
    'menu_name'       => 'main-menu',
  );

  return $items;
}

function getDiscover()
{
  $result = ['cat','dog','monkey','cow'];
  return $result;
}

function getAnimal()
{
  $result = ['cat','dog','monkey','cow'];
  return $result;
}

/**
 * Implements hook_preprocess_html().
 */
function animal_farm_preprocess_html(&$vars) {

  $node = menu_get_object();

  $path = current_path();

  // echo $path;

  // Add a new theme suggestion when viewing node's of mynodetype.
  if ($path == 'animals') {
    $vars['theme_hook_suggestions'][] = 'html__mynodetype';
    $vars['data'] = [1,2,4,'monkey'];
  }

  if ($path == 'animals/getanimal') {
    $vars['theme_hook_suggestions'][] = 'animal_farm_discover';
    $vars['data'] = [1,2,4,'monkey'];
  }

}

/**
 * Implements hook_theme().
 */
function animal_farm_theme($existing, $type, $theme, $path) {
  $theme = array();

  //Add our templates/html--mynodetype.tpl.php to the theme registry
  $theme['html__mynodetype'] = array(
    'template' => 'html--mynodetype',
    'path' => drupal_get_path('module', 'animal_farm') . '/templates',
  );
  return $theme;
}

```

# Answer
> 0 votes
D7's `html.tpl.php` doesn't contain menu in `$vars`, as it's supposed to represent the template that contains the high-level HTML document. This data is in `page.tpl.php` via `$main_menu` / `$secondary_menu` vars.

If you need menu data in `hook_preprocess_html()` you can do something like call `menu_tree_all_data('main-menu')` in your code which will retrieve the menu data for `main-menu`.

---
Tags: 7, theming
---


# Question
Title: Messed-up div IDs for ajax-modified form field
I want to change, using Ajax, some attributes to `field2` (a select widget) when `field1` changes:

In mymodule.module:

```
function mymodule_form_NODETYPE_FORM_alter(&$form, &$form_state, $form_id) {
    $form['filed1']["widget"]['#ajax'] = array(
        'callback' => 'on_filed1_change',
        'wrapper' => 'edit-field-filed2-wrapper',
        'event' => 'change',
        'method' => 'replace',
    );
}

function on_filed1_change(array $form, FormStateInterface $form_state)  {
    $form['field2'] = $modified_field2;
    return $form['field2'];
}

```

**This works only the first time.**

I found out the following id's have been changed with **additional trailing random numbers**:

* `edit-field-field2-wrapper--GCPg2vSCav0` for `field2` wrapper `<div>`
* `edit-field-field2--EXhOuuWQld8` for `field2` `<select>` element

Since the original Ajax wrapper `edit-field-field2-wrapper` no longer exists, no further modifications to `field2` are possible.

Why does this happen? And how can I prevent this from happening, or use the new IDs as wrapper in the Ajax call?

I'm using 8.6.0-dev.

# Answer
```
function mymodule_form_NODETYPE_FORM_alter(&$form, &$form_state, $form_id) {
    $form['field2']['#attributes']['id'] = 'my_dom_id_for_elem2';
    // or if it doesn't work properly you can wrap the element
    // $form['field2']['#prefix'] = '<div id="my_dom_id_for_elem2">';
    // $form['field2']['#suffix'] = '</div>';

    $form['filed1']["widget"]['#ajax'] = array(
        'callback' => 'on_filed1_change',
        'wrapper' => 'my_dom_id_for_elem2',
        'event' => 'change',
        'method' => 'replace',
    ); }

function on_filed1_change(array $form, FormStateInterface $form_state) {
    // This line is not necessary, at this time $form['field2']
    // has already been modified and you can just return the form element itself, it will be used as response.data by javascript.
    //$form['field2'] = $modified_field2;
    return $form['field2'];

```

}
> 3 votes

# Answer
Drupal changes DOM IDs on every submit. You can, however, fix them by adding an attribute specification to your element:

```
$form['field2']['#attributes']['id'] = 'my_dom_id_for_elem2';

```

and then use **my\_dom\_id\_for\_elem2** as your wrapper property.
> 2 votes

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


# Question
Title: How do I add drupalSettings info from an AJAX callback
I have a custom Drupal 7 module that does a zipcode lookup to return town and county. I set Drupal.settings.zip\_code\_success to true within the callback. This is the code I am using.

```
drupal_add_js(array('zip_code_success' => TRUE), 'setting');
$commands = array();
$commands[] = ajax_command_html('#triage_city', $out);
return array(
  '#type' => 'ajax',
  '#commands' => $commands,
);

```

The zip\_code\_success value is then available in some processing code that runs on the js side.

In moving things to Drupal 8, the lookup and html replacement are working fine, but I can't figure out how to get the zip\_code\_success info into drupalSettings. drupalSettings gets set up in the the initial page generation and shows within the DOM with the values that are passed initially through the hook\_preprocess\_html function. I've tried a variety of things in the zipcode lookup function but haven't been able to update drupalSettings. Here's the current D8 code snippet comparable to the D7 above:

```
$response->addCommand(new SettingsCommand(['zip_code_success'=>TRUE] ,TRUE));
$response->addCommand(new HtmlCommand('#triage_city', $out));
return $response;

```

I've also tried:

```
$response->setAttachments([
  'library' => ['core/drupalSettings'],
  'drupalSettings' => ['zip_code_success' => TRUE]
]);
$response->addCommand(new HtmlCommand('#triage_city', $out));
return $response;

```

Any wisdom as to how to handle this situation?

# Answer
> 2 votes
In Drupal 8, as you've discovered, drupal\_add\_js() has been removed.

There are two things you need to do this:

1) You cannot add JS in an ajax callback. It was a bad practices in D7, and cannot be done at all in D8. You'll need to add the JS in your form definition, not the ajax callback.

2) You add JS through a two-step process. The first is to create a new library in the \*.libraries.yml file. Add a dependency to core/drupalSettings\`. Then, in your form definition, you add your setting like this:

```
$form['some_element'] = [
  '#markup' => '', // required to render the element
  '#attached' => [
    'libraries' => [
      'some_library', // The library you created
    ],
    'drupalSettings' => [
      'modulename' => [
        'zip_code_success' => TRUE,
      ],
    ],
  ],
];

```

---
Tags: 8
---


# Question
Title: Extract data from Field Collection using db_select()
I'd like to use db\_select() to extract values from a field collection attached to the user profile, to help speed up some complex Ajax forms (rather than loading the entire field collection, using standard entity queries, etc, etc).

Assuming I have the following:

Field Collection: `field_my_address`
Field 1: `field_street_number` (integer field)
Field 2: `field_street_name` (text field)
Field 3: `field_city` (taxonomy term reference field)

How would I go about doing this?

# Answer
> 0 votes
I got it to work like this:

```
$pid = $profile->pid;

$query = db_query('SELECT nn.field_street_number_value AS number,
                          ss.field_field_street_name_value AS street,
                          cc.field_city_tid AS city,
         FROM field_data_field_my_address AS aa
         LEFT JOIN field_data_field_street_number AS nn ON aa.field_my_address_value = nn.entity_id
         LEFT JOIN field_data_field_street_name AS ss ON aa.field_my_address_value = ss.entity_id
         LEFT JOIN field_data_field_city AS cc ON aa.field_my_address_value = cc.entity_id
         WHERE aa.entity_id = '.$pid);

$records = $query->fetchAll();

```

---
Tags: database, entities
---


# Question
Title: Select groups to relate the node to directly in the node creation form
An admin who wants to relate a node to a group can go to the group and then create a node from there (`/group/{id}/node/create`) . The node is then assigned to the group. Or she can assign a already created node (`/group/{id}/content/add`)

What I need is a way to relate a node to one or multiple groups directly when creating it. Is there a module to do this or some documentation to get me started in developing it?

# Answer
There is no module that offers this out of the box as far as I know. You'd need some custom programming. I don't know what exactly you need, but here's something that might help to get you started.

Let's assume you want to programmatically relate a node/content to one/multiple groups as soon as the node is created. You could use a hook `hook_ENTITY_TYPE_insert()` (*hook* replaced by your custom module's name and *ENTITY\_TYPE* replaced by the entity type (e.g. *node*).

Here's an example for article nodes:

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

/**
* Implements hook_ENTITY_TYPE_insert().
*/
function modulename_node_insert(Node $node) {
  if ($node->bundle() == 'article') {
    $pluginId = 'group_node:article';
    // Here create some logic to load/chose the group id's you want to
    // add the content to
    // ...
    foreach ($group_ids as $gid) {
      $group = Group::load($gid);
      $group->addContent($node, $pluginId);
    }
  }
}

```

This would automatically add the (article) nodes that are created to one or multiple groups. This is just a basic example of how to code the differnt parts. You can however make it as complex as you need. Hope this helps
> 2 votes

---
Tags: 8, group
---


# Question
Title: How to prevent "drush up" from destroying my git repo
I just updated Drupal to 7.39 using Drush, in particular the command `drush up` and all related steps as explained here: https://www.drupal.org/node/2550801. During the update I have noticed this extremely worrying line, saying that Drush is messing with my .git directory:

and indeed after the update:

So I got back the .git folder from the backup created by the Drush updater, committed and pushed.

The problem is that Drush, without any warning, not only corrupted the .git directory but also messed with my .gitignore file, deleting several lines.

As a result I pushed a very large number of cache and temporary files to my company's git repo and had to later fix it and apologise to my colleagues.

**My question is:** is there a way to update Drupal programmatically (no admin or manually moving files) without Drush trying to destroy my git repo?

# Answer
> 2 votes
The deletion of the .git directory and other non-Drupal files when running `drush up drupal` has been a somewhat randomly occurring problem for many Drush users as documented on this GitHub issue. As far as I know, no definitive reason for this behavior has been found, and there is even debate about whether this behavior is, or should be, by design.

In my experience and that of others participating in the GitHub discussion, this deletion of the .git directory did not happen when using Drush 6, but happens in some circumstances when using Drush 7 or 8. Therefore, there's no surefire way of avoiding the deletion of the .git directory and other non-Drupal files when running `drush up drupal` besides moving those files out of the Drupal root directory *before* running the update.

However, the overwriting of .gitignore when running `drush up drupal` occurs by design. .gitignore is a core Drupal file, and as Drush warns, updating core will discard any customizations:

```
Code updates will be made to drupal core.
WARNING:  Updating core will discard any modifications made to Drupal
core files, most noteworthy among these are .htaccess and robots.txt.  If
you have made any modifications to these files, please back them up
before updating so that you can re-create your modifications in the
updated version of the file.

```

.gitignore isn't mentioned explicitly in that warning, but it is treated similarly since it, too, is a Drupal core file.

# Answer
> 1 votes
Try this, I'm searching for this topic and I found a solution.

At first you need to move .git, .gitignore... folder out (You need to be at web root)

mv .gi\* ../

After that you can run drush up normally without affect any git files

drush up drupal -y

Finally you need to move .git, .gitignore... folder back and then apply your commits like such file changes

mv ../.gi\* ./

---
Tags: drush, updating
---


title: How to make custom URL mandatory?

text:
# Question
Title: How to make custom URL mandatory?
I'd like to force users to customize URL. How to make the following field mandatory?

# Answer
> 1 votes
The path alias is a field, so you just need to alter the form and set the `#required` property on the element:

```
function module_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['path']['widget'][0]['alias']['#required'] = TRUE;
}

```

---
Tags: 8
---


title: Optimize on the huge number of markers

text:
# Question
Title: Optimize on the huge number of markers
I have more then 8000 markers on a Gmap view, using clusters (markerclusterer.js) , and I have a loading time 16 seconds.

How can this be optimized? The view is cached, Drupal is cached and compressed and running on Pantheon already.

This loading time is caused from the view query to get the markers, as they are all already in the head of the HTML page when the page is loaded.

I was thinking to hardcore the markers into JSON, but still I don't know how it could be intehrated with gmap after.

# Answer
> 0 votes
You could try using Redis, "The World's Fastest Database".

> Redis is a very fast non-relational database that stores a mapping of keys to five different types of values. Redis supports in-memory persistent storage on disk, replication to scale read performance, and client-side sharding1 to scale write performance.
>
> Quote from redislabs.com - 1.1 What is Redis?

There is some offical documentaiton on Pantheon on this, Installing Redis on Drupal.

They also made a video about it, Pantheon Academy - Redis on Pantheon

---
Tags: google-maps
---


# Question
Title: How do I allow modules to provide their own view?
In Drupal 7, there is `hook_views_default_views()` which allows modules to provide their own views. What's the equivalent for Drupal 8?

# Answer
> 4 votes
Views are config, so:

1. Create a View
2. Export the config for it as a single item using the UI or drush (removing the uuid if applicable).
3. Include it in your module’s ./config/install folder
4. Install the module on a different site; the View will be created automatically

# Answer
> 1 votes
I Have a reference URL for this. Go through, you can achieve this. Creating views programmatically is quite different than we did in Drupal 7. In Drupal 7 we have hook\_views\_default\_views(), we don’t have this hook in Drupal 8. We will use configuration manager in Drupal 8 for creating views programmatically How to create views programmatically in Drupal 8

Hope it will help for you.

# Answer
> 0 votes
You can use *Drupal Console* to export your views into custom module, e.g.

```
drupal config:export:view viewid --module="modulename"

```

See: `config:export:view`.

> Export a view in YAML format inside a provided module to reuse in other website.

This will export views into module's `config/install` folder which would be imported on install.

---
Tags: 8, views
---


# Question
Title: Problem translation of terms menu - Drupal 8.5.1 - Distribution VarBase
how are they? I have a problem with the menu item translation. when i make click in button translate i have a issue i attach image.

I am using `Drupal 8.5.1` and the `distribution VarBase 8.x-4.16`.

Error: After the click, we see the following error.

El sitio web encontró un error inesperado. Vuelva a intentarlo más tarde.InvalidArgumentException: Field content\_translation\_source is unknown. in Drupal\Core\Entity\ContentEntityBase-\>getTranslatedField() (line 580 of core/lib/Drupal/Core/Entity/ContentEntityBase.php). Drupal\Core\Entity\ContentEntityBase-\>get('content\_translation\_source') (Line: 44) Drupal\content\_translation\ContentTranslationMetadataWrapper-\>getSource() (Line: 120) Drupal\content\_translation\Controller\ContentTranslationController-\>Drupal\content\_translation\Controller{closure}('es') array\_filter(Array, Object) (Line: 122) Drupal\content\_translation\Controller\ContentTranslationController-\>overview(Object, 'menu\_link\_content') call\_user\_func\_array(Array, Array) (Line: 123) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() (Line: 582) Drupal\Core\Render\Renderer-\>executeInRenderContext(Object, Object) (Line: 124) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>wrapControllerExecutionInRenderContext(Array, Array) (Line: 97) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber-\>Drupal\Core\EventSubscriber{closure}() (Line: 151) Symfony\Component\HttpKernel\HttpKernel-\>handleRaw(Object, 1) (Line: 68) Symfony\Component\HttpKernel\HttpKernel-\>handle(Object, 1, 1) (Line: 57) Drupal\Core\StackMiddleware\Session-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\KernelPreHandle-\>handle(Object, 1, 1) (Line: 99) Drupal\page\_cache\StackMiddleware\PageCache-\>pass(Object, 1, 1) (Line: 78) Drupal\page\_cache\StackMiddleware\PageCache-\>handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\ReverseProxyMiddleware-\>handle(Object, 1, 1) (Line: 50) Drupal\Core\StackMiddleware\NegotiationMiddleware-\>handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel-\>handle(Object, 1, 1) (Line: 664) Drupal\Core\DrupalKernel-\>handle(Object) (Line: 19)

I hope favorable answers!! As always thank you very much

# Answer
> 0 votes
I solved it, going to **admin/config/regional/content-language** and check the box in Custom menu link and solve the problem.

---
Tags: views, console
---


# Question
Title: List migrations separately but use single migration class
I have successfully created a custom migration class which works perfectly but my issue is with the `drush migrate-status` output.

When I execute `drush migrate-status` all the XML files I am attempting to migrate from ( I have over a hundred of them each with the same XML structure ) are all compacted into a single migration of *10,000*. **What I need is for each of my xml files to be listed individually.**

I know I can achieve the individual listing by giving each of my XML file a unique migration class but that is inefficient because the code will be exactly the same in all the classes except for the class names.

Can anyone suggest a solution to help achieve my objective?

# Answer
It sounds like you're trying to force a tool to do something it's not supposed to do. The migration tools `drush migrate-status` command only provides a **high-level** overview of the migration batch work associated with a migration (current state, migration source entities found, number of entities, migrated, etc.)

There is `drush migrate-messages` if you're wanting to inspect *individual migrations that may have failed*. But if you're wanting a super-granular, per-entity, view of each migration item then you're probably looking at building your own tool or debugging a migration as it's being processed.
> 0 votes

---
Tags: 7, migrations
---


# Question
Title: Getting a list/array of all organic groups a user is part of
I have been searching online for awhile and so far I have been unable to find any og functions that will give me an array or list of all groups a user is a member of. Does such a function exist? If not, is there a sql query I could run that would give me this?

# Answer
> 8 votes
Assuming you are using Drupal 7 and latest OG you can use og\_get\_groups\_by\_user().

> Get the group IDs of all the groups a user is an approved member of.

# Answer
> 0 votes
Although I am a big fan of `og_get_groups_by_user()`, sometimes a bit more control about what is returned with the membership data is useful.

Here's a starter query that'll get you all the group nodes a particular user is a member of:

```
$uid = 123;

$query = db_select('og_membership', 'ogm');
$query->condition('ogm.type', OG_MEMBERSHIP_TYPE_DEFAULT);
$query->condition('ogm.etid', $uid);
$query->condition('ogm.entity_type', 'user');
$query->condition('ogm.group_type', 'node');

$query->join('node', 'n', 'n.nid = ogm.gid');
$query->fields('n', ['nid', 'title']);
$query->condition('n.type', 'group');
$query->orderBy('n.title', 'ASC');

$rows = $query->execute();
foreach ($rows as $row) {
  drupal_set_message(t('Member of @group', ['@group' => $row->title]));
}

```

# Answer
> -1 votes
The user groups can also obtained by loading the user. For ex: `$test_user = user_load(2);
 $groups = $test_user['og_user_node']; // returns all group ids of a user`

---
Tags: 7, users, organic-groups, database
---


# Question
Title: How to check the first item/content on Drupal View
I'm currently using Drupal Views and I'm trying to figure how to check the first item/content on the view. On a twig template I could write

```
{% for items in related_content.entity.field_content_items %}

    {% if loop.first %}

    first element

    {% endif %}

{% endfor %}

```

I tried writing the same condition within the view using `{% if loop.first %}` but it doesn't work. Is there similar code to achieve this within Drupal Views Custom Text

# Answer
> 2 votes
Have you tried to print other stuff of the loop variable, maybe `{{ loop.index }}`, did this work? You then could if-request this. As far as I remember `loop.index` worked fine in Drupal.

Next thing you can try is to iterate over the keys and if-request the key for your logic. Pretty much the same as `loop.index`.

```
{% for key, items in related_content.entity.field_content_items %}
  {% if key == 0 %}

```

Last resort would be to target `related_content.entity.field_content_items[0]` directly.

But I think the first two suggestions should give you at least one opportunity to do what you want.

---

Thanks for the clarification. Views custom text only. OK, in that case consider to use 2 views (or just 2 displays of the same view) as outlined here https://drupal.stackexchange.com/a/104608. Then you'd attach the first view (or display) - which is limited to display only 1 row - before your second view (there must be an attachment option somewhere) and your second view then should be configured to have an offset of 1.

---
Tags: views, 8
---


title: how to get count of total record

text:
# Question
Title: how to get count of total record
I'm using drupal pagination here i have add some part of my code pagination is working perfect while I'm trying to get the total no of record it is always displaying 10. As i understand i have set the limit 10 so it displaying only total 10

```
$query->orderBy('r.published_date', 'DESC');
        $pager = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit(10);
    $results = $pager->execute()->fetchAll();

```

This `$results` variable I'm getting data with the set of 10 values.

I would like to display total no of data for that i have created other variable where i have directly executed query in `$result` so it could give total no of records but its not working it displaying only 10

```
$result = $query->execute();
        while($data = $result->fetchObject()){
           $count_ret[]=$data->published_date;
        }
             $total=count($count_ret);

```

please guide me where i'm doing wrong

# Answer
Until the issue Convert pager.inc to a service is solved you find the pager information still in global variables:

```
global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;

$count_of_total_records = $pager_total_items[$element];

```

Where `$element` defaults to `'0'` if this is the first pager with no element id set.
> 0 votes

---
Tags: views, 8, paging
---


# Question
Title: How to provide the “Privacy policy link” correctly on EU COOKIE COMPLIANCE module?
After this recent update of the module, when I run a Status Report, it warns me that: “Privacy policy link not provided”, but I actually think I did it by filling up the field “Privacy policy link”, am I missing any additional configuration on the module set up (Drupal 8.5.5)?

Note that, despite this warning the message abouts the cookies is displayed on the website and the respective button “MORE INFO” links to a page I created with additional info on the cookie compliance.

# Answer
> 0 votes
After not being able solve the issue I decided to restore my Drupal Site and install first the Google Analytics Module update and after the UE Cookie Compliance Module update and the warning message didn’t appear this time. Maybe just Drupaluck (nevertheless I decided to share my experiance).

A special thanks to all that tried to help me.

# Answer
> 2 votes
Actually it's better you'd report issues like that on drupal.org and not here on Drupal Answers.

The recent EU Cookie Compliance updates happened in a rush when during the ongoing development a security hole was found. Because of that a lot of half-ready new features got released.

It happens I just released a patch which may be related to your problem, see https://www.drupal.org/project/eu\_cookie\_compliance/issues/2985543.

But you may not necessarily need the patch. All you need to do is to update to the latest version, then go to the module's config page and choose a method (default, opt\_in etc.). Choose *default* to turn back to the initial method before the most recent updates added additional methods.

If that doesn't work try to follow the steps from https://www.drupal.org/project/eu\_cookie\_compliance/issues/2985613#comment-12685609 which was a fix for the 7.x branch but may apply for D8 as well.

---

Last but not least, double-check that the link you provided either goes to an *existing* internal route or is an external link.

---
Tags: cookies
---


title: How to use ajax in field widget form?

text:
# Question
Title: How to use ajax in field widget form?
I need to store a country and a region for geographical objects. Countries and regions are stored in a taxonomy vocabulary. Moreover, some countries have regions (as child terms) but someones don't have it.

I decided to create a complex field contains tid of a country and tid of a region. If an object doesn't have a set region, then a value of the region is 0 in this case.

I want to create a field widget for it. The widget should contain a combo box with a list of countries. Moreover, if the user is selected a country having regions, then a new combo box with its regions is appeared.

I have tried to do it with ajax like it is done in forms.

That is, I have written the following. (Here I have removed some code from the source to shorten it)

```
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state)
  {

// come code here ....

    // TODO: Implement formElement() method.
    $element['country_id'] = [
      '#type' => 'select',
      '#title' => t('Select a country'),
      '#options' => PalomGeo::getCountryList(),
      '#default_value' => $country_id,
      '#ajax' => [
        'callback' => '::changeCountry',
      ]
    ];

    $regions = PalomGeo::getRegionList($country_id);

    if ($regions!=[]){
      $element['region_id'] = [
        '#type' => 'select',
        '#title' => t('Select a region'),
        '#options' => $regions,
        '#default_value' => $region_id,
      ];
    }

    return $element;
  }

// Some code here

  public function changeCountry(array &$form, FormStateInterface $form_state){
    return $form['region_id'];
  }

```

But unfortunately, it doesn't work.

The error "The specified #ajax callback is empty or not callable" is appeared.

I want to clarify is it possible to use AJAX upon creating field widgets? If yes, does it differ from using AJAX in Drupal 8 Forms?

# Answer
You need to specify the class (including the full namespace) to run that method on. E.g: `'callback' => \Drupal\my_module\Plugin\Field\FieldWidget\MyWidget::changeCountry`
> 2 votes

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


# Question
Title: Ajaxly set Text Field Value with Drupal Forms API
I have a text field and a `ajaxified` link in my form:

```
$form['id_number'] = array(
    '#title' => t('ID Number'),
    '#type' => 'textfield',  //textfield
    '#suffix' => '<div>l(t('101-03043'), 'myid_choose_result/101-03043/1, array('attributes' => array('class' => 'use-ajax')))</div>',  //ajaxified link
    '#attributes' => array('id' => 'myid_search_id_number'),
);

```

The link above calls a function `myid_choose_result` define in my hook menu:

```
function myid_menu(){
    $items = array();

    $items['myid_choose_result'] = array(
        'page callback' => 'myid_choose_result',
        'access callback' => 'myid_user_access',
        'file' => 'myid.pages.inc',
        'type' => MENU_CALLBACK,
    );
    return $items;
}

```

What I want to achieve is every time the user clicks the link, the text field value will be the link's text. After doing so, I want to call a another function:

```
function myid_choose_result($id,$template){
      //Change the textfield's value into $id
      myid_some_function(); //Call another function
}

```

How will I do that?

# Answer
I suggest you instead of creating link and try to call ajax with old method( call form your custom js file ) try drupal ajax method

My suggestion is :

```
function yourmodule_form_alter(&$form,$form_state,$form_id){
if($form_id=='your specified form name '){
$form['id_number'] = array(
    '#title' => t('ID Number'),
    '#type' => 'textfield',  //textfield
     '#prefix' => '<div id="vm-container">',
    '#suffix' => '</div>'
    '#attributes' => array('id' => 'myid_search_id_number'),
 );
$form['myajax'] = array(
        '#type' =>'button',
        '#value' => t('fill me'),
        '#ajax' => array(
            'callback' => '_myfuction_fill_number_ajax',
            'wrapper' => 'vm-container',
            'method' => 'replace',
            'effect' => 'fade',
            'prevent'=> 'sumbmit',
        ),
    );
 }
}
function _myfuction_fill_number_ajax(&$form,$form_state){
     $form['id_number'] ['#default_value'] = myid_some_function();
    // if not work try it with  $form['id_number'] ['#value'] = myid_some_function();
      return $form;
    }

```

also if you can want do ajax with jquery, add js file to your form, in that js file set click handler for your link ( tag) and in click call `$.ajax` with you menu rout.
> 0 votes

# Answer
You need to format the response of your callback correctly.

First of all define the menucallback as following:

```
/**
 * Implements hook_menu().
 */
function my_module_menu() {
  $items = [];

  $items['my_module/test/%/%'] = array(
    'page callback' => 'my_module_test_callback',
    'page arguments' => [2, 3],
    'access callback' => TRUE,
    'delivery callback' => 'ajax_deliver',
    'type' => MENU_CALLBACK,
  );

  return $items;
}

```

Then your callback function need to return an array containing info about ajax commands

```
function my_module_test_callback($var_0 = '', $var_1 = '') {

  // Build your text value here according to var_0 and 1.
  $text_val = $var_0 . ' ' . $var_1;

  $commands = [];
  // This will add a command that in JS side will translate in something like this: $('#myid_search_id_number').val('new_value');
  // The textfield value will be updated.
  $commands[] = ajax_command_invoke('#myid_search_id_number', 'val', [$text_val]);

  // return an array that "ajax_prepare_response" can read and prepare for js side
  return ['#type' => 'ajax', '#commands' => $commands];
}

```
> 0 votes

---
Tags: 7, forms, ajax
---


# Question
Title: How to move nested links in menu edition?
In Drupal 8 I created nested menu links. After some days I tried to move them. Eg. one nested link to one parent menu link but the moving got disabled.

I remember that there were small cross icons with arrows in front of each menu link that were handles to move them before. But now they are not present. How to move the links?

There is no problem on chrome but firefox.

See the picture of the problem:

# Answer
If you don't have javascript error in the browser console try to click **Hide row weight** then you will see normal table drag behavior.
> 1 votes

---
Tags: 8, navigation
---


title: Views relationship to second database

text:
# Question
Title: Views relationship to second database
Is there any possibility to add a relationship in views from a second database to the default one. I.e. I am using a second database which contains one table with a userid. In my hook\_views\_data I would like to add a relationship from this field to users\_field\_data uid. How can I do this?

# Answer
> 0 votes
I was logged out. Yes I tried to add field relationship on views settings, but my joined table was not shown. Consider that I want to join from a view showing my table to the users\_field\_data table, not vice versa.

my view is simply showing the the fields from my custom table. This works. But I can't add a relationship to the second db. The SQL query is

```
SELECT my_tracking.id AS id, my_tracking.uid AS my_tracking_uid, my_tracking.event_id AS my_tracking_event_id
FROM {my_tracking} my_tracking
ORDER BY id ASC
LIMIT 25 OFFSET 0

```

my hook\_views\_data looks like

```
$data['my_tracking']['table']['name'] = 'event_tracking' . '.my_tracking';

$data['my_tracking']['table']['group'] = t('Event Tracker');

$data['my_tracking']['table']['base'] = array(
  'field' => 'id',
  'title' => t('Event Tracker'),
  'help'  => t('Contains data about tracking events.'),
  'database' => 'event_tracking',
);

$data['my_tracking']['table']['join'] = array(
  'users_field_data' => array(
    'table' => 'default' . '.users_field_data',
    'left_field' => 'uid',
    'field'      => 'uid',
  ),
);

$data['my_tracking']['table']['provider'] = 'my_tracking';

$data['my_tracking']['id'] = array(
  'title' => t('Record ID'),
  'field' => array(
    'id' => 'numeric',
  ),
  'sort' => array(
    'id' => 'standard',
  ),
  'filter' => array(
    'title' => t('Record ID'),
    'id' => 'numeric',
  ),
  'argument' => array(
    'id' => 'numberic',
  ),
);

$data['my_tracking']['uid'] = array(
  'title' => t('UID'),
  'help'  => t("The user's UID."),
  'field' => array(
    'id' => 'numeric',
  ),
  'sort' => array(
    'id' => 'standard',
  ),
  'filter' => array(
    'title' => t('UID'),
    'id' => 'numeric',
  ),
  /*  'relationship' => array(
    'title'              => t('User who is tracked'),
    'help'               => t('The user associated with the record.'),
    'id'                 => 'standard',
    'base'               => 'users_field_data',
    'base field'         => 'uid',
    'field'              => 'uid',
    'label'              => t('The who is tracked'),
  ),*/
  'argument' => array(
    'id' => 'numeric',
  ),
);

$data['my_tracking']['event_id'] = array(
  'title' => t('Event ID'),
  'field' => array(
    'id' => 'numeric',
  ),
  'sort' => array(
    'id' => 'standard',
  ),
  'filter' => array(
    'title' => t('Event ID'),
    'id' => 'numeric',
  ),
  'argument' => array(
    'id' => 'numberic',
  ),
);

```

No relationship can be added in views. Previously when I used a single database I was able to add the relationship by using the relatationship handler that is commented out above now. I don't know how to adapt it to 2 databases.

---
Tags: 8, database, views
---


# Question
Title: Composer doesn't see that updates are needed
My Drupal version is 8.5.1, and yet when I run...

```
composer outdated drupal/*

```

It says "nothing to install or update".

What to do?

This is the relevant part of my composer.json...

```
"require": {
        "composer/installers": "^1.0.21",
        "wikimedia/composer-merge-plugin": "~1.3",
        "drupal/core": "^8.5"
    },

```

Looks fine to me, but composer says no update is available.

# Answer
> 1 votes
**Update: This is not a good answer. Leaving it here for reference, but this does not solve the underlying problem, whatever it is.**

Fixed by deleting vendor and core directories and composer.lock and then running...

composer update drupal/core --with-dependencies

It seems there must be some circumstances when the 'composer outdated' command doesn't work, but it's still possible to upgrade.

---
Tags: 8, composer, upgrading
---


# Question
Title: How to embed webform to update existing submission
I'm trying to display a webform through a module controller. The webform display works as it should but I need to update existing submission data and instead of updating the existing submission a new one gets created.

The code I use looks like this:

```
public function edit()
{
  $submissionId = \Drupal::request()->get('sid');
  $webform = Webform::load('eventsignup');
  $webformSubmission = WebformSubmission::load($submissionId);
  $webform = $webform->getSubmissionForm([
    'data' => $webformSubmission->getData()
  ]);

  $build['submissionForm'] = $webform;

  return $build;
}

```

I tried to alter it by giving the operation "edit" and setting the "sid" but that leads to a duplicate key error:

```
public function edit()
{
  $submissionId = \Drupal::request()->get('sid');

  $webform = Webform::load('eventsignup');
  $webformSubmission = WebformSubmission::load($submissionId);
  $webform = $webform->getSubmissionForm([
    'sid' => $submissionId,
    'data' => $webformSubmission->getData()
  ], 'edit');

  $build['submissionForm'] = $webform;

  return $build;
}

```

What am I doing wrong?

Thanks for your help!

# Answer
> 1 votes
Existing webform submissions are entities and you can use the entity form builder service to build the form:

```
// load the webform submission entity
$webformSubmission = WebformSubmission::load($submissionId);
// build a form for the entity
$webform = \Drupal::service('entity.form_builder')->getForm($webformSubmission, 'edit');

```

---
Tags: 8, webforms
---


# Question
Title: Composer require drupal/ packages doesn't work
If I run...

```
composer require drupal/token

```

...I get...

```
Could not find a version of package drupal/token matching your minimum-stab
  ility (dev). Require it with an explicit version constraint allowing its de
  sired stability.

```

Not sure if this is relevant, but token is already installed in my site, but is not required in composer. I want to require (and upgrade) the module with composer.

Changing my minimum stability from dev to stable does not resolve the problem.

I am having the same problem with other modules when I try to run 'composer require'. Composer always responds with "Could not find a matching version of package..."

Here is a question I posted earlier today that may be related: Composer doesn't see that updates are needed

# Answer
Sounds like Composer doesn't know about Drupal's packages, which suggests you're missing a reference to the repository in composer.json.

Add this and you should be good to go:

```
"repositories": [
  {
    "type": "composer",
    "url": "https://packages.drupal.org/8"
  }
]

```
> 5 votes

---
Tags: composer, upgrading
---


title: Use conditions in views rewrite

text:
# Question
Title: Use conditions in views rewrite
I have a view that shows an overview of "experiences". The problem I am having is they switch HTML on every row.

so the first will be:

Image text

then the second will be:

Text Image

I tried using conditionals in the rewrite result. But they seem to not work as shown below:

This outputs:

Is there a fix or workaround for this?

# Answer
> 2 votes
By setting field\_my\_link to show as URLs / plain text I was able to quickly get the result I needed, to point the URL of the title to an offsite URL if it has data, and keep it to the NID url otherwise. view\_node is a view field of the URL

```
{% if field_my_link|length > 0 %}
<a href="{{ field_my_link }}">{{ title }}</a>
{% else %}
<a href="{{ view_node }}">{{ title }}</a>
{% endif %}

```

This worked quickly and effectively as a rewrite. Although I would rather not have a rewrite stored as config in views, it was a quick and reliable solution.

# Answer
> 1 votes
The following answer is from Drupal 7 post, long time ago but I guess the methodology is still the same.

Basically in your views template you can specify that logic.

https://www.drupal.org/node/1932102#comment-7182640

```
if (row is even)
  // display order 1
else {
  // display order 2
}

```

Update: There is port of the views conditional module available on github.

https://github.com/anandtoshniwal93/views\_conditional/blob/master/README.md You can reuse it in your view like that....

```
Views Conditional field (if row is even)

  print rewrite field 1 (which is the first combination order)

Viws Conditional field (if row is odd)

  print rewrite field 2 (which is the second combination order)

```

---
Tags: views, 8
---


# Question
Title: Is it possible to hardcode views as part of the custom module to avoid `config/sync`?
I've exported views into the custom module using *Drupal Console* and `config:export:view` command, so they exist as part of the module in `modules/custom/my_module/config/install` (YAML files).

After I've enabled the newly created custom module, the views are imported on install as expected.

However when I'm trying to to do config import (`drush config-import`), *Configuration Manager* wants to remove the views. Respectively, when I want to export (`drush config-export`), it asks to create them in `../config/sync` (despite they're already existing in the module it-self).

What I'm looking is, the ability to hardcode the views into custom module, so they won't be part of `../config/sync` anymore, so config import won't affect or remove them. In other words, I'm looking for locking down mechanism to avoid accidental removal during config import on the production (something similar to `hook_views_default_views` in D7), where views are hardcoded as part of the code.

# Answer
> 2 votes
I see 2 options you have:

1. Use Features to take care of your view and its config together with Config Ignore or some similar approach to have this view's built-in config completely ignored from configuration management. With Features then you still have the ability to track and/or deploy any possible changes of the view.
2. Build your own controller or block and have full control of the output, with your own templates, your own database queries, your own everything. Most if not all of this then will simply be invisible to configuration management.

Depending on the complexity of the view, I'd prefer option 2.

# Answer
> 2 votes
Yes that's right the config export will recreate them for its config sync handling. The /module/config/install is exactly that, just for install time. The config syncing would become a big mess of overlaps if every module could define different elements to handle syncing themselves. Is it such a problem that config sync has them? As that can be your master of that the view should contain. So think of it as: The module sets up the default upon install and Drupal's config sync will make a copy so that's now the master and won't get removed unless you remove it through the UI and then do a config export.

If people are paying attention it should hopefully be unlikely someone would delete a view from the UI, do a config export and do an import on live without realising they've messed up. But just in case have you thought about adding your config sync directory into GIT? So that if someone does say delete a view through the UI and do an export you'd be able to revert

# Answer
> 2 votes
To complete @leymannx answer, after exporting into *Feature* and adding the views into *Config Ignore*, the following hooks can be added for additional precaution to prevent any alteration of the views.

```
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\views\Entity\View;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Implements hook_entity_predelete().
 */
function MYMODULE_entity_predelete(EntityInterface $entity) {
  if ($entity instanceof View) {
    // Protecting only non-local environments.
    if (strpos($entity->id(), 'MYVIEW_') === 0) {
      // Views are protected from deletion.
      drupal_set_message(t("This view can't be deleted as it is crucial for the system to work correctly."), 'error', FALSE);
      $response = new RedirectResponse('/admin/structure/views');
      $response->send();
      // Preventing any success messages from appearing.
      exit;
    }
  }
}

/**
 * Implements hook_entity_presave().
 */
function MYMODULE_entity_presave(EntityInterface $entity) {
  // Protecting only non-local environments.
  if ($entity instanceof View) {
    if (!$entity->isNew() && strpos($entity->id(), 'MYVIEW_') === 0) {
      // Views are protected from modification.
      drupal_set_message(t("This view can't be modified as it is crucial for the system to work correctly."), 'error', FALSE);
      $response = new RedirectResponse(\Drupal::request()->getRequestUri());
      $response->send();
      // Preventing any success messages from appearing.
      exit;
    }
  }
}

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Protecting only non-local environments.
  if ($form_id === 'view_edit_form' && empty($_POST)) {
    foreach ($form['#cache']['tags'] as $tag) {
      if (strpos($tag, 'config:views.view.MYVIEW_') === 0) {
        // Views are protected from modification.
        drupal_set_message(t("Note that changes to this view won't be visible across the page. The view, in its original state, is crucial for the system to work correctly."), 'warning', FALSE);
        return;
      }
    }
  }
}

```

Note: Extra conditions can be added as needed like `if (empty($GLOBALS['APP_ISPROD']))` or similar.

---
Tags: views, 8, configuration
---