Problem/Motivation
Enabling user overrides enables a lot of options which may not always be desired. Perhaps e.g. only dark mode selection is desired, or all except control of the toolbar.
Steps to reproduce
- Enable overrides from the Gin theme settings
- All options are given to the user
Proposed resolution
- Add a secondary field 'Enabled user override options'
- Default existing sites that have overrides enabled to have all options enabled to maintain status quo
Remaining tasks
Merge requestUpdate hook to maintain status quoTest coverage update
User interface changes
Gin settings gets a secondary checkboxes field to control which options are possible to override per user.
Gin theme settings:

User override options shown:

API changes
N/A
Data model changes
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | user-overrides.png | 43.03 KB | scott_euser |
| #4 | overrides.png | 41.08 KB | scott_euser |
Issue fork gin-3505686
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 #3
scott_euser commentedNeed to update test coverage still but out of time this morning, will finish later
Comment #4
scott_euser commentedComment #5
scott_euser commentedOkay added test coverage, added update hook to maintain status quo for existing sites.
Comment #6
jurgenhaasHey @scott_euser, thanks for your contribution. I've only had a quick look into the MR and it looks really comprehensive. Just one major gap, I think hasn't been covered:
If one of the settings has been enabled and a user has altered the setting in their profile, it will be stored for them. Now, if that setting gets disabled for user overrides later on, the setting will still be stored with those users. As a result,
\Drupal\gin\GinSettings::getmay return an overridden value, although that's no longer allowed. That method needs to check the enabled override settings at that point.And a minor missing tweak is in the update hook. The
enabled_user_theme_settingsneeds to be initialized with an empty array ifenabled_user_theme_settingsis turned off.I'll go for a more comprehensive review when we've sorted those out.
Comment #7
saschaeggiThank you for your contribution here.
I have one question: Could this be solved with permissions? We've started https://git.drupalcode.org/project/gin_permissions a long time ago but it got never fully being worked on
See also #3138529: Add permissions for User settings
I'm asking as there could be a use case that you want to expose more settings to admins and less settings to content editors. But this solution seems to generally limit the settings no matter their role.
Comment #8
scott_euser commentedUp to you of course. Looks like you closed that issue #3138529: Add permissions for User settings years ago as adding too much complexity; I tend to agree; not sure there is a case e.g. where you'd like admin role control dark mode but not let editors do that. This is much simpler.
I could create a new module, or put in a request to co-maintain that module if you aren't interested in having it in here.
For now I addressed the feedback in #6 + added further test coverage.
Comment #9
saschaeggi@scott_euser we closed it in favor of https://git.drupalcode.org/project/gin_permissions
So it could be worked on in gin permissions and I could add you as a maintainer if you'd like to contribute to that ☺️
But would also love to hear @jurgenhaas opinion first about a permission approach 👀
Comment #10
scott_euser commentedgin_permissions seems like it never had any attempt at making it work though.
Personally I think better to start simple and gin_permissions can then leverage this to control per role for someone needing that complexity. I could open an issue there like 'Future of this module' and request people comment if they do have a need for different permissions per role. We could then gauge whether there is an actual demand for that option rather than building in just in case?
Comment #11
scott_euser commentedBut if ultimately the two of you decide you prefer that approach, happy to take over development and maintenance of it and shift this code over to there + extend for permissions layer
Comment #12
jurgenhaasI really like the idea of making this permission based, but I don't like the idea of a separate module. I guess, it felt necessary because a them can't provide permissions? If that's the case, I'd rather put that into gin_toolbar as it is already a hard dependency for Gin and we could rely on it to be present.
But to do this step by step, I think the approach in MR!575 is a great start and could afterwards be extended with a permission controlled follow-up.
I just don't believe that the latest merge in
helper.themeis appropriate. This should be handled in\Drupal\gin\GinSettings::getso that this service is the one central place which determines the correct value for each settings. Whatever feature in Gin needs to know about the setting, they should all just call that service to always receive the correct value.Comment #13
scott_euser commentedCan you have another look please? That is already the case, see https://git.drupalcode.org/project/gin/-/merge_requests/575/diffs#411dd7... + the test converage checking for 'Increase contrast' not shown, then config update only (no user data change) 'Increase contrast' being shown also validates that that is the case.
The helper.theme only addresses this comment from you earlier:
Well sort of addresses it; it maintains the same problem as Gin theme currently has - that user data settings are only removed on resave (which is fine since the GinSettings::get() respects the enabled overrides as per above right?).
Comment #14
saschaeggiI'm relying on Jürgen's expertise here, but if we can move complexity out of Gin or avoid adding it by adding it to a helper module I'm usually very happy as Gin is already quite complex on it's own. My 5 cent:
100%, themes can't declare permissions. So a helper module is needed
That is currently the case, but once
navigationis stable and takes over and we deprecatetoolbarwe have to evaluate the need forgin_toolbaragain. So if this specific use case is handled in it's separated module it might make more sense [at least to me]Comment #15
scott_euser commentedYeah if separate module is the route personally would prefer gin permissions since it doesn't really have much to do with toolbar
Comment #16
jurgenhaasSorry for the delay. The gin_toolbar only came to mind as it is already an existing dependency. But @saschaeggi is right, of course, if the toolbar becomes deprecated, that wouldn't be a smart move.
If we go for another helper module instead, it should be declared as a hard dependency because the code in Gin would rely on those permissions being declared.
Comment #17
scott_euser commentedAn alternative is I reduce the scope of this MR to just refactoring the code enough to make it easy to extend.
Then e.g. with a route subscriber or something like that the gin_permissions module can be a progressive enhancement.
In which case here it can be in 'suggest' within composer.json and possibly a helptext in the current form like "Looking for more fine-grained permissions around user overrides..." type thing.
Would that work?
If so, did either of you want to be the owner of gin_permissions and make me a maintainer? Happy to make it independently too if you prefer and add you both as co-maintainers.
Comment #18
jurgenhaasThe https://www.drupal.org/project/gin_permissions already exists, hope that @saschaeggi can maintainers there as @dermario is the owner.
Simplifying the MR sounds perfect. But I'm not sure what you mean by "progressive enhancement". So you want to alter route permissions? That wouldn't be sufficient, I guess, as we need access to the permissions when building the user profile form and when preprocessing elements, don't we?
Comment #19
saschaeggi@Jürgen @Scott I've added you both as maintainers to gin_permissions
Comment #20
scott_euser commentedThanks @sashaeggi
@jurgenhaas - sorry hadn't gone through the code very far, was more hypothetical, but basically with this understanding of your goals (do say if I got this wrong):
So in the current merge request, its not permissions based because permissions aren't available.
So I will work on changing to route 2 and close the current merge request I believe. Is that correct? So I think I should close this one then.
Comment #21
jurgenhaasI describe the architecture once again with my own words, maybe that makes it easier to understand:
That way, Gin can work on its own just with settings on which setting can be overridden by users. And the optional gin_permission module can hook into that decision and overrule this settings-based decision by a permission-based decision.
Re-opening the issue as it still needs some work to be done.
Comment #22
scott_euser commentedThanks for providing more detail.
Already completed
Yes that's the case already with the MR + has test coverage here which I tried to explain in #13.
Here is the test coverage proving this case:
https://git.drupalcode.org/project/gin/-/merge_requests/575/diffs#586603... where:
Here is the code that ensures that only enabled settings will use the user override:
https://git.drupalcode.org/project/gin/-/merge_requests/575/diffs#411dd7...
Already completed
Yes that is the case, per screenshot of the UI:
To do here
Okay understood will refactor the existing code in this MR to cover this.
To do in Gin Permissions
Okay created follow-up here: #3512885: Create permissions per option that user can override
Comment #23
scott_euser commentedComment #24
jurgenhaasThat looks great, thank you @scott_euser
Only one (final) consideration: should we move the
_gin_user_form_submitinto GinSettings as well? Then we have the settings related functionality all in one place.Comment #25
scott_euser commentedSure @jurgenhaas I have moved the contents of it over, I kept as public function, not public static function so $this can be used, figured that's better than a static callback and removing altogether, but fine to change to that if you prefer of course.
Thanks
Comment #26
jurgenhaasLooks much better thank you. Any reason why we want to keep
_gin_user_form_submitaround? Couldn't the form builder refer to the submit method in the service directly? Just one fewer step that might otherwise be confusing at some point.Comment #27
scott_euser commentedThat's what I meant by #25, callback is static so removes function but then loses ability to use $this so ends up statically loading itself - matter of preference which you think is the lesser of two evils...
Comment #28
jurgenhaasAh, sorry, then I misread that.
But I guess we should be able to get both. See this change record which comes with an option "Object method, instantiated by ClassResolver, container aware using ContainerInjectionInterface", the third from the bottom of the list. That should allow us to use the method in GinSettings with a non-static method and dependency injection.
Comment #29
scott_euser commentedOoh nice TIL, will update to use that then :)
Comment #30
scott_euser commentedOkay that works & tests pass locally on supported Drupal BUT I attempted to update gitlab-ci.yml because its not supported by Drupal 9 (and therefore also had to update PHP version because Drupal 10.3 (lowest supported version) does not support PHP 7.4). The error in current Gitlab CI setup is "You have requested a non-existent service "callable_resolver"" because it does not exist until Drupal 10.2.
So I reverted the change and left _gin_user_form_submit in.
I think there are two routes forward:
Or I could create two follow-up issues to avoid this getting blocked for a longer time:
Comment #31
scott_euser commentedFor now started #3516730: Gitlab CI template update as I think its first step either way, whether you decide its a hard blocker to do callable or not
Comment #32
jurgenhaasGreat work @scott_euser. I'd say we go for the modern approach, so please bring back the last 3 reverted commits. There is just a tiny issue in there:
The variable should be
$class_resolverinstead of$submit_handler.And then we should raise the core requirement in the info file to
^10.3 || ^11. But that can be done in the related issue. I'll review #3516730: Gitlab CI template update now, so that we can commit them both together and all should be great.Comment #33
scott_euser commentedSure sounds good, if its okay I will wait until you have merged #3516730: Gitlab CI template update since this will have some conflicts to resolve + can then double check that tests subsequently stay green.
Comment #34
jurgenhaasSure, let's do that.
Comment #35
scott_euser commentedOkay ready again, thanks for merging in the gitlab ci one!
Comment #36
scott_euser commentedHi! Anything I can do here to help get this over the line? Thank you!
Comment #37
jurgenhaasExcuse me @scott_euser, didn't mean to ignore this issue for such a long time. It's just that we're currently heads-down with the Gin migration into core, and we've stalled literally everything in the issue queue for the time being. Give us a bit more time until the dust settled on this major step, and we'll then get back into these topics that we'll want to get into Gin and move them forward in that new context.
Comment #38
scott_euser commentedNo problem thanks for the update!
Comment #39
jwilson3I'm here to report a related issue I'm having whereby the "Admin theme settings" wrapper element gets added to every user edit form mode. I don't know if this makes sense to add here or not. This does have to do with "fine-grained control" over display admin theme user settings.
Steps to reproduce:
Proposed resolution:
Make "Admin theme settings" available for placement via drag and drop on Manage Form Display settings on /admin/config/people/accounts/form-display
If this can be tackled independently of the awesome overhaul going on in this issue, I'm happy to split this off to a separate issue, but I don't know enough about the plans here or whether it makes sense to roll this into this feature request or not. Thanks.
Comment #40
jwilson3In addition to #39, I found the terminology of the form elements on the user edit form a bit confusing.
Currently, the UI looks like this:
I’d propose the following improvements:
The benefit of this approach is flexibility: if a frontend theme also provides customization options, both admin UI and frontend UI preferences could be grouped together under one field group. For example, by setting the wrapper to Container (invisible), you could present two checkboxes side by side inside a custom field group:
Comment #41
scott_euser commentedPersonally would much prefer to keep to the issue summary here as we have spent a lot of time having a back and forth to agree approach and get test coverage in. The goal here is to break up the options so it's not an all or nothing but otherwise leave the status quo to keep the scope limited and in a place that is realistically mergeable.
Changing the UX and what the options are do sound like you're raising seperate issues that are related to the user controls in general. I'm not a maintainer here of course so would suggest waiting until they chime in :)
Comment #42
scott_euser commentedResolved conflicts with 5.0.x branch and retargeted the MR to there, the phpstan issues are unrelated and exist on 5.0.x main as can be seen here https://git.drupalcode.org/project/gin/-/jobs/7291859
What can we do to get this in to avoid having to do a big conflict resolve again? Anything I can help with? Thanks!
Comment #43
jurgenhaasI know this is very unfortunate. There is a lot urgent staff in 5.x for Drupal 11, and there's the ongoing effort to merge Gin into core. But codebases have diverged from each other a lot. So, I'm unsure how to approach this now. Doing the work twice isn't what we want to do, I guess. For the version that goes into core, the approach would have to be revisited.
Comment #44
saschaeggiWhat's the status here? Should this be closed for the contributed version of Gin and moved to Gin's Core version (admin)?
Comment #45
scott_euser commentedWe had resolved all issues after a fair amount of back and forth and it was ready to merge as final bits from #32 were addressed (the latest comments from others were hijacks/unrelated issues).
Obviously would not like to have to redo all the work but sounds like that's the path sadly. I would rather not spend the time unless I have a new steer though because the above seems to indicate that a different approach might be needed for Core. Who would decide that? Or is that up to you and Jurgen still? E.g does this need to be targeted to 6x now? It's unclear what's happening in #3530849: [META] Gin 6.x: Preparation for merging into core.
Comment #46
jurgenhaasThat would have to happen in the main branch of core. And the php part of the theme is nothing lime it was before, everything is living in oop hooks now.
We could merge this into 5, though. But we would have to make it very clear that it won't be available afterwards. And Gin in contrib will probably not support Drupal 12.
As for starting the process for core, an issue would be the best starting point. And then getting sign off to do it before actually starting the code migration.
Comment #47
scott_euser commentedI think your comment that you are happy to merge it is sufficient; actually merging it and regressing after is probably too confusing. For now its not in Drupal Core yet is it? I tried at https://git.drupalcode.org/project/drupal/-/tree/main/core/themes?ref_ty... but don't see Gin there at this stage. So at the moment I should wait before opening or moving this issue project to core I think?
Not a problem converting to OOP hooks of course.
Thanks!
Comment #48
jurgenhaasHaha, it's there, but it's not called Gin anymore. Go to https://git.drupalcode.org/project/drupal/-/tree/main/core/themes/defaul... and that's what used to be Gin.
Comment #49
scott_euser commentedAha! I see, thank you!