The Themekey rule chain only allows for static assignment of themes based on particular conditions. However, I would like to make a dynamic theme assignment. Specifically, I would like to test the organic group assignment of the node and then assign the theme to the theme chosen for 'my content' for the owner of the group. Thus, the group owner can change the theme for their group content dynamically without the Drupal administrator having to get involved.

How would I do this? If the feature cannot be added to themekey, can you post a php snippet to accomplish my goal?

Perhaps the addition of dynamic themekey rules could have other cool applications as well :-)

Thanks for any help!

Jeff

Comments

mkalkbrenner’s picture

Category: Feature request » Support request

That's doable. But this use-case is too specific to implement it as feature within ThemeKey. And I think that it will take more time to guide you through the implementation using the issue queue than just implementing such a custom module.
I suggest that you contact me via mail.

webservant316’s picture

I will contact you via email.

It seems to me that you could easily extend Themekey to allow for a PHP snippet on the right hand side of the Rule Chain. That would allow for all sorts of possibilities. It would solve my use case and countless others.

Or I can write a custom module as you suggest.

mkalkbrenner’s picture

I will never support the input of PHP code instead of a theme name. Having PHP code in the database is a nightmare for debugging and eneables users to crash their installation.

If you want to modify a theme decision dynamically you can implement hook_themekey_custom_theme_alter(). You'll get the information about the rules matched for this decision.

webservant316’s picture

Fair enough. Drupal itself makes provision for it and with some protection for bad code and I make use of it in a few blocks, but I fully understand your concern.

Do you have an example hook_themekey_custom_theme_alter() to change the theme based on the group id and assign the theme to the 'my content theme' for the owner of the group? How do I figure out the 'my content theme' for a particular user id? How do I reassign the theme?

mkalkbrenner’s picture

Drupal itself makes provision for it and with some protection for bad code and I make use of it in a few blocks

Yes, the PHP Filter. And it was a good decision to remove it from drupal core for future versions: #1203886: Remove the PHP module from Drupal core

Do you have an example hook_themekey_custom_theme_alter() to change the theme based on the group id and assign the theme to the 'my content theme' for the owner of the group? How do I figure out the 'my content theme' for a particular user id? How do I reassign the theme?

That's what will take too much time.
And the better approach will be to implement hook_themekey_properties() instead and provide a "static" property. That will be user-friendlier (easier to administrate) but will also take some more time.

webservant316’s picture

Ok, sounds good. Anything you can do to point me in the right direction would be appreciated.

webservant316’s picture

As for a solution integrated into your module the other option would be a sub-module that presented various tokens for the right hand side of the rule chain. I think tokens must be the Drupal alternative to PHP snippets in this situation. I bet 10 tokens could handle 90% of the common use cases.

mkalkbrenner’s picture

You miss an important part. The theme decision of the core happens in an early bootstrap phase of drupal where important parts of the infrastructure are not available. I assume you can't use something like tokens. For example the whole field api is not available.
The second difficulty is the compatibility with drupal's internal caches.
If you're interested I'll send you an estimation via mail.

webservant316’s picture

just emailed you. thanks.

mkalkbrenner’s picture

Do you know how to get the "group owner" from the group id?

webservant316’s picture

trying to find an answer here https://drupal.org/node/2235897

webservant316’s picture

Got the answer. The group id is the group node id. So the logic for this problem is really simple. In my use case nodes will only be allowed to be assigned to one group. Organic groups does allow nodes to be linked to multiple groups which would make it difficult to chosen which group, group owner, and theme to choose. However, again in my use case I am allowing a node to be assigned to only one group. Thus to find the group owner...

if (  arg(0) == 'node' &&
      is_numeric( arg(1) ) &&
      ($current_node = node_load(arg(1)) &&
      !empty( $current_node->groupid ) &&
      ($group_node = node_load( $current_node->groupid ) &&
      ($group_owner = user_load( $group_node->uid ) ) {
            $current_theme = $group_owner->theme;
}

I have to check the location of the $current_node->groupid variable. Of course there may also be ways to optimize this logic so that we do not have to read two nodes for every page load just to determine the theme.

webservant316’s picture

ALTERNATIVELY...

Does Themekey allow the explicit assignment of a theme to particular node types? I could allow the explicit assignment of a theme to the group node type. This would allow other privileged group admins to change the theme as well. Then all other node types that are can be associated with a group could be set to maintain the current theme. In this way the theme for all pages will always be the theme of the group homepage that they came from.

The solution is potentially better because the same node could then be associated with multiple groups and be themed according to the context of the group they came from. If this works then no special code is needed.

Let me try out the idea.

mkalkbrenner’s picture

Your code from #12 won't work. Or at least it will cause different issues because node_load must not be called at this stage of the drupal bootstrap where not all modules are fully initialized!
You need to access the database directly or (since drupal 7.22) use ThemeKeyEntityFieldQuery.
Again, it's doable ... but probably you need me to implement it.

But similar as you described in #13 you might use two different already existing proerties to solve your issue:
1. node:type
2. node:field_groupid

The second one is created dynamically since ThemeKey 7.x-3.x. Just check out "properties explained". This list is not static but increases dynamically when you add modules or fields.

webservant316’s picture

hope to try out #13 in the next month and report back.