Issue summary updated as of comment #32
Problem/Motivation
The block module does not make provision for negating the user role visibility condition. That makes it impossible (via the UI) to make a block visible only to authenticated users who do not also have a specified additional role, such as member.
Steps to reproduce
Go to /admin/structure/block/manage/BLOCKNAME and look at the "roles" tab; there is no "negate" option.
Proposed resolution
See patch: enable-block-visibility-user-role-negation-2986958-27.patch
Remaining tasks
Update issue summary
Add change record
Manual testing
Tested with themes
- Bartik
- Bootstrap
- Radix
- Umami
User interface changes
On /admin/structure/block/manage/BLOCKNAME ("roles" tab), add "negate" option.
API changes
None.
Data model changes
None.
Release notes snippet
Add a "negate" option to "roles" tab in block visibility settings.
| Comment | File | Size | Author |
|---|---|---|---|
| #71 | block-visibility-roles.png | 283.62 KB | prashant.c |
| #63 | 2986958-invert-block-visibility-by-role.patch | 502 bytes | sajithathukorala |
| #60 | enable-block-visibility-user-role-negation-2986958-60.patch | 4.64 KB | shabana.navas |
| #53 | 2986958-53-enable-block-visibility.patch | 4.44 KB | ptmkenny |
| #46 | interdiff-2986958-43-46.txt | 2.65 KB | mohit_aghera |
Issue fork drupal-2986958
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
benjaminbradley commentedThis simple patch restores the ability to negate the UserRole condition in block visibility rules.
Comment #3
drupgirl commentedPatch #2 works for me. Thank you very much.
A lot of times it makes sense that you only want to show a block to authenticated users. This is the base set of users with no special anythings and it makes a lot of sense to be able to isolate this set of users. It would be good to know why this functionality was removed and if this change is going to cause issues down the line. Does anyone have the backstory on the change?
Something to note: this solution does not carry through to block visibility conditions in Panels. So if you are using Panels you may have to resort to using blocks, as well.
Comment #4
kclarkson commentedWow! Its amazing how many little things this get lost over time. This is definitely a feature that was required for a member site. show a member renews block on all roles except member.
Patch applied cleanly and works as expected alongside block visibility groups.
Comment #5
markdcI was just looking for this. Patch does the trick. Thank you!
Comment #6
berdir> A lot of times it makes sense that you only want to show a block to authenticated users. This is the base set of users with no special anythings and it makes a lot of sense to be able to isolate this set of users. It would be good to know why this functionality was removed and if this change is going to cause issues down the line. Does anyone have the backstory on the change?
Why do you need invert for that? All users either have anonymous or authenticated roles, so its' very easy to target either all authenticed or all anonymous users.
I would say the main reason it is hidden is that the UX was kept when those settings were converted to more generic plugins but we tried to avoid changing the UI in the same issue.
Comment #7
drupgirl commentedHi, Berdir, I mean just authenticated users with no other roles. Obviously when we select authenticate we get the everybody. Sometimes you want just users with only the authenticated role, which leads us to negate.
Comment #8
shawn dearmond commentedYup, #2 works for us too.
Comment #9
knyshuk.vova commented+1 to RTBC
Comment #10
catchThis should probably have some test coverage, should be possible to extend an existing test.
Comment #12
webel commentedThanks for raising this feature request, I have this exact need also, and it would be good to have it in core (although clearly it is not hard to do in custom hook code).
Case: I want to show certain promotional blocks (in the right sidebar) for users who are anonymous or "only" authenticated, but not for users with higher roles (staff users) who need the entire right sidebar free for viewing large views tables.
Comment #13
kclarkson commentedIs there someone from the core team we can get to look at this? Always having to remember patching always stinks :)
Comment #15
dercheffeHaving the same use case here.
Would like to display a block, if a user does not have one (or all) of the specific user roles.
Edit:
patch #2 works for me. Would also vote for same feature for content types and aliases.
Comment #16
dercheffeHmm okay after updating core from 8.8.2 to 8.8.3 it doesn't take an effect anymore
Comment #18
ptmkenny commented@kclarkson: Reverting this issue to "Needs work" because it needs tests; it will not get committed to core without tests, so the correct status until the tests are added is "needs work." Once tests are added to the patch, it can be marked "Needs review."
@dercheffe: The patch is working for me on 8.9; please double-check how you are applying the patch if you are still having problems.
Comment #19
liliplanet commentedYou are a star @benjaminbradley #2 patch works perfectly 🌷
Comment #21
mohit_aghera commented- Adding small test cases to evaluate the negate condition.
Tests are passing on local, let's see how it goes.
Comment #23
larowlanSlight title update to reflect this is a feature
Comment #24
gaurav.kapoor commentedComment #25
mohit_aghera commentedIssue re-roll with 9.3.x
Comment #27
mohit_aghera commentedReplace the deprecated method.
Comment #28
liliplanet commentedthank you @mohit_aghera, works perfectly 🌿
Comment #29
vikashsoni commentedApplied patch #27 working fine for ref sharing screenshot ....
Comment #30
segovia94 commentedI added a change record that can be reviewed at https://www.drupal.org/node/3243401. This is working well on our sites.
Comment #31
quietone commentedNice to see this moving along, however it is not quite ready for RTBC.
There are several steps, or core gates that an issue must pass first. For this issue, an Issue Summary update is needed. Note there are use cases in #8 and $12 that should be put in the IS. For this, I have started by adding that template. so I could add remaining tasks. This is also changing the user interface text, so it needs a change record.
I tested with Drupal 9.3.x, demo_umami install. I added the language switcher block to the Seven theme and that block displayed. I then modified the Roles settings, ticking Administrator and 'negate the condition'. I expected the block to not display but it did. I tested again with Bartik and the negate worked as expected. Does this only work on Bartik?
@vikashsoni, the latest screenshots should be put in the issue Summary.
Also tagging novice because the follow tasks are suitable for someone new to Drupal:
Comment #33
rclemings commentedI've tested this with Drupal 9.34, using a custom theme based on Bootstrap 8.x-3.23, and everything works as expected.
I've also taken a swing at updating the issue summary but I don't quite understand how the two-line patch in #27 works, so I've just pointed to the patch and left the rest for a wiser mind (@mohit_aghera?) to complete.
Comment #35
aaronbaumanUsing a Radix-based theme, as well as on the demo_umami install profile, and #27 works as expected in both cases.
@quietone maybe you can check your settings and re-test?
All tasks have been addressed addressed.
Comment #36
catchThis wasn't actually removed as such.
Block visibility originally didn't have a built in concept of 'negate', and role visibility didn't include its own one.
When the visibility options were moved to plugins, a generic concept of 'negate' was added, but for existing ones that didn't previously have it, this was disabled to avoid making UX/functionality changes. i.e. more or less what Berdir says in #2986958-6: Add support for negating user role condition for block visibility.
It makes sense to have these consistent to me.
The test exposes a bit of a usability issue though - i.e. what is the difference between 'authenticated' + negate and anonymous, or between anonymous + negate and authenticated - since those roles are always mutually exclusive. Having said that, since either direction works maybe it doesn't matter to offer both?
However, I can see the use-cases for 'show to all authenticated users but not site admins' and not sure it's worth complicating the code further to avoid combinations that will work. Although if you picked both anonymous and authenticated then negated, the block would show to no-one.
Tagging for usability review to get an extra opinion.
Comment #37
aaronbaumanThanks for that detailed history @catch
fwiw, block viz settings already have some other contradictions, e.g. various ways to set a block to never appear with path settings, or combining an admin-only path with a non-admin role.
+1 for making the "negate" setting consistent
Comment #38
benjifisherFor usability (and other) review, it will help to have some before/after screenshots in the issue summary, under "User interface changes".
Comment #39
aaronbaumanUpdated IS with pics from #29
Comment #40
rossidrup commented#27 works for latest drupal?
Comment #41
simohell commentedHi,
We discussed this in UX weekly last month and came up with some suggestions for the UI. Sorry for the delay in posting this comment.
You can find the recording of the meeting linked to the meeting issue https://www.drupal.org/project/drupal/issues/3296084
In some cases Drupal uses a checkbox to negate a setting, but this does add to the cognitive strain. One needs to know the original rule and then understand what the result is when the rule negated. "When the user has the following roles" do what? What happens when that is negated.
Our conclusion was that it is more usable to have similar setting as we have for the Pages-tab as radiobuttons where the effect of the setting is explained directly.
- Show for the listed pages
- Hide for the listed pages
Also it would be useful if the selection of action would precede selection of the roles.
- Show for the selected roles
- Hide for the selected roles
I'll add screenshots of the existing default Pages tab in Claro and a mockup of the suggestion for roles. (Pages tab would probably also benefit from moving the radiobuttons first.)
Comment #42
benjifisherI am setting the status to NW based on #41. That comment has the usability review, so I am removing the tag for that.
Comment #43
mohit_aghera commentedThanks for the feedback @benjifisher and @simohell
Looks like changes will be related to title and re-arranging few things.
I've updated the patch as per the feedback.
I think test cases will remain the same.
Comment #44
berdirI understand this from a usability perspective, the problem is that this results in yet another custom optimization that only that specific condition and the block UI benefits from.
Conditions are a generic plugin system that are used by contrib modules in other places, those will still get the other UI. And other plugins will all require a custom and unique solution for this.
But even doing it generically in this specific plugin is tricky for backwards compatibility and the text might not make sense in other contexts. A condition might be used to execute a certain action or not, nothing is shown or hidden.
But again, I understand that this is much better for users, it's just a bit sad from a technical perspective.
Comment #45
berdirAnother note: I believe this still uses the standard negate behavior though, which could be interesting. with custom rules and authenticated. the tests only verifies the generic authenticated role. can we check what happens if you hide it for a specific role but not authenticated? I'm honestly not sure what happens then.
Comment #46
mohit_aghera commentedHi @Berdir
Yes, looks like something is wrong with Negate condition with other role.
I am attaching a patch for reference which seems to be failing on local.
Mainly it is same patch as #43, I've just added few more test cases.
Comment #51
ptmkenny commentedSorry, bad patch; please ignore and will fix.
Comment #52
ptmkenny commentedComment #53
ptmkenny commentedHere's a corrected reroll of #46.
Comment #54
gaurav.kapoor commented#53 would require some changes as it isn't removing these 2 lines and the radio buttons disappear as their type gets changed to 'value'.
Also, the saved value of user role negation isn't reflected in the UI after saving the block. Should we make this change as well:
Thoughts?
Comment #55
liliplanet commentedHow I wish this negate role functionality could be committed, it is awesome! Been having to hack the block module since D8 😉
Comment #56
edward.peters commentedMe too, this would be such a great development to have this in core.
Comment #57
liliplanet commentedThank you! But the patch in #53 does not save when you select 'hide for the selected roles'.
Comment #58
liliplanet commentedOh dear, I have tried patch #43, #46, #53, #54: still 'hide for selected roles' is not saving.
Any progress most appreciated.
Comment #59
liliplanet commentedThank you #@mohit! #46 is definitely the one.
Comment #60
shabana.navas commentedUpdating patch in #46 to fix default value problem mentioned in #54.
Comment #61
ptmkenny commented@gaurav.kapoor I renamed request_path to user_role; that was a mistake on my part. Thank you for pointing it out.
As for the first two lines, in Drupal 11 it seems those lines are already gone.
Comment #62
iancawthorne commentedIs there a patch for 10.2.x which works on this thread?
I've tried #53, which will apply, but as mentioned in #58, saving the block does not update or reflect the negate/non negate setting. The patches at #43, #46 and #60 will not apply to 10.2.6.
Comment #63
sajithathukorala commentedPatch for Issue #2986958: Invert visibility of chosen roles for blocks
Here is the patch to invert the visibility of chosen roles for blocks as per Issue #2986958.
This patch introduces a custom block permissions handler that allows inverting the visibility settings for blocks based on roles.
@iancawthorne #62
Please review and test the changes.
This patch tested with Drupal 10.2.x
https://www.drupal.org/files/issues/2024-06-03/2986958-invert-block-visibility-by-role.patch
Comment #64
iancawthorne commentedThe patch at #63 works great on 10.2.x.
Comment #66
prabha1997 commentedThe patch #63 works on 10.2.x.
Comment #67
ptmkenny commentedWarning: Patch #63 is a different modification than the MR
2986958-add-support-forand the rest of the patches in this thread. Patch #63 inverts the visibility of the roles in all cases, whereas the rest of the patches and the MR2986958-add-support-foradd a setting that allows the roles to be negated. Patch #63 is not a solution to this issue and it doesn't have any tests.Comment #68
iancawthorne commented@ptmkenny Can you clarify on the
inverts the visibility of the roles in all casespart?From my testing, I update a blocks visibility and did a config export. Only the user role visibility changed in that config export, as expected. No config changed for negating visibility was negated for any of the other conditions, such as by content type, by page or by vocabulary etc.
Are you talking about a different scenario which I'm missing?
Comment #69
ptmkenny commented@iancawthorne I meant all cases for user roles, not for the other conditions. Anyway, you can clearly see this by reading the code for the patch; patch #63 is a one-liner whereas the other patches in this thread are many more lines.
Comment #71
prashant.cI noticed a few things, and I would like to request your inputs on the following considerations:
"Show for the selected roles"is selected and it gives the impression that we have to select some role before proceeding"If nothing is selected the block will be visible to all the listed roles"Please see the attached screenshot.

Comment #72
iancawthorne commented@ptmkenny I can see the patch at #63 is a lot less lines of code than others. However, up until needing to upgrade from Drupal 10.1.x to 10.2.x, I've been using the patch at #21. If you take out the test lines for that patch, you are left with a two liner, which as far as I can tell does the same as patch #63 but in a very slightly different way.
I'm still not sure what you mean by
all cases for user rolesthough?Comment #73
ptmkenny commented@Prashant.c First, please note that this change has already undergone a usability review.
As for your points:
In Drupal, radios generally have something selected by default. For example, in "Submission form settings", "Preview before submitting" also has a default value selected. If no default value was selected, when creating a new entity, users would always have to fill out that part of the form. Anyway, this is the way other
This could be a helpful suggestion but I think it is out of scope for this issue, as the change has already undergone usability review. Please consider opening a new issue with this request.
Comment #74
ptmkenny commentedFor anyone coming to this issue and "just looking for a patch," please consider using the User Not Role module instead, which does what this issue will eventually accomplish in core.
Comment #75
prashant.c@ptmkenny
Thanks for your responses; I understand your points. Apologies for missing #41