# Question
Title: Is there any technical reason why we now should put third-party modules in the [docroot]/modules folder?
Is there any technical reason why we now should put third-party modules in the \[docroot\]/modules folder? It seems like an odd inconsistency that common third-party modules go there, while multisite-specific modules go in the traditional /sites/\[site\]/modules folder. It appears that creating a sites/all/modules folder still works.

# Answer
Technical? Not really, it isn't faster or anything like that.

It's basically about Developer/User Experience. It's 2 clicks less to go there and find a module.

Also, there multiple issues to either drop multisite entirely (although most people disagree with that) or not exposing it by default and just have a settings/settings.php by default.
> 4 votes

# Answer
Part of the reasoning was that it was confusing for people new to the system to have a modules folder in the base directory that you're not supposed to touch at all, and the modules folder you're supposed to use is buried in sites/all/modules.

Personally, I think it makes sense to move all the core files to the core folder and using the modules and themes folders for custom and contributed modules.
> 1 votes

---
Tags: 8
---


# Question
Title: How to make the image hover between the 2 uploaded image?
How to make the image hover between the 2 uploaded image?

```
<div class="portfolio_area_left">
    <a href="<?php if (!empty($node->field_link_site)) print $node->field_link_site['und'][0]['value']; ?>" target="_blank">
        <?php print theme('image_style', array('path' => $imageone, 'style_name' => 'image_800x600', 'attributes'=>array('alt'=>$title))) ?>
    </a>
</div>

```

The script above just make the node display one image.

The second image is not appearing.

How to make it the image change to the 2nd image if mouse move over the image?

# Answer
> 3 votes
Display both images independently with something like this:

```
<div class="portfolio_area_left">
    <?php print theme('image_style', array('path' => $imageone, 'style_name' => 'image_800x600', 'attributes'=>array('alt'=>$title))) ?>
    <?php print theme('image_style', array('path' => $two, 'style_name' => 'image_800x600', 'attributes'=>array('alt'=>$title))) ?>
</div>

```

Then use jQuery for the hover/fade: http://jsfiddle.net/adeneo/xTw44/

---
Tags: nodes
---


# Question
Title: How to get all database which can be used in 'db_set_active'
Is there any way to list all possible database connections using Drush? I am debugging an application where db connections are not written in settings.php and I'm not able to find all possible connections. And in code I can see

```
$database = db_set_active('test');

```

Is there any way to list the db connection names like test, test1, test2? Any help is appreciated.

# Answer
> 4 votes
All database connection strings are in global $databases variable;

```
global $databases;
dpm($databases);

```

with drush:

```
drush php-eval 'global $databases; print_r($databases);'

```

# Answer
> 0 votes
I don't know if Drush is able to do it, but in Drupal 6 you might try to look for the global variable `$db_url` in your code using grep or similar:

The "Set up multiple databases on the fly" section on the documentation below explains how the connections are set, for both Drupal 7 and Drupal 6 and older:

https://www.drupal.org/docs/7/creating-custom-modules/howtos/how-to-connect-to-multiple-databases-within-drupal

For instance, for Drupal 6 you might find the following to define an alternative 'mydb' connection:

```
//set up the new database value
$db_url['mydb'] = 'mysql://user:pwd@localhost/anotherdb';

```

---
Tags: 6, database, drush
---


# Question
Title: How to put up a notification about scheduled maintenance?
I'm using Drupal 7.5 and I want to put up a notification about the website going into maintenance mode on x scheduled date and time. What is the best way to do this? Are there any built-in options for posting server maintenance notifications or must I create a custom block for it?

Forgive me for this super basic question, but I did a search and the other questions on this were more advanced.

Note: this site is run on a Commons Profile and developed by someone else.

# Answer
> 1 votes
### Reduce the risk of "*modulitis*"

As an alternative to the Scheduled Maintenance module, suggested in the previous answer, you can also use the Rules module for this. Instead of installing yet another module that you can only use for "*announcing scheduled maintenance*".

If you don't have Rules enabled yet, you can probably (actually: pretty sure) use it to implement lots of other features in your site. That will help to reduce the risk of your site suffering "***modulitis***", aka "*way too much contributed modules that slow down a site*").

### Creating a custom Rule

Have a look at this custom rule (in Rules export format):

```
{ "rules_announce_scheduled_maintenance" : {
    "LABEL" : "Announce scheduled maintenance",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "data_is" : {
          "data" : [ "site:current-date" ],
          "op" : "\u003E",
          "value" : 1477639800
        }
      },
      { "data_is" : {
          "data" : [ "site:current-date" ],
          "op" : "\u003C",
          "value" : 1477726200
        }
      },
      { "user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "2" : "2" } }
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "\u003Cstrong\u003EMaintenance upcoming!\u003C\/strong\u003E Please note that access to this site will be limited due to scheduled site maintenance.",
          "type" : "warning"
        }
      }
    ]
  }
}

```

If you have the Rules UI enabled, you can import the above rule in your own site. Some details about what this rule actually does:

* The rule is triggered (= Rules Event) for anything a user/visitor does in the site (because of Rules Event *Drupal is initializing* being used).
* The first 2 Rules Conditions check is the site's current time (in GMT) is between `2016-10-28 07:30:00` and `2016-10-29 07:30:00`.
* The 3rd Rules Condition verifies if the user is authenticated, so nothing happens for anonymous users. Remove or adapt this Rules Condition to fit your needs.
* If all Rules Conditions are satisfied, then the Rules Action will display a message (of type warning) with content like so:

`**Maintenance upcoming!** Please note that access to this site will be limited due to scheduled site maintenance.`

If you want, change the type of message from *Warning* to *Status* (= Information only), or to change the actual message content, which BTW can also include some HTML markup.

### How to use this rule

* Any time you have a maintenance window coming up, you only adapt the "from" and "to" dates in the Rules Conditions.
* You can either leave this rule enabled permanently, or you disable the rule and only enable it around the timeframe you want to show this maintenance message.
* After the "to" date/time has arrived, no more message will be shown. Even if you don't (or forget to) disable this rule.

### Possible improvements

You have all the power of Rules available to further improve this rule, e.g.:

* Only trigger this rule when (e.g.) "Content is viewed" (by replacing the Rules Event with any other event that fits).
* Only show it on selected pages (like the frontpage?).
* Send an eMail to an admin if special conditions are met.
* Refine the message being shown (e.g. with an hyperlink to a page with more details about scheduled maintenance).

# Answer
> 1 votes
Drupal Core has in built option to put site on maintenance but out of the box it does not have option to show maintenance message prior to scheduled date. In order to do that you can Scheduled Maintenance module.

> Scheduled maintenance allows users to schedule an upcoming maintenance and show site visitors a warning message in advance.

---
Tags: 7, notifications, maintenance-mode
---


# Question
Title: How to create a select box field to select from a filtered list of articles?
in this example, I want to make the select box to select from a filtered list of articles.

What is the proper way to customize the options available in this select box ?

# Answer
> 2 votes
### Step 1

To have such a list of articles that can be referenced, you should ***first*** (repeat: ***first***) create a view (with the Views module) to create a list of all the articles that are allowed to be selected. And the display type of such view must be an *Entity Reference* display.

### Step 2

Your select box field (to select from a filtered list of articles) should be field that looks like so:

* Field Name = Anything you want, eg `field_articles_list`.
* Field Type = Entity Reference, using these additional settings for it:

+ *Target type* = `node`
    + *Number of values* = `1` (probably, though something like "unlimited may do as well).
    + "Mode" (within "entity selection") = `Views: Filter by an entity reference view`. However, before you can select an appropriate view at this point (which is eligible to do so), you first need to create a view with an *Entity Reference* display, or add such a display to an existing view. In your case, you should select the view created in "Step 1".
    + Pick any of the other options to define this field as you see fit.

---
Tags: entities
---


title: Download library using Libraries CDN

text:
# Question
Title: Download library using Libraries CDN
Does anyone knows how to programmatically download a library from https://cdnjs.com using Libraries CDN ?

# Answer
> 0 votes
@cilefen is correct: The purpose of the Libraries CDN API module is not downloading a library, but making the libraries found on a CDN available for your site; if then you are using the Libraries API module, it avoid the needs to download the libraries you need.

> Libraries CDN API is an API module to query CDN services to **automatically provides libraries** on your site.

> t also provides an integration with Libraries API. If your module depends on a library that needs to be downloaded and installed in sites/all/libraries and if this library is also hosted on a CDN, this module allows you to use the CDN version of the library very easily, **without the need to download** the library.

# Answer
> 0 votes
While this is not the purpose of the Libraries CDN API Module, the module page does say that it's possible:

> Libraries CDN API is an API module to query CDN services to automatically provides libraries on your site.
>
> It is bundled with two CDN plugins: CDNJS and jsDelivr. Check the very simple API to understand how to query a CDN and how to create your own CDN plugins too.
>
> It also provides an integration with Libraries API. If your module depends on a library that needs to be downloaded and installed in sites/all/libraries and if this library is also hosted on a CDN, this module allows you to use the CDN version of the library very easily, without the need to download the library.
>
> Basically, the module alter the libraries array and adds variants to it, these variants gets their files from the cloud, the module is also able to download a local copy of the library.

Basic API information and examples are available on the module page.

---
Tags: theming
---


# Question
Title: How to copy taxonomy terms of a node into a textfield using rules?
So what are the steps for the Rules module to copy taxonomy terms of a node into a textfield?

How do you copy all the taxonomy terms of a node and populate a text field with them?

Note: I am testing search speed of views exposed filters. Instead of using relatioships I will create a field containing keywords of all other fields in a form of an "index" and I will search on that.

# Answer
> 0 votes
Well that was easy then.

Create a rule with this configuration.

1. Trigger the rule "After updating existing content" and "After saving new content".
2. IMPORTANT. Create a condition with "Entity is of bundle" and choose the desired Content Type. If you don't do this, not all the fields of the content type are exposed to rules for manipulation.
3. The Action is "Set Data Value" and as Data choose you text field (node:field-keywords in my case). For value choose your desired terms field (\[node:field-business-categories\] in my case).

Run a "Published" procedure on all desired nodes with VBO and you are done.

And here is the exported rule.

```
{ "rules_keyword_field_generation" : {
"LABEL" : "Keyword Field Generation",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"ON" : { "node_update" : [], "node_insert" : [] },
"IF" : [
  { "entity_is_of_bundle" : {
      "entity" : [ "node" ],
      "type" : "node",
      "bundle" : { "value" : { "business" : "business" } }
    }
  }
],
"DO" : [
  { "data_set" : {
      "data" : [ "node:field-keywords" ],
      "value" : "[node:field-business-categories]"
    }
  }
]

```

} }

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


# Question
Title: Hide the displayed article in a most viewed/popular sidebar
In an article panel page, i have a sidebar with the Most Viewed articles as per RAdioactivity module. If the main article that I am viewing is one of the Most viewed, I want to hide that article link in the sidebar but instead display the rest of the Most Viewed articles links. How can I do this using Panels, mini Panels, views?

# Answer
I figured it out by going to **Advanced** \> **Contextual Filter**. Choose **Content: Nid**. Then under "WHEN THE FILTER VALUE IS NOT AVAILABLE", pick "Provide default value", Type = 'Content ID from URL'. Under "**More**", check on 'exclude' checkbox.
> 0 votes

---
Tags: views, panels
---


# Question
Title: Rule fails to send email to billing address
I'm trying to create notification emails which are sent when the checkout has been completed. (Drupal Commerce module)

* I added a rule to send the email to site owner. It works.
* I created a new rule to send email to to the customer's billing address. I Used `[commerce-order:mail]` replacement pattern as suggested, but unfortunately the email fails to arrive.

What could cause this problem? I even considered add new data selectors, but couldn't find anything fitting to add.

# Answer
As per one of the comments below this question (which kept showing up as a question with no answers):

> It seems that for the email field an additional field was added to customer profile form. Thus obviously it couldn't be accessed.
>
> A solution which works is to continue using the "Account information" checkout pane instead.

Credits: Gugols
> 0 votes

---
Tags: commerce, rules, emails
---


title: Friendly error page to replace WSOD

text:
# Question
Title: Friendly error page to replace WSOD
This should be the easiest thing to do, but for some reason I just can't get it done.

I'm trying to get a friendly static error page to replace nasty 500 scenarios. For now I'm just trying to replicate a 500 situation on my local machine (Drupal 7 running on MAMP) by throwing in some crap characters on the top of my template.php in my theme, which does trigger a 500 situation, but for some reason the ErrorDocument directive in my `.htaccess` or Apache config file has no effect.

What I'm doing is quite simply this:

```
ErrorDocument 500 /500.html

```

And I have the simplest ever static html-page in the root of my site with the name of 500.html.

Still, when I intentionally break template.php, I get the dreaded White Screen Of Death instead of my nice friendly error page.

What am I doing wrong here? I've done this a billion times in non-Drupal setups but just can't get my head around this one.

# Answer
> 2 votes
500 error pages are strictly server error pages. Once the server hands off execution to PHP, Drupal/PHP are responsible for serving their own error page. **You might try telling Drupal to redirect the user to a custom error page, along with an HTTP 500 status header, when it receives certain errors within a `try...catch` block.**

However, **note that some WSODs can occur at the system level and they could cause a fatal error that immediately halts execution and possibly prevent the `catch` to execute**. One example of this is when your database is not properly tuned to handle queries of certain size (like when doing a Features revert all operation) - the database may choke up, giving you an insta-WSOD.

I'd say the best thing to do is check your apache, MySQL and PHP error logs, and try to isolate the root cause of WSOD on a case-by-case basis, as opposed to trying to cover them up with a pretty-error page. While the errors that cause the typical 500 server error pages sometimes are unavoidable, and having custom server error pages in production is feasible, having WSODs happening live is not.

It looks like you have the server error pages set up properly. You just need to make the distinction that typical server error pages != WSODs. Server error pages can be triggered because of high traffic and resource bottlenecks, but you shouldn't really be having WSODs happen in production, period. These typically happen because of poor coding, optimization or configuration. If you still see an WSOD, make sure you find (and solve) the root cause of the problem first, as opposed to trying to apply a band-aid to it.

# Answer
> 1 votes
Following, Theming the Drupal maintenance page, you can create the *maintenance-page.tpl.php* and *maintenance-page--offline.tpl.php* template files, and hard code some settings in the *settings.php* file.

It doesn't seem to matter what level `error_reporting` is set to or whether you have set `display_errors` to on or off. When you have a *maintenance-page--offline.tpl.php* file in place, Drupal will display this page when the database goes away. It doesn't matter what you have set at /admin/config/development/logging. If you just have syntax errors, which was the OP's situation, that won't actually trigger a 500: It's a 200 with a PHP error either displayed or hidden based on the `display_error` setting. There is no way, that I know of, other than to add your custom error handling logic throughout your custom code as needed.

# Answer
> 1 votes
You are getting WSOD because you turned error reporting off in php.ini. This is a security issue - if you have an error and hacker sees what it is, he may potentially use it to hack the site.

If you want to intercept the error, though, you need to enable showing the errors in **php.ini** (the example will only show serious errors):

```
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

```

And then, you can set the error documents in the htaccess file:

```
ErrorDocument 401 http://yourwebsite.com/error-401
ErrorDocument 403 http://yourwebsite.com/error-403
ErrorDocument 500 http://yourwebsite.com/error-500

```

Alternatively, you can specify the errors in Drupal's **settings.php** file.

In NGINX:

```
error_page 403 = /error.php?code=403;
error_page 404 = /error.php?code=404;
error_page 500 = /error.php?code=500;

```

Since you are running Apache in MAMP, set it in .htaccess. Remember that `AllowOverride` in apache config should be on (usually it is).

# Answer
> 0 votes
Have you turned error reporting on? (admin/config/development/logging -\> Set **All messages** for **Error messages to display**)

By default, Drupal shows a WSOD as a security feature.

# Answer
> 0 votes
To replace all WSOD with something else would require hacking core: you do *not* want to do this. Drupal defines its own error handlers in bootstrap.inc and errors.inc. If you were to mess around with that code you would have to make sure you accounted for all the things that could be wrong when execution reached this stage (no database, no theme engine, no theme, no config, etc).

# Answer
> 0 votes
I made a sandbox project to do this.

I was able to accomplish this by extending the HttpExceptionSubscriberBase in /src/EventSubscriber/fivehundredEventSubscriber.php

```
    <?php
namespace Drupal\five_hundred\EventSubscriber;

use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Serializer\SerializerInterface;

class five_hundredEventSubscriber extends HttpExceptionSubscriberBase {

      public function __construct($stack) {

        if(
          (
            null !== $stack->getCurrentRequest()->attributes->get('exception')->getCode()
            && $stack->getCurrentRequest()->attributes->get('exception')->getCode() == 500
          )||(
            null !== $stack->getCurrentRequest()->attributes->get('exception')->getStatusCode()
            && $stack->getCurrentRequest()->attributes->get('exception')->getStatusCode() == 500
          )
        ){
            $response = new Response();
            $errorDocumentHtml = 'html here';
            $response->setContent($errorDocumentHtml);
            $response->setStatusCode(500, '500 Internal Server Error');
            $response->send();
            die();
        }
      }

      /**
       * {@inheritdoc}
       */
      protected function getHandledFormats() {
        return array('html','');
      }

    }
?>

```

And you'll need to add the service in your module.services.yml

```
services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }

```

---
Tags: .htaccess, wsod, http-request
---


# Question
Title: How to add first and last classes to local task items?
I'd like to add some classes to local task items, now there is only "active" class available which is pretty not flexible, I'd like to have "first" on first item and "last" on last item.

Tried `theme_menu_local_tasks()` and `theme_menu_local_task()`, neither of them work. And the post about "Add first and last classes to secondary local tasks" is probably for Drupal 6 so it's not working either.

# Answer
> 1 votes
You can use jQuery :first and :last selectors, example:

```
$('ul li:first').addClass(‘first’);
$('ul li:last’).addClass(‘last’);

```

Or you can use CSS :first-child and :last-child selectors, example:

```
li:first-child { add your css here }
li:last-child { add your css here }

```

The CSS way will give better performance.

# Answer
> 0 votes
You could use hook\_menu\_local\_tasks\_alter(). You can access all local tasks through the first parameter`$data` and you can add more class names to the option array `localized_options` of each tab.

```
function YOURMODULE_menu_local_tasks_alter(&$data, $router_item, $root_path){
    if(isset($data['tabs'][0])){
        $tabs =  $data['tabs'][0];
        $i = 1;
        foreach($tabs['output'] as &$t){
            if($i == 1) $class = 'first';
            elseif($i = $tabs['count']) $class = 'last';
            if(isset($t['#link']['localized_options']['attributes'])){
                $attributes = $t['#link']['localized_options']['attributes'];
                $attributes['class'][] = $class;
            }else{
                $attributes = array(
                    'attributes' => array(
                        'class' => array($class)
                    )
                );
            }
            $t['#link']['localized_options'] = $attributes;
            $i++;
        }
        $data['tabs'][0] = $tabs;
    }
}

```

If you don't want to loop through all local tasks for performance sake, you can directly update`$data['tabs'][0]['output'][0]` and `$data['tabs'][0]['output'][$data['tabs'][0]['count']-1]`. But you should check if the indexes exist, otherwise you will get **Warning: Undefined index...**

# Answer
> 0 votes
You may use the `nth-child` CSS 3 property if `.active` is not convinent:

```
p:nth-child(2) {
  background:#ff0000;
}

```

Source is MDN.

---
Tags: 7, theming
---


# Question
Title: How to create a content-type with "sub-pages" that are default and/or custom per node
I'm in the process of planning a Drupal 7 site-build that will make use of what we're calling 'sub-pages' or 'minisites.' Essentially, as you can see in the wireframe below, we'll have a page for each Doctor, and each doctor page will have a sub-nav.

---

Here are some requirements;

1. This sub-nav will link to pages with the url structure 'doctors/\[doctor-name\]/\[sub-page-title\]'.
2. Sub-pages like 'Biography' are populated via fields on the node.
3. Sub-pages like 'News' and 'Case Studies' are populated via contextual Views (based on references from these content types).
4. Sub-pages like 'Community' are completely custom and unique to each doctor. Another doctor may have a 'Family' sub-page instead.
5. The header above the sub-page should stay the same on every sub-page.
6. Content managers should be able to easily add additional custom sub-pages.
7. The site is being built utilizing the Panels suite (Panels Everywhere included).

What's the best way to accomplish this? I've fielded suggestions like 'use the Book module', but I wanted to get some feedback from the larger community before I start down a path that leads to a "90% solution."

# Update (Includes my solution)

I've decided to pursue the Organic Groups route, as OG and its suite of modules have value in other areas of the site's architecture. In order to meet my requirements I've had to introduce a few additional modules (benefits included);

* OG Menu
    + Configured to automatically create a menu for each 'Doctor' (an organic group).
* OG Menu: Default Links (Submodule)
    + Configured to provide default menu links to views standard for any Doctor. When a Doctor is created, they'll automatically have menu links like 'News' and 'Case Studies'.
* Rules
    + When my content managers create a new Doctor Page (organic group content to the Doctor Group), I made a custom rule that adds a menu link entry to the referred group menu (provided by OG Menu).
* Sub-pathauto
    + We want URLS that are aliased to match the pattern 'doctors/\[doctor-name\]/\[doctor-page-title\]'. This modules lets me do that easily (doctor/\[node:og\_group\_ref\]/\[node:title\]).
* OG Role Override
    + I need all content managers to edit and assign content to all Doctor groups. This module lets me do that easily.
* Panels
    + General layout, but also overriding layout for Doctor Pages and default links that direct to views.

All-in-all, I have exactly what I need and didn't write a line of code.

# Update Nov 16

This feature was sent out to pasture. Sad Panda. :\`(

# Answer
> 2 votes
Everything you've described is done by OG (Organic Groups).

OG is originally designed for GROUPS to have 'private' sections of a website, or to manage how groups manage different parts of a website, but the side effect of that allows you to build highly contextual "sub sections" of a website just like you're describing.

All of the 'contextual' stuff you mention. Site side branding, sub section branding, site wide menus, section based menus. Are covered by OG.

Good luck!

# Answer
> 2 votes
For Drupal 7 and 8, and alternative to Organic Groups is the Group module. https://www.drupal.org/project/group Here is a blog post about the benefits of Group over OG: https://www.deeson.co.uk/labs/group-alternative-organic-groups

As suggested in comments to this post: here is a link to questions about group module: https://drupal.stackexchange.com/questions/tagged/group

# Answer
> 1 votes
Depends a bit on your desired workflow and complexity. If you only need this might be simpler to just have another content type that has a entity reference (ie field\_parent) to the doctor's page. Then a hook menu alter to add it to the submenu/a auto path seeingwith tokens to generate a sensible path. OG may do it better but may also add more overhead.

---
Tags: 7, entities, panels, organic-groups, navigation
---


title: Same path for different domains

text:
# Question
Title: Same path for different domains
I have Drupal 7 with Domain Access on it. On the main domain i have an About us page with the path www.example.com/about-us

How can i get same "/about-us" path on several subdomains like domain.example.com/about-us, domain2.example.com/about-us etc. to point to different nodes?

# Answer
> 0 votes
One possible option to create a view page (/about-us) and under filter option make it available on this domain and content type (create a content type for about us and place all about us content under it).

---
Tags: path-aliases, domain-access
---


# Question
Title: How to keep "active" css on menu item when clicking on other link on same page?
I have an issue with my main menu. When you click on the "Cases by Topic" menu item, you are taken to the "Cases by Topic" page. The "Cases by Topic" menu item is then given the css class "active". I set it up so if a menu item has "active" css it is dark blue, rather than light blue to indicate it is the current menu item.

The page it's self has a drupal block that has a bunch of taxonomy menu items. Each one of these taxonomy menu items also point to this page but will load a different set of information in the page (which is a drupal view).

When they click on a taxonomy link in the block it reloads the page, but then the "Cases by Topic" main menu item no longer has the "active" css class on it.

Here is a picture example:

The user clicks on the "Cases by Topic" main menu item and the page loads. At this point the "Cases by Topic" menu item has the 'active' css class. The user then clicks on a taxonomy link in the drupal block ("Access to Information").

The same page reloads, but now the "active" css is on the taxonomy link and not the main menu "Cases by Topic" menu item.

I would really like to have the "active" css class stay on the "Cases by Topic" main menu item, even when people click the links in the taxonomy block.

At the very least I would not have the taxonomy link just clicked have "active" css and "Cases by Topic" should keep that css class.

Any ideas?

# Answer
> 1 votes
You could consider using jQuery client-side to set the class based on path. See this post on how to do that: http://www.itworld.com/article/2832973/development/setting-an-active-menu-item-based-on-the-current-url-with-jquery.html

or you could try using Menu Trail By Path module https://www.drupal.org/project/menu\_trail\_by\_path

# Answer
> 0 votes
Borrowed from here: This deals with hover, but you should be able to modify the principles to work for you. With this you could create css that functions on the taxonomy menu item being active.

```
When I hover over a div or class with an id of "a", can I get the background color of a div or class with the id of "b" to change?

Yes, you can do that, but only if #b is after #a in the HTML.

If #b comes immediately after #a: http://jsfiddle.net/u7tYE/

#a:hover + #b {
    background: #ccc
}

<div id="a">Div A</div>
<div id="b">Div B</div>
That's using the adjacent sibling combinator (+).

If there are other elements between #a and #b, you can use this: http://jsfiddle.net/u7tYE/1/

#a:hover ~ #b {
    background: #ccc
}

<div id="a">Div A</div>
<div>random other elements</div>
<div>random other elements</div>
<div>random other elements</div>
<div id="b">Div B</div>
That's using the general sibling combinator (~).

Both + and ~ work in all modern browsers and IE7+

If #b is a descendant of #a, you can simply use #a:hover #b.

ALTERNATIVE: You can use pure CSS to do this by positioning the second element before the first. The first div is first in markup, but positioned to the right or below the second. It will work as if it were a previous sibling.

```

# Answer
> 0 votes
Future readers may be interested in controlling the active trail with the module: menu\_position

> Often times site builders want certain types of content to appear in a specific position in the navigational menu. The simplest solution, adding all of that content individually to the menu system, has performance and usability issues. (Imagine hundreds of menu items added to one spot in the menu.)
>
> This module allows for the creation of rules that will dynamically add the current page into the menu system at the requested spots.
>
> This includes affecting:
>
> * The main links of the theme
> * The secondary links of the theme
> * The breadcrumb trail
> * Menu blocks provided by core's Menu module
> * Menu blocks provided by the Menu Block module

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


title: Entity Reference returns blank

text:
# Question
Title: Entity Reference returns blank
I have a content type where users upload a file. An administrator then uses a select list which is an Entity Reference that assigns the node to another user with a specific role. They do there work on the file and upload their work. The issue is, when the second user saves the node the entity reference gets blanked. Using version 7.51

How can I insure that the field stays populated through the whole process?

Thanks

# Answer
> 0 votes
Try using the Field Permissions module and only allow admin to edit and view value for the entity reference field.

---
Tags: nodes
---


# Question
Title: How to prevent users from adding content without putting the site into full maintenance mode?
We are planning a scheduled update of our site. There is no reason for people to not be able to see the site as anonymous users, or even browse their account if they want to log in.

How can I simply prevent people from adding new content while I do the updates instead of having the site completely down from having to use maintenance mode?

# Answer
I would uncheck the "add \[type\] content" permissions checkboxes on the roles that have it, and re-check them after. However, depending on the updates, having people attempting to log in or use other features of your site may be problematic during updates.
> 3 votes

# Answer
I would not recommend this but if I would do it I would disable the login form and remove all sessions from the database. No users are logged in now so there can not be any changes been done to the database. During maintance I would how ever recommend to minimize the risk (on eg conflicts) so putting it in maitance mode still have my preference.

edit: just read the comment about read only mode module, didnt knew that module sounds interesting :)
> 1 votes

# Answer
You can also use the Rules module for this. If you don't have Rules enabled yet, you can pretty sure use it to implement lots of other features in your site. That will help to reduce the risk of your site suffering "***modulitis***" (= *way too much contributed modules slowing down a site*).

Have a look at this custom rule (in Rules export format):

```
{ "rules_disallow_updates_to_content" : {
    "LABEL" : "Disallow updates to content",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "OR" : [
          { "text_matches" : {
              "text" : [ "site:current-page:path" ],
              "match" : "node\/add\/",
              "operation" : "starts"
            }
          },
          { "text_matches" : {
              "text" : [ "site:current-page:path" ],
              "match" : "\/edit",
              "operation" : "ends"
            }
          },
          { "text_matches" : {
              "text" : [ "site:current-page:path" ],
              "match" : "\/delete",
              "operation" : "ends"
            }
          }
        ]
      },
      { "NOT user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "3" : "3" } }
        }
      }
    ],
    "DO" : [
      { "drupal_message" : {
          "message" : "\u003Cstrong\u003EMaintenance ongoing!\u003C\/strong\u003E, therefor a path like [site:current-page:path] is currently not allowed.",
          "type" : "error"
        }
      },
      { "redirect" : { "url" : "no_access" } }
    ]
  }
}

```

If you have the Rules UI enabled, you can import the above rule in your own site.

Some details about what this rule actually does:

* The rule is triggered (= Rules Event) for anything a user/visitor does in the site (because of Rules Event *Drupal is initializing* being used).
* The first 3 Rules Conditions check if the current path fits any of these patterns (remove or adapt these Rules Conditions to fit your needs, or add similar ones):
    + Starts with `node/add/`.
    + Ends with `/edit`.
    + Ends with `/delete`.
* The last Rules Condition checks that the user does NOT have role "admin" (so that admin will not be blocked by this rule in case of emergencies), adapt the role id if needed, or simply remove this condition if this exception handling is not desired.
* If all Rules Conditions are satisfied, then these Rules Actions will be performed:

+ display a message (of type warning) with content like so (with the token replaced by the actual path): `**Maintenance ongoing!**, therefor a path like [site:current-page:path] is currently not allowed.`. If you want, change the actual message content, which BTW can also include some HTML markup.
    + Perform a redirect to path `no_access` (adapt to fit your needs).

All it takes to use this rule is to enable the rule while maintenance is ongoing (and disable the rule when maintenance is finished).

### Possible improvements

You have all the power of Rules available to further improve this rule, e.g.:

* Send an eMail to an admin if special conditions are met (eg to eMail data about the actual user who was blocked by this rule).
* Refine the message being shown (e.g. with an hyperlink to a page with more details about scheduled maintenance).
> 1 votes

---
Tags: 7, maintenance-mode
---


title: Lock configurations

text:
# Question
Title: Lock configurations
I have EForm module installed on my Drupal 8 website. My customer uses EForm module to create new forms. The problem is that newly created forms are storing in configurations. Every time I deploy my code to the production instance I deploy it without configurations for newly created forms and when I do sync on the production it deletes forms that were added by the customer since they are not in my configurations. Now I need to download latest backup from the production to keep customers forms and it is very annoying. So I wonder is there any way to lock particular configurations in Drupal 8 either using contrib module or programmatically.

I've found Configuration Read-only mode module but it locks all configurations but not particular one.

# Answer
> 1 votes
What you can do is to use `--skip-modules` if you sync configuration with drush. You can even put it in a `drushrc` file so you don't need to remember it.

Doing will will make drush skip the sync of the entire module. It's not possible to omit only some config files, like a reg ex pattern etc.

# Answer
> 1 votes
You could have a look at the drush CMI tools recently published by PreviousNext: https://www.previousnext.com.au/blog/introducing-drush-cmi-tools

That allows you to have exclude patterns of certain config, so they're not maintained with git at all.

I don't use them yet. My workflow is basically to do new development in a separate branch, staging or something else. Then before the deployment, I export production config, sync it back to local, commit that, merge in your branch that contains the new config, resolve possible merge conflicts, deploy, run drush cim and verify that there are only expected config changes.

It's not perfect, there is a possibility that a config change happens right between those steps, but it is rather unlikely and in the case of contact forms or eforms, easy to spot.

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


# Question
Title: how to remember results of a views query in rules
I have a site with an eva view that is embedded into a view page that is directly accessible, running the query for the first time. To that I have added rules\_views, I want to e-mail out certain fields values of the view when the user requests it using a flag. (as the trigger) But I want to e-mail the field values out after the query is first run, with the original values. I want to preserve the state.

What is the best way to do this?

# Answer
As a possible alternative to make this work (instead of using Views Rules), you may want to give it a try to *process the results of a VBO enabled view via Rules*, whereas your rule performs 2 Rules Actions:

* Load the VBO list that you want to be processed.
* Add a loop to perform a Rules Action, for each row contained in your Views results.

For more details, have a look at the tutorial "How to process the results of a VBO enabled view via Rules?".

To actually trigger such Rules Action, you should be able to use a Rules Event like "*... when the user requests it using a flag.*" (as in your question).
> 0 votes

---
Tags: rules, views, cookies
---


title: Payment methods not showing

text:
# Question
Title: Payment methods not showing
I've installed - drupal commerce + paypal + payment + commerce payment- modules. Commerce seems to be working fine with regards adding and displaying products. But in 'configuration', there is no list item there that says 'payment methods'. I've enabled all related modules, so 'paypal wpp' and '..wps' etc. Also installed and enabled 'payment' and payment commerce'. What am I missing?

Any help would be great,thanks Jon

# Answer
Drupal Commerce payment methods can usually be found at /admin/commerce/config/payment-methods. They are rules in fact. If for any reason that menu doesn't exist, check your rules.

To get that menu you need ro enable Payment UI module.

You also need to properly enable and setup your checkout panes at admin/commerce/config/checkout
> 1 votes

---
Tags: commerce, payment-gateways
---


# Question
Title: How can I check in Rules if the number of members is below 50 or not?
I need to add some user points to users when they signup to the site. Using the Rules module I already provided that functionality. But problem is to add some less points after 50 members have signed up.

So how can I implement a condition to differentiate the people that are registered:

* first 50 members means `Sign-up (first 50 = 20,000)`.
* after 50 members add `3000 points to user signup` .

Anyone suggestions?

# Answer
> 1 votes
You need get the count of the total users so far from the users table. To do that, you can use a condition with php code where you have to write a `db_query("SELECT COUNT(*) FROM users"); //[not tested]`

if result gets number of existing users. you can return true/false to go to the action in order to assign points.

Let me know if you got it working.

# Answer
> 0 votes
You can make this work by using Rules in combination with the Views Bulk Operations module, as further detailed below.

### Step 1

Use the Views Bulk Operations module to create a view of all your users, in which you add a VBO field to it. Simply include a field like `uid` for each user (no need for any other fields). Just make sure you get exactly 1 row for each user you want to take into consideration (eg: also count `user/1`?).

### Step 2

Create a 1st Rules Component with a Rules Condition "***Check number of results returned by a VBO view***". And select the VBO view created in the previous step. If the number of results is 50 or less, then perform a Rules Action (in that Rules Component) to grant 20,000 points (similar to what your current rule already does).

### Step 3

Create a 2nd Rules Component which is similar to the Rules Component from Step 2, but in this component the logic is like so: if the number of results is 51 or more, then perform a Rules Action (in that Rules Component) to grant 3,000 points.

### Step 4

Replace your existing Rule like so:

* Keep the same **Rules Event** (= when users signup to the site).
* Don't use any **Rules Conditions** (there is no need for them in this rule).
* Perform 2 **Rules Actions**:
    + Execute the Rules Component from Step 2.
    + Execute the Rules Component from Step 3.

***Done!***

---
Tags: users, rules, userpoints
---


title: Remove content from a view

text:
# Question
Title: Remove content from a view
I have a Master view & numerous child views for the same content type. The Master View has all nodes from the content type. The content gets copied to the child view from the master view basis of specific requirements by the user. I want to have the functionality to remove specific content from the child views. I do not want to delete it as the content would be reused for others from the Master View.

Is there any module to achieve this?

I am not developer.

# Answer
When you click on a field or a setting. At the very top, you need to use the **For** "override" option. (select `This [view type] override`) so it only affects your current view.
> 1 votes

---
Tags: views
---


title: Guzzle settings (base_url, user agent)

text:
# Question
Title: Guzzle settings (base_url, user agent)
I'm searching a way to configure Drupal's HTTP Client Guzzle. I.e. the base\_url and user agent.

The Guzzle docs provide info here: http://docs.guzzlephp.org/en/latest/quickstart.html#creating-a-client

But nothing that works with the Drupal implementation.

I can see in core/lib/Drupal/Core/Http/ClientFactory.php that there is a default config with which the Guzzle Client constructor is fed.

```
//Line 46-65:

public function fromOptions(array $config = []) {
    $default_config = [
      // Security consideration: we must not use the certificate authority
      // file shipped with Guzzle because it can easily get outdated if a
      // certificate authority is hacked. Instead, we rely on the certificate
      // authority file provided by the operating system which is more likely
      // going to be updated in a timely fashion. This overrides the default
      // path to the pem file bundled with Guzzle.
      'verify' => TRUE,
      'timeout' => 30,
      'headers' => [
        'User-Agent' => 'Drupal/' . \Drupal::VERSION . ' (+https://www.drupal.org/) ' . \GuzzleHttp\default_user_agent(),
      ],
      'handler' => $this->stack,
    ];

    $config = NestedArray::mergeDeep($default_config, Settings::get('http_client_config', []), $config);

    return new Client($config);
  }

```

Any way to reconfigure this?

`\Drupal::httpClient()` does not provide any parameters for configuration.

# Answer
> 8 votes
You may add your own factory and corresponding service.

```
# Service definition in YAML.
services:
 my_module.client:
   class: GuzzleHttp\Client
   factory: my_module.client.factory:get
 my_module.client.factory:
   class: MyModule\ClientFactory

```

And the corresponding PHP (example).

```
class ClientFactory {

  /**
   * Return a configured Client object.
   */
  public function get() {
    $config = [
      'base_url' => 'https://example.com',
    ];

    $client = new Client($config);

    return $client;
  }
}

```

However you can set the URL and Header in the request itself so this is not actually necessary. See Request Options.

```
$options = [
  'headers' => [
    'User-Agent' => 'Foobar 1.0'
  ]
];
$response = $client->request('GET', 'https://example.com/api/endpoint', $options);

```

One reason why you might want to use a factory is to inject the ConfigFactory or LoggerFactory to add various options.

However in a unit test it probably makes sense not to call the class from the service container so that you may add the quirky MockHandler (Guzzle developers decided on a non-standard way of mocking because).

```
$mock = new MockHandler([new Response(200, ['Content-Length' => 0])]);
$options = [
  'handler' => HandlerStack::create($mock)
];
$client = new \GuzzleHttp\Client($options);

```

My preference is to create the factory class. Add a unit test for the factory class that correctly instantiates, and then add unit tests that create the client class directly if I'm testing a custom client that extends GuzzleHttp\Client.

As suggested by gapple in their answer, you may also forgo creating your own Factory class, and instead use the `http_client_factory` service provided by Drupal 8 core to create a one-off custom Client via the `ClientFactory::fromOptions()` method. Or you can add default configuration to your `settings.php` file under `$settings['http_client_config']`.

# Answer
> 12 votes
There is no need to create your own Client or ClientFactory service.

Because `ClientFactory::fromOptions()` has

```
$config = NestedArray::mergeDeep($default_config, Settings::get('http_client_config', []), $config);

```

You can specify default options to Guzzle for all clients created by Drupal via your settings.php. Core only provides an example of proxy settings, but you could alter the user agent via

```
$settings['http_client_config']['headers']['User-Agent'] = 'Foobar 1.0';

```

---

To create a single client with different options, (which will override settings from both `ClientFactory::fromOptions()` and settings.php), you can use the factory service directly:

```
\Drupal::service('http_client_factory')->fromOptions([
  'headers' => ['User-Agent' => 'Foobar 1.0'],
]);

```

---
Tags: 8
---


# Question
Title: How to show a block on specific content type and combine it with path restrictions
How do I show a block on all nodes of content type A, without restricting it to other "pages"? I already have some restrictions based on the path. The problem is that by using the settings under Visibilty \> Content Type, the block disappears from other places where the block is defined. I want to combine it with showing this block on all nodes of Content Type A.

# Answer
> 3 votes
With D8 you can make multiple instances of the same block, just use Place Block to place another copy of it. Then you can have one display on the specific content types, and the other display on the pages you need.

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


# Question
Title: How do I include a Javascript Library from a Twig Extension in Drupal 8?
I have a custom Twig Extension that needs to add a Javascript library **ONLY** when the Twig Extension is used.

Here is my `modules/custom/MY_MODULE/MY_MODULE.libraries.yml`:

```
my-twig-extension:
  version: VERSION
  js:
    js/myTwigExtension.js: {}
  dependencies:
    - core/jquery

```

Here is my `modules/custom/MY_MODULE/js/myTwigExtension.js` (just for testing):

```
console.log("Hello World!!! at " + Date.now());

```

In my `modules/custom/MY_MODULE/src/TwigExtension.php` I define the extension here:

```
public function getFunctions() {
    return [
        new \Twig_SimpleFunction('MY_MODULE_widget', [$this, 'MY_MODULEWidget']),
    ];
}

```

and then it's function:

```
public function MY_MODULEWidget($MY_VARIABLE)
{
    return array(
            '#theme' => 'twig_extension_MY_MODULE_widget',
            '#MY_VARIABLE' => $MY_VARIABLE,
            );
}

```

The `#theme` above is correctly loading my file here `modules/custom/MY_MODULE/templates/twig_extension_MY_MODULE_widget.html.twig`:

```
<div class="MY_CLASS" data-MY_VARIABLE="{{ MY_VARIABLE | url_encode }}">Loading Widget...</div>

```

### Attempt 0:

Added the following twig function to `modules/custom/MY_MODULE/templates/twig_extension_MY_MODULE_widget.html.twig`:

```
{{ attach_library('MY_MODULE/my-twig-extension') }}

```

but that did not work.

### Attempt 1:

Tried adding the library in the render array:

```
public function MY_MODULEWidget($MY_VARIABLE)
{
    return array(
            '#theme' => 'twig_extension_MY_MODULE_widget',
            '#MY_VARIABLE' => $MY_VARIABLE,
            '#attached' => array(
                'library' => array(
                    'MY_MODULE/my-twig-extension',
                    ),
                ),
            );
}

```

but it doesn't look like `BlockBase` logic is supported here to load the library.

### Attempt 2:

I looked at how the Twig function `attach_library` works and saw how in `Drupal\Core\Template\TwigExtension::attachLibrary($library)` worked and tried to implement it here like this:

```
public function MY_MODULEWidget($job_name)
{
    static $doOnce = true;
    if ($doOnce) {
        $doOnce = false;

        /* @var $renderer Drupal\Core\Render\Renderer */
        $renderer = \Drupal::service('renderer');
        $template_attached = ['#attached' => ['library' => ['MY_MODULE/my-twig-extension']]];
        $renderer->render($template_attached);
    }

    return array(
            '#theme' => 'twig_extension_adicio_rated_job_widget',
            '#job_name' => $job_name,
            );
}

```

... with the idea of including the library the first time the Twig Extension was called. But no go.

**IMPORTANT:** yeah I know I can add the following to my `module/custom/MY_MODULE/MY_MODULE.info.yml`:

```
libraries:
  - MY_MODULE/my-twig-extension

```

but I do not want to load this library (very expensive logic), to every page.

Any assistance would be greatly appreciated. Thank you.

# Answer
**Partial Answer that works**

... but I don't like it because the list of paths in the config never gets reset. I think I need to figure out how to do *Cache Contexts* for a proper answer.

In my `modules/custom/MY_MODULE/src/TwigExtension.php` file:

```
class TwigExtension extends \Twig_Extension
{
   const CONFIG_KEY_NAME = 'MY_CONFIG_NAME';
...
    public function MY_MODULEWidget($MY_VARIABLE)
    {
        /* @var $config Drupal\Core\Config\Config */
        $config = $this->configFactory->getEditable($this->getName() . '.settings');

        $paths = (array)$config->get(self::CONFIG_KEY_NAME);

        /* @var $currentPath string */
        $currentPath = \Drupal::service('path.current')->getPath();        // returns '/node/47446' not the alias

        if (in_array($currentPath, $paths)) {
            // Good
        } else {
            // Add $currentPath to config
            $paths[] = $currentPath;
            $config->set(self::CONFIG_KEY_NAME, $paths)->save();
        }

        return array(
                '#type' => 'inline_template',
                '#template' => '<div class="MY_CLASS" data-MY_DATA="{{ MY_VARIABLE }}">Loading Widget ...</div>',
                '#context' => array(
                    'MY_VARIABLE' => $MY_VARIABLE,
                    ),
                );
    }
}

```

The above code will add the current path to a config. Unknown if there's an upper limit to the size of the data in the config; however, in my implementation the number of pages that this is on will be small (\< 100).

Then once the path is added to the module's config setting then we read it to conditionally add a library like this using `hook_page_bottom()` like this in my `modules/custom/MY_MODULE/MY_MODULE.module` file:

```
/**
 * Implements hook_page_bottom
 */
function MY_MODULE_page_bottom(array &$page_bottom)
{
    /* @var $paths array of strings */
    $paths = (array)\Drupal::config('MY_MODULE.settings')->get(Drupal\MY_MODULE\TwigExtension::CONFIG_KEY_NAME);

    /* @var $currentPath string */
    $currentPath = \Drupal::service('path.current')->getPath();     // like '/node/47446', not the Alias

    if (in_array($currentPath, $paths)) {
        // Include the library that will modify jQuery(".MY_CLASS")
       $page_bottom['MY_MODULE']['#attached']['library'][] = 'MY_MODULE/my-twig-extension';
    }

}

```

**EDIT 0**

Added a `hook_build()` to my module like this so I could clear the setting manually:

```
function MY_MODULE_rebuild()
{
    /* @var $config Drupal\Core\Config\Config */
    $config = \Drupal::service('config.factory')->getEditable('MY_MODULE.settings');

    $config->clear(Drupal\MY_MODULE\TwigExtension::CONFIG_KEY_NAME);

    $config->save();

}

```

Note: $config support fluid interface (e.g. $config-\>clear(...).

I will still not accept my answer because I still believe I should be using *Cache Context* for this.
> 1 votes

---
Tags: 8, theming
---


# Question
Title: "Is all of" view search doesn't work with the module "Better exposed filter"
* Drupal version : 8.2.0
* Module "Better exposed filter" version : 8.x-3.0-alpha1

**In short :**

I created a view with an exposed filter. When I use the operator "is all of" from my exposed filter, all works. My exposed filter shows some tags in a select/option html list. I downloaded and installed the module "Better exposed filter" for display my exposed filter in checkbox instead the select/option html list. If I configure my exposed filter for it display checkboxs, then the view displays no result.

**In detail :**

I created 3 simples contents of type 'articles' :

* Recipe one (tags 'ingredients' : salt, sugar )
* Recipe two (tags 'ingredients' : super, pepper )
* Recipe three (tags 'ingredients' : pepper, salt )

I created a very simple view :

When I do a search, I get two of my articles if I select the tag "sugar" with the exposed operator "is all off" : (look the Query, **only one "INNER JOIN"**)

Tags exposed filter is an html select/option list. I want to change this style by a list of checkboxs. So, I configure the filter style with the "better exposed filter" module :

When I do that, my view works when I search with the filter exposed operator "is one of". But when I use the filter exposed operator "is all off", no result displayed !

In the new query, I noticed there are two "INNER JOIN". The second uses an id = 0, the error must be here.

My questions are :

* Do I forget something in my configuration ?
* Is a bug in the module "better exposed filter" ?
* What should I do to operate the operand "is one off" when I display it in list of checkboxs ?

# Answer
No, It's a bug with the Better Exposed Filter module. From the looks of it, something is causing a '0' value to be added as a part of the `WHERE` clause.

You can see this in action by toggling the **Allow multiple selections** filter option; when the option is off you can select a non *\- Any -* value to filter the view as expected; when the option is on any selection appends '0' value to the filter.

From looking at your linked issues, they look potentially related but not the same. You should look through the BEF module issue queue and if it's not posted yet, post it there to be reviewed.
> 0 votes

---
Tags: 8, views
---


title: Get taxonomy terms by taxonomy term id

text:
# Question
Title: Get taxonomy terms by taxonomy term id
When I'm on a taxonomy term page, I want to list all my taxonomy in that vocabulary.

So I have a taxonomy term ID in the URL. I need to lookup which vocabulary has this value, than list all the values of that vocabulary.

# Answer
You'll need a *Taxonomy Term* view with a *Taxonomy vocabulary: Vocabulary ID* contextual filter.

The problem here is there isn't a core-provided argument plugin for a default value. The closest thing is the *Taxonomy term ID from URL provider*, but it supplies the *Term ID*, not the *Vocab ID*. So you can:

1. Use the *PHP Code* plugin provided by Views to retrieve the term ID and return the vocab ID. (Not recommended, as it could cause various problems & won't be compatible with D8).
2. Implement a custom module with views integration via `hook_views_plugins()` and a handler that extends the `views_plugin_argument_default` class. (You can use the Views module's `views_plugin_argument_default_taxonomy_tid` provider as an example).
> 0 votes

---
Tags: 7, views
---


# Question
Title: Role Hierarchy and Management of Assigned Users
I need to set up a role hierarchy like this:

* Super Admin - Full permissions, can manage all users and content
* + Regional Manager - can manage only his/her own Store Managers; cannot manage another regional manager's Store Managers. Can manage those users' content as well.
* + - Store Manager - can manage only his/her own employees; cannot manage another store manager's employees. Can manage those users' content as well.
* + - * Employee - the low-end of the totem pole. All they can do is create content of a certain type.

How can I go about setting that up?

Thanks!

# Answer
**Drupal Role Hierarchy**

Drupal has a robust and modular permission system. You create roles, give permissions to roles and assign users one or more roles. The modules that give the site different functionalities define the permissions and use the user\_access() function to ask Drupal if the current user has a specific permission. To clarify how Drupal manages permissions lets set an example:

We have a very basic site that uses the taxonomy module, this module lets users categorize the content. Lets say we have a user called john assigned a role called Editor. Drupal uses a static variable called $perm, this variable is an array of the different permissions the current logged in user has. When we execute user\_access Drupal only checks if the $perm array contains the permission we send as a parameter.

The taxonomy module only defines one permission called “Administer taxonomy”, if the Editor role has this permission then john’s $perm variable will include the string “Administer taxonomy”. When we try to access the administer taxonomy page the taxonomy module will call the user\_access function sending ‘Administer taxonomy’ as the parameter. If we log in as john the function will return true and we will be able to access that page. This is a very simple example and will meet all the requirements a basic site needs because these kind of sites usually just have one or two editors.

When developing sites that are managed by more people the permissions need to be handled in a more complex way. We wish we could have a hierarchy of roles so that permissions can be inherited and we can move roles around the hierarchy tree just like we can with taxonomy terms. This is not a feature that Drupal has out of the box. Drupal only has two levels in their core role hierarchy and the permissions are inherited throughout these roles. Some of you that have used Drupal long enough know this already. The first level of Drupal roles are the default core Drupal roles that cannot be edited or removed: Anonymous and Authenthicated. Any new role created will be created as child of the authenticated role and permissions given to this role will be inherited automatically by any new role created.

I’m yet to find a module that lets the administrator handle the roles in a hierarchical way and I believe the reason for this is because Drupal does not implement the db\_sql\_rewrite function when pulling permissions. This means that no other modules can rewrite the query that Drupal uses when loading the permissions. Want this in your site?? A module is on its way with it’s corresponding patch file.

This just started development and it will be available in the community in a short time. But just so you know, this change has also been suggested for Drupal 7 tho I am not sure if its gonna be considered.
> 1 votes

# Answer
You could try to use Organic Groups, it's a module used in many distributions, Open Atrium probably would be the most popular.

With OG you could create groups and assign permissions to create/update content only in those groups.
> 0 votes

# Answer
This sounds like a perfect usecase for the Group module, especially in combination with its Subgroup submodule, which ***allows a group to belong to another group***.

Some more details (from the Community documentation about subgroups):

> After the subgroup module has been activated you can use it by going to the group type config page (`/admin/group/type`), clicking 'config' on a group type (`/admin/group/type/manage/GROUPTYPE/config`), and then clicking on the small 'Subgroups' tab that appears (`/admin/group/type/manage/GROUPTYPE/config/subgroup`) as shown in this image also:
> 0 votes

---
Tags: 7, users
---


# Question
Title: What step am I missing installing drush with Composer?
From my project root, where composer.json and composer.lock are, I tell composer to require drush/drush. It seems to do what it should, but upon completion it seems drush is not installed.

```
$ composer require drush/drush
Using version ^8.1 for drush/drush
./composer.json has been updated
> DrupalProject\composer\ScriptHandler::checkComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing webmozart/path-util (2.3.0)
    Downloading: 100%

  - Installing symfony/var-dumper (v2.8.13)
    Downloading: 100%

  - Installing jakub-onderka/php-console-color (0.1)
    Downloading: 100%

  - Installing jakub-onderka/php-console-highlighter (v0.3.2)
    Downloading: 100%

  - Installing dnoegel/php-xdg-base-dir (0.1)
    Downloading: 100%

  - Installing nikic/php-parser (v2.1.1)
    Downloading: 100%

  - Installing psy/psysh (v0.7.2)
    Downloading: 100%

  - Installing pear/console_table (v1.3.0)
    Downloading: 100%

  - Installing consolidation/output-formatters (1.1.0)
    Downloading: 100%

  - Installing consolidation/annotated-command (1.4.1)
    Downloading: 100%

  - Installing drush/drush (8.1.5)
    Downloading: 100%

Writing lock file
Generating autoload files
> DrupalProject\composer\ScriptHandler::createRequiredFiles

$ drush
The program 'drush' is currently not installed. You can install it by typing:
sudo apt install drush

```

# Answer
> 1 votes
Well, actually you installed it locally. You can find it in your project's directory under vendor/drush/drush place (maybe, it depends where the composer put it). You can call only from that place because it's not in your global path. If you want to use this method, you need to call it with an absolute or relative route. Like if your composer installed to here:

On Windows: D:/phptest/my\_project/vendor/drush/drush

On Linux: ~/my\_project/vendor/drush/drush

and you are in the D:/phptest/my\_project (Windows) or ~/my\_project (Linux) dir, in that case, you need to call it like:

On Windows: vendor/drush/drush --version OR D:/phptest/my\_project/vendor/drush/drush --version

On Linux: vendor/drush/drush --version OR ~/my\_project/vendor/drush/drush --version

and you will get something like:

Drush Version : 8.1.3

Of course for this, you need a PHP in the global path. (so you need to be able to call PHP from anywhere.)

If you installed it globally with composer (I think you just installed it locally), in that case maybe you need to create a (soft) symlink one place which is globally available for you (listed in the %PATH% variable on windows or in the $PATH variable on Linux), or you need to add the drush's dir to your global path variable.

I suggest you, install it globally, like here is written: https://docs.drush.org/en/8.x/install/

```
# Browse to https://github.com/drush-ops/drush/releases and download the drush.phar attached to the latest 8.x release.

# Test your install.
php drush.phar core-status

# Rename to `drush` instead of `php drush.phar`. Destination can be anywhere on $PATH.
chmod +x drush.phar
sudo mv drush.phar /usr/local/bin/drush

# Optional. Enrich the bash startup file with completion and aliases.
drush init

```

Then you can use it in any site's dir.

TIPP: if you're installing drush launcher (https://github.com/drush-ops/drush-launcher) globally, then you can have per-site base different drush installed. In this case, you don't need to have global drush installed.

# Answer
> 0 votes
Since you didn't use the `--global` option, Composer installed Drush in the vendor directory. More precisely, the Drush executable is on vendor/bin. If I run `vendor/bin/drush status`, I get the following output.

> Drupal version : 8.2.1
> Site URI : http://default
> Database driver : sqlite
> Database name : sites/default/files/.ht.sqlite
> Drupal bootstrap : Successful
> Drupal user :
> Default theme : bartik
> Administration theme : seven
> PHP executable : /usr/local/bin/php
> PHP configuration : /usr/local/etc/php/7.0/php.ini
> PHP OS : Darwin
> Drush script : /Library/Server/Web/Data/Sites/Default/vendor/drush/drush/drush.php
> Drush version : 8.1.5
> Drush temp directory : /tmp
> Drush configuration :
> Drush alias files :
> Install profile : standard
> Drupal root : /Library/Server/Web/Data/Sites/Default
> Drupal Settings File : sites/default/settings.php
> Site path : sites/default
> File directory path : sites/default/files
> Temporary file directory path : /tmp
> Sync config path : sites/default/files/config\_Dy0z5R0mB3fLiKC\_f8qR1UcV4HkXFeohO3KKXBcYUTWrsxunPXpZbezfqd39 mz4u0G7LVAYSmg/sync

I normally read they suggest installing Drush as you did, but you can also install it globally, with `composer --global require drush/drush`. On macOS Sierra, using that command installs Drush in ~/.composer/vendor/bin, which I then need to add to the Bash PATH with the following command.

```
if [ -d $HOME/.composer/vendor/bin ]; then
    export PATH=$PATH:$HOME/.composer/vendor/bin
fi

```

I didn't install Drush globally, but I added those lines in ~/.bash\_profile, in the case I globally install other commands with Composer.

---
Tags: drush, composer
---


# Question
Title: How to use User Points for storing Quiz scores?
How can I add points directly to the User Points database? I have a quiz site and would like to use the User Points module to store quiz scores, instead of creating something from scratch. I have created a taxonomy "Quiz" for such points.

Every quiz ends by showing the score made (between 0 to 100 depending on how many answers they got right). I would like to go on and store this in the userpoint database.

I am using the following code but I'm getting 2 error messages:

> Notice: Undefined variable: user in ...
> Notice: Trying to get property of non-object in ....

The code I am using is the following one:

```
$params = array (
  'uid' => $user->uid,
  'description' => 'Totals points from quizes',
  'points' => $percentage,
  'tid' =>127,
);

userpoints_userpointsapi($params);

```

# Answer
> 3 votes
Userpoints has an API.

See especially `userpoints_userpointsapi()` Something like this: `userpoints_userpointsapi(array('uid'=>$some_user, 'points'=>9000));`

You might also be interested in the Quiz module which supports Userpoints.

# Answer
> 0 votes
If you're using the 7.x-5.x version of the Quiz module, you can take advantage of the integration with the Rules module that this new Quiz release comes with (which was not in the 7.x-4.x version version), which doesn't require any custom code at all.

To do so, have a look at the delivered rule, which looks like so:

```
{ "rules_send_results_at_the_end_of_a_quiz" : {
    "LABEL" : "Send quiz results at the end of a quiz",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "TAGS" : [ "quiz" ],
    "REQUIRES" : [ "rules", "entity" ],
    "ON" : { "quiz_result_update" : [] },
    "IF" : [
      { "data_is" : { "data" : [ "quiz-result-unchanged:is-evaluated" ], "value" : "0" } },
      { "data_is" : { "data" : [ "quiz-result:is-evaluated" ], "value" : "1" } }
    ],
    "DO" : [
      { "mail" : {
          "to" : [ "quiz-result:uid:mail" ],
          "subject" : "[site:name]: Your results for [quiz-result:nid:title]",
          "message" : "[quiz-result:uid:name],\r\n\r\nYou finished the quiz [quiz-result:nid:title] on [quiz-result:time-start]\r\n\r\nYour score: [quiz-result:score]%\r\n\r\nYou can access the result here: [site:url]node\/[quiz-result:nid:nid]\/quiz-results\/[quiz-result:result-id]",
          "language" : [ "" ]
        }
      },
      { "mail" : {
          "to" : [ "quiz-result:nid:author:mail" ],
          "subject" : "[site:name]: [quiz-result:uid:name]\u0027s results for [quiz-result:nid:title]",
          "message" : "[quiz-result:nid:author:name],\r\n\r\n[quiz-result:uid:name] finished the quiz [quiz-result:nid:title] on [quiz-result:time-start]\r\n\r\nTheir score: [quiz-result:score]%\r\n\r\nYou can access the result here: [site:url]node\/[quiz-result:nid:nid]\/quiz\/results\/[quiz-result:result-id]\/view",
          "language" : [ "" ]
        }
      }
    ]
  }
}

```

After you enable Rules (and Rules UI, a submodule of it), just clone the above rule (using the Rules UI) and replace both Rules Actions with a Rules Action to grant an amount of User Points that is equal to `[quiz-result:score]` (note that this token is also shown in the Rules example above (within the Rules Action).

If you're not familiar with how to use Rules to grant user points, then have a look at the answer to "How to grant userpoints only for modifying nodes last changed at least 20 days ago?" (which also includes a Rules example to make that happen).

---
Tags: userpoints
---


# Question
Title: Is there any hook_node_pre_submit() like hook?
I have a Drupal 6 site where I am using the Webform module. There are business validations written in JavaScript, but users can bypass them by disabling JavaScript.

Is there any `hook_node_pre_submit()` kind of hook in Drupal 6 that doesn't allows users to submit the form if the validation fails?

# Answer
You can add a validation handler to the form as follows:

```
function hook_form_alter(&$form, &$form_state, $form_id)
{
  if($form_id == 'my_form_id')
  {
    $form['#validate'][] = 'my_validation_handler';
  }
}

```

You need to change 'my\_form\_id' to the actual ID of the webform.

Then in your validation handler, you check whatever you need to check, and if it's an error, you call form\_set\_error on that form element:

```
function my_validation_handler($form, &$form_state)
{
  // Example, check if $form['name'] has a value
  if(!strlen($form_state['values']['name']))
  {
    form_set_error('name', t('Please enter a name'));
  }
}

```
> 1 votes

# Answer
I think hook\_form\_alter is also a good option to overcome this issue. You can validate by altering the webform.

for example:

```
function mymodule_form_alter($form, &$form_state,$form_id) {
  //dpm($form);
  if ($form_id == 'your_form_id') {

    //validate function call
  }
}

```
> 1 votes

---
Tags: 6, hooks, webforms
---


# Question
Title: Administer simplenews subscriptions with views
In simplenews the default path to manage the subscriptions to newsletters is: admin/people/simplenews. The problem with that page is that it doesn't, for example, have any columns that would allow you to see when the subscription was added or even select all the subscriptions and perform actions on them (a feature that is available by default in vbo).

My question is the following:

Is there any way to make the specific page available for further configuration through Views so that I can add extra fields/features to it? What I'm looking for is basically something like Administration Views but for the simplenews interface.

# Answer
> 0 votes
Answer for 2016 and Drupal 7. Simplenews module does now include bulk operations. Simplenews has Views integration built in. It does not come with a pre-defined view, so you have to create one.

Here is an export of a view that shows when the subscriber was added and by what means. However Simplenews does not current provide VBO integration to allow a bulk action.

```
  $view = new view();
  $view->name = 'newsletter_subscriptions';
  $view->description = '';
  $view->tag = 'default';
  $view->base_table = 'simplenews_subscription';
  $view->human_name = 'Newsletter subscriptions';
  $view->core = 7;
  $view->api_version = '3.0';
  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

  /* Display: Master */
  $handler = $view->new_display('default', 'Master', 'default');
  $handler->display->display_options['use_more_always'] = FALSE;
  $handler->display->display_options['access']['type'] = 'none';
  $handler->display->display_options['cache']['type'] = 'none';
  $handler->display->display_options['query']['type'] = 'views_query';
  $handler->display->display_options['exposed_form']['type'] = 'basic';
  $handler->display->display_options['pager']['type'] = 'full';
  $handler->display->display_options['pager']['options']['items_per_page'] = '25';
  $handler->display->display_options['style_plugin'] = 'table';
  $handler->display->display_options['style_options']['columns'] = array(
    'mail' => 'mail',
    'name' => 'name',
    'timestamp' => 'timestamp',
    'activated' => 'activated',
    'source' => 'source',
    'status' => 'status',
    );
  $handler->display->display_options['style_options']['default'] = 'mail';
  $handler->display->display_options['style_options']['info'] = array(
    'mail' => array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
      ),
    'name' => array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
      ),
    'timestamp' => array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
      ),
    'activated' => array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
      ),
    'source' => array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
      ),
    'status' => array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
      ),
    );
  /* Relationship: Simplenews subscription: Subscriber ID */
  $handler->display->display_options['relationships']['snid']['id'] = 'snid';
  $handler->display->display_options['relationships']['snid']['table'] = 'simplenews_subscription';
  $handler->display->display_options['relationships']['snid']['field'] = 'snid';
  /* Relationship: Simplenews subscription: Term ID */
  $handler->display->display_options['relationships']['tid']['id'] = 'tid';
  $handler->display->display_options['relationships']['tid']['table'] = 'simplenews_subscription';
  $handler->display->display_options['relationships']['tid']['field'] = 'tid';
  $handler->display->display_options['relationships']['tid']['label'] = 'Newsletter';
  /* Field: Simplenews subscriber: Subscriber */
  $handler->display->display_options['fields']['mail']['id'] = 'mail';
  $handler->display->display_options['fields']['mail']['table'] = 'simplenews_subscriber';
  $handler->display->display_options['fields']['mail']['field'] = 'mail';
  $handler->display->display_options['fields']['mail']['relationship'] = 'snid';
  /* Field: Taxonomy term: Name */
  $handler->display->display_options['fields']['name']['id'] = 'name';
  $handler->display->display_options['fields']['name']['table'] = 'taxonomy_term_data';
  $handler->display->display_options['fields']['name']['field'] = 'name';
  $handler->display->display_options['fields']['name']['relationship'] = 'tid';
  $handler->display->display_options['fields']['name']['label'] = 'Newsletter';
  /* Field: Simplenews subscription: Timestamp */
  $handler->display->display_options['fields']['timestamp']['id'] = 'timestamp';
  $handler->display->display_options['fields']['timestamp']['table'] = 'simplenews_subscription';
  $handler->display->display_options['fields']['timestamp']['field'] = 'timestamp';
  $handler->display->display_options['fields']['timestamp']['date_format'] = 'short';
  $handler->display->display_options['fields']['timestamp']['second_date_format'] = 'long';
  /* Field: Simplenews subscription: Source */
  $handler->display->display_options['fields']['source']['id'] = 'source';
  $handler->display->display_options['fields']['source']['table'] = 'simplenews_subscription';
  $handler->display->display_options['fields']['source']['field'] = 'source';
  /* Field: Simplenews subscriber: Activated */
  $handler->display->display_options['fields']['activated']['id'] = 'activated';
  $handler->display->display_options['fields']['activated']['table'] = 'simplenews_subscriber';
  $handler->display->display_options['fields']['activated']['field'] = 'activated';
  $handler->display->display_options['fields']['activated']['relationship'] = 'snid';
  $handler->display->display_options['fields']['activated']['type'] = 'unicode-yes-no';
  $handler->display->display_options['fields']['activated']['not'] = 0;
  /* Field: Simplenews subscription: Status */
  $handler->display->display_options['fields']['status']['id'] = 'status';
  $handler->display->display_options['fields']['status']['table'] = 'simplenews_subscription';
  $handler->display->display_options['fields']['status']['field'] = 'status';
  $handler->display->display_options['fields']['status']['type'] = 'unicode-yes-no';
  $handler->display->display_options['fields']['status']['not'] = 0;
  /* Filter criterion: Simplenews subscriber: Subscriber */
  $handler->display->display_options['filters']['mail']['id'] = 'mail';
  $handler->display->display_options['filters']['mail']['table'] = 'simplenews_subscriber';
  $handler->display->display_options['filters']['mail']['field'] = 'mail';
  $handler->display->display_options['filters']['mail']['relationship'] = 'snid';
  $handler->display->display_options['filters']['mail']['operator'] = 'contains';
  $handler->display->display_options['filters']['mail']['group'] = 1;
  $handler->display->display_options['filters']['mail']['exposed'] = TRUE;
  $handler->display->display_options['filters']['mail']['expose']['operator_id'] = 'mail_op';
  $handler->display->display_options['filters']['mail']['expose']['label'] = 'Subscriber';
  $handler->display->display_options['filters']['mail']['expose']['operator'] = 'mail_op';
  $handler->display->display_options['filters']['mail']['expose']['identifier'] = 'mail';
  $handler->display->display_options['filters']['mail']['expose']['remember_roles'] = array(
    2 => '2',
    1 => 0,
    3 => 0,
    4 => 0,
    );
  /* Filter criterion: Taxonomy term: Term */
  $handler->display->display_options['filters']['tid']['id'] = 'tid';
  $handler->display->display_options['filters']['tid']['table'] = 'taxonomy_term_data';
  $handler->display->display_options['filters']['tid']['field'] = 'tid';
  $handler->display->display_options['filters']['tid']['relationship'] = 'tid';
  $handler->display->display_options['filters']['tid']['group'] = 1;
  $handler->display->display_options['filters']['tid']['exposed'] = TRUE;
  $handler->display->display_options['filters']['tid']['expose']['operator_id'] = 'tid_op';
  $handler->display->display_options['filters']['tid']['expose']['label'] = 'Newsletter';
  $handler->display->display_options['filters']['tid']['expose']['operator'] = 'tid_op';
  $handler->display->display_options['filters']['tid']['expose']['identifier'] = 'tid';
  $handler->display->display_options['filters']['tid']['expose']['remember_roles'] = array(
    2 => '2',
    1 => 0,
    3 => 0,
    4 => 0,
    );
  $handler->display->display_options['filters']['tid']['type'] = 'select';
  $handler->display->display_options['filters']['tid']['vocabulary'] = 'newsletter';
  /* Filter criterion: Simplenews subscriber: Activated */
  $handler->display->display_options['filters']['activated']['id'] = 'activated';
  $handler->display->display_options['filters']['activated']['table'] = 'simplenews_subscriber';
  $handler->display->display_options['filters']['activated']['field'] = 'activated';
  $handler->display->display_options['filters']['activated']['relationship'] = 'snid';
  $handler->display->display_options['filters']['activated']['group'] = 1;
  $handler->display->display_options['filters']['activated']['exposed'] = TRUE;
  $handler->display->display_options['filters']['activated']['expose']['operator_id'] = '';
  $handler->display->display_options['filters']['activated']['expose']['label'] = 'Activated';
  $handler->display->display_options['filters']['activated']['expose']['operator'] = 'activated_op';
  $handler->display->display_options['filters']['activated']['expose']['identifier'] = 'activated';
  $handler->display->display_options['filters']['activated']['expose']['remember_roles'] = array(
    2 => '2',
    1 => 0,
    3 => 0,
    4 => 0,
    );

  /* Display: Page */
  $handler = $view->new_display('page', 'Page', 'page');
  $handler->display->display_options['path'] = 'newsletter-subscriptions';
  $handler->display->display_options['menu']['type'] = 'normal';
  $handler->display->display_options['menu']['title'] = 'Newlsetter subscriptions';
  $handler->display->display_options['menu']['weight'] = '0';
  $handler->display->display_options['menu']['context'] = 0;
  $handler->display->display_options['menu']['context_only_inline'] = 0;

```

---
Tags: 7, views, emails
---


# Question
Title: How to add class in current page link fields?
I have an unlimited number of button who are link fields. Like on photo down.

```
{{ loop.first ? field.element_attributes.addClass(green) }}

```

I use this in twig to add class green for first button.

**Orange button is link of current page where I am. How to add orange class to that field in loop?**

There is loop.first, loop.last, loop.index, loop.index0, loop.lenght..Is someone for current page?

# Answer
> 3 votes
If the links are not part of the menu tree, then this can be tricky. Essentially you'll have to evaluate the href value to the current URL.

Otherwise, if they were part of the menu, you can look to the default menu.html.twig file and see in its items loop:

```
// code ...
{%
  set classes = [
    item.in_active_trail ? 'active-trail'
  }
%}

```

As it stands in your situation, you may want to do this in a preprocess and not the twig file itself.

```
function mytheme_preprocess_field(&$variables) {
  // code ..
  $url = Url::fromRoute('<current>');

  // loop field values, compare $url to value
  // if match, add 'orange' to class in the attributes
}

```

Then you would only have to worry about rendering the link fields in the twig, as the attributes part will take care of getting the class to the output.

I suppose another way of encapsulating this logic would be writing your own field formatter for this purpose.

---
Tags: theming, 8, entities, navigation
---


# Question
Title: $form_state['num_names'] increases differently
I'm implementing ajax add more example in my own module. I am pulling data from an Oracle database and printing children's data. However, when I click Add Person, the 1st child's data is multiplied several times, 2nd child's data is multiplied several times and so on. How can I multiply only the last child's fieldset once?

My code:

```
function suweb_agi_add_more_callback($form, &$form_state) {
  return $form['c'];
}
function suweb_agi_add_more_add_one($form, &$form_state) {
  $form_state['num_names']++;
  $form_state['rebuild'] = TRUE;
}
function suweb_agi_add_more_remove_one($form, &$form_state) {
  $form_state['id']=$form_state['clicked_button']['#attributes']['data-id']+1;
}
..
..
..
function suweb_agi_form(&$form, &$form_state, $form_id) {
  for ($x=0;$x<count($child);$x++) {
    for ($y=0;$y<$form_state['num_names'];$y++) {
      $form['c'][$x][$y]['info'] =  [
        '#type' => 'fieldset',
        '#title' => ($lang == 'tr')?'Çocukları / Bakmakla Yükümlü Olduğu Kişilerin Durumu':'Status of Children Dependent On or Living With The Taxpayer',
        '#collapsed' => false,
        '#collapsible' => false,
        '#prefix' => '<div id="agi-fieldset-wrapper">',
        '#suffix' => '</div>',
        'info' => [
          '#type' => 'markup',
          '#markup' => ($lang == 'tr')?'Çocuğunuz 18 yaşından büyük ve eğitimine devam ediyorsa; eğitim durumu bilgilerini doldurunuz. Eğitimine devam etmiyor ise, Asgari Geçim İndirimi kapsamında değildir. Çocuğunuz 24 yaşından büyük ise Asgari Geçim İndirimi kapsamında değildir.':'If your other is older than 18 and continuing his/her education, fill out the education status information. If he/she is not continuing his/her education, he/she is not covered in the Minumum Living Allowance. If your other is older than 24, he/she is not covered in the Minumum Living Allowance.',
          '#prefix' => '<span class="agi-warning">',
          '#suffix' => '</span>'
        ],
      ];
      $form['c'][$x][$y]['info']['first_name'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'Ad':'Name',
        '#default_value' => ($form_state['num_names']>1)?'':$child[$x]['CHILD_FIRST_NAME'],
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['middle_name'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'Orta Ad':'Middle Name',
        '#default_value' => ($form_state['num_names']>1)?'':$child[$x]['CHILD_MIDDLE_NAME'],
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['last_name'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'Soyad':'Last Name',
        '#default_value' => $person['LASTNAME'],
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['tckn'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'T.C. Kimlik No':'T.C. Identity Number',
        '#default_value' => ($form_state['num_names']>1)?'':$child[$x]['TC_KIMLIK_NO'],
        '#attributes' => [
          'class' => ['tckn'],
        ],
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['birth_date'] = [
        '#type' => 'date_popup',
        '#title' => ($lang == 'tr')?'Doğum Tarihi':'Date of Birth',
        '#default_value' => ($form_state['num_names']>1)?'':date('Y-m-d',strtotime($child[$x]['BIRTH_DATE'])),
        '#date_format' => 'd/m/Y',
        '#date_year_range' => '-30:+0',
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['father_name'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'Baba Adı':'Father\'s Name',
        '#default_value' => $person['CINSIYET'] == 'M'?$person['FIRSTNAME']:$other['SPOUSE_FIRST_NAME'],
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['mother_name'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'Anne Adı':'Mother\'s Name',
        '#default_value' => $person['CINSIYET'] == 'F'?$person['FIRSTNAME']:$other['SPOUSE_FIRST_NAME'],
        '#size' => 20,
        '#maxlength' => 20,
      ];
      $form['c'][$x][$y]['info']['gender'] = [
        '#type' => 'radios',
        '#title' => ($lang == 'tr')?'Cinsiyeti':'Gender',
        '#options' => ($lang == 'tr')?['F'=>'Kız','M'=>'Erkek']:['F' => 'Girl','M' => 'Boy'],
        '#default_value' => ($form_state['num_names']>1)?'':trim($child[$x]['GENDER']),
      ];
      $form['c'][$x][$y]['info']['studying'] = [
        '#type' => 'checkbox',
        '#title' => ($lang == 'tr')?'Çalışıyor mu?':'Studying?',
        '#default_value' => (isset($child[$x]['SCHOOL_NAME']))?1:0,
      ];
      $form['c'][$x][$y]['info']['education'] = [
        '#type' => 'fieldset',
        '#title' => ($lang == 'tr')?'Eğitim Bilgileri':'Education Details',
        '#collapsed' => false,
        '#collapsible' => false,
        '#states' => [
          'visible' => [
            ':input[name="c['.$x.'][0][info][studying]"]' => ['checked' => TRUE],
          ],
        ],
      ];
      $form['c'][$x][$y]['info']['education']['education_type'] = [
        '#type' => 'select',
        '#title' => ($lang == 'tr')?'Eğitim Tipi':'Education Type',
        '#options' => ($lang == 'tr')?[0=>'İlköğretim',1=>'Lise',2=>'Üniversite']:[0=>'Primary School',1=>'High School',2=>'University'],
        '#default_value' => ($form_state['num_names']>1)?'':$child[$x]['EDUCATION_TYPE'],
      ];
      $form['c'][$x][$y]['info']['education']['school_name'] = [
        '#type' => 'textfield',
        '#title' => ($lang == 'tr')?'Okulun Adı':'School\'s Name',
        '#default_value' => ($form_state['num_names']>1)?'':$child[$x]['SCHOOL_NAME'],
      ];
      $form['c'][$x][$y]['info']['education']['school_start_date'] = [
        '#type' => 'date_popup',
        '#title' => ($lang == 'tr')?'Okulun Başlangıç Tarihi':'School Start Date',
        '#default_value' => (!isset($child[$x]['SCHOOL_START_DATE']))?'':date('Y-m-d',strtotime($child[$x]['SCHOOL_START_DATE'])),
        '#date_format' => 'd/m/Y',
        '#date_year_range' => '-18:+0'
      ];
      $form['c'][$x][$y]['info']['education']['school_end_date'] = [
        '#type' => 'date_popup',
        '#title' => ($lang == 'tr')?'Okulun Bitiş Tarihi':'School End Date',
        '#default_value' => (!isset($child[$x]['SCHOOL_END_DATE']))?'':date('Y-m-d',strtotime($child[$x]['SCHOOL_END_DATE'])),
        '#date_format' => 'd/m/Y',
        '#date_year_range' => '-18:+10'
      ];
      $form['c'][$x][$y]['info']['remove_person'] = [
        '#type' => 'submit',
        '#value' => ($lang == 'tr')?'Kişi Sil':'Remove Person',
        '#submit' => ['suweb_agi_add_more_remove_one'],
        '#attributes' => ['style' => 'float:right', 'data-id' => $x],
        '#ajax' => [
          'callback' => 'suweb_agi_add_more_callback',
          'wrapper' => 'agi-fieldset-wrapper',
        ],
      ];
    }
  }
  $form['add_person'] = [
    '#type' => 'submit',
    '#value' => ($lang == 'tr')?'Kişi Ekle':'Add Person',
    '#submit' => ['suweb_agi_add_more_add_one'],
    '#ajax' => [
      'callback' => 'suweb_agi_add_more_callback',
      'wrapper' => 'agi-fieldset-wrapper',
    ],
  ];
  $form['submit'] = [
    '#type' => 'submit',
    '#value' => ($lang == 'tr')?'Bilgileri Güncelle ve Yazdır':'Save Information and Print',
  ];
  return $form;
}

```

# Answer
> 0 votes
You have double for-loop in your provided code.. Here is an example how it could be done. The code is not tested but should work and is only the an example for the approach.

```
function suweb_agi_add_more_add_one($form, &$form_state) {
  // We want to add one more fieldset, so lets signalize that.
  $form_state['add_more'] = TRUE;
  // And build the form with the new form_state again.
  $form_state['rebuild'] = TRUE;
}

function suweb_agi_form(&$form, &$form_state, $form_id) {
  // Don't know where you get $child from.. but let's assume, you have it from somewhere.
  // And it is an array.
  $child = array();
  for ($x=0;$x<count($child);$x++) {
    // First you should create the form for existing data.
    $form['c'][$x]['info'] =  [
      '#type' => 'fieldset',
      // Use the t()-function and do your translations not in your functions!!
      '#title' => t('Status of Children Dependent On or Living With The Taxpayer'),
      '#collapsed' => false,
      '#collapsible' => false,
      '#prefix' => '<div id="agi-fieldset-wrapper">',
      '#suffix' => '</div>',
      'info' => [
        '#type' => 'markup',
        // Use the t()-function and do your translations not in your functions!!
        '#markup' => t('If your other is older than 18 and continuing his/her education, fill out the education status information. If he/she is not continuing his/her education, he/she is not covered in the Minumum Living Allowance. If your other is older than 24, he/she is not covered in the Minumum Living Allowance.'),
        '#prefix' => '<span class="agi-warning">',
        '#suffix' => '</span>'
      ],
    ];
    // [...]
  }

  // Now you can check if there is the request for add more..
  if (!empty($form_state['add_more']) && $form_state['add_more']) {
    // Copy the latest form element.
    $latest_form_element = end($form['c']);
    // Change some values, i.e. the id you use for delete functionality.
    $latest_form_element['xyz']['#attributes']['data-id'] += 1;
    // And then add it to the element
    $form['c'][] = $latest_form_element;
    // Reset the form_state add_more
    $form_state['add_more'] = FALSE;
  }

  $form['add_person'] = [
    '#type' => 'submit',
    '#value' => t('Add Person'),
    '#submit' => ['suweb_agi_add_more_add_one'],
    '#ajax' => [
      'callback' => 'suweb_agi_add_more_callback',
      'wrapper' => 'agi-fieldset-wrapper',
    ],
  ];
  $form['submit'] = [
    '#type' => 'submit',
    '#value' => t('Save Information and Print'),
  ];
  return $form;
}

```

---
Tags: 7, ajax
---


# Question
Title: How to change user info with a rule when Points are granted to user (using userpoints module)?
I need to create a rule to change info of a user when this user is granted with points using the http://drupal.org/project/userpoints module.

I need the rule to have a condition and action like:

if total points of the user are greater than 1000 --\> then set the field **passed** to 1

The **field passed** is a field that I added at **admin/config/people/accounts/fields**

My problem is that I can't load the Total points of the user in the **conditions** of the rule

I already have the userpoints\_contrib module enabled.

# Answer
I think that was added recently in dev: drupal.org/node/1109992
> 1 votes

# Answer
In the condition of your rule add **Execute custom PHP code**. Then add the following code to get total userpoints and check condition:

```
$current_points = userpoints_get_current_points($userpoints_transaction->uid, 'all');
if ($current_points >= 1000) {
  return true;
}

```

For more information about `userpoints_get_current_points` refer to this page
> 0 votes

# Answer
Apart from what's mentioned in the previous answers, there is also the Rules Action "***Load user points of a user***", whereas you can ask for either a specific category, or for all categories together. This Rules Action provides a Rules variable (for which you can specify its name and description) which contains the amount of user points for the requested category. You can then use this variable in subsequent Rules Actions.

If you then want to use that variable within a Rules Condition, you have 2 ways of doing so:

* Include the condition in a Rules Component, whereas you trigger the execution of that Rules Component via a Rules Action following the "Load user points of a user" (and passing the variable containing the amount of user points as a variable for the Rules Component).
* Use the Conditional Rules module, so that you can specify Rules Conditions within Rules Actions.

Here is a basic example that displays a message about the current total user points for a user (change the Rules Event to any Rules Event that you want):

```
{ "rules_display_userpoints_after_updating_content" : {
    "LABEL" : "Display userpoints after updating content",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "userpoints_rules", "rules" ],
    "ON" : { "userpoints_event_points_awarded_after" : [] },
    "DO" : [
      { "userpoints_rules_get_current_points" : {
          "USING" : { "user" : [ "site:current-user" ], "tid" : "all" },
          "PROVIDE" : { "loaded_points" : { "total_points" : "Number of points in all categories together" } }
        }
      },
      { "drupal_message" : { "message" : "You now have [total-points:value] points" } }
    ]
  }
}

```

Use the Rules UI to import the above rule in your own site if you want.
> 0 votes

---
Tags: rules, userpoints
---