Sorry if I am missing the obvious. When making a Panel Layout or setting the css on a region on the Content area when making a Panel Page (see attached images) etc you can set a Class and or ID. Would it be possible to make the Class/ID dynamic using the variables available like %term:vocabulary
So that region or page has more info about the content/context.

I am will to try and write a patch it people think it is even worth it?



Letharion’s picture

Title:Not sure if it is worth it but just an idea» Use keyword replacements for CSS settings

I think this is a good idea. I've wanted to be able to set CSS classes based on keywords on a pane by pane basis before, so this this would be great in my opinion.

Please name your issues better though in the future. "Not sure if it is worth it but just an idea" is not a good issue title.

merlinofchaos’s picture

Running a keyword substitution on the CSS should be relatively trivial as a patch. Anyone want to attempt it?

rogical’s picture

It makes sense, I think it should be using token to do this.

suldan’s picture

And for body classes too!

Yuri’s picture

@yurtboy: This is absolutely worth it, please go ahead.’s picture

Any word on this yet? I would love to be able to use substitutions in css ids/classes.

yurtboy’s picture

will work on it this week.

yurtboy’s picture

Gave it a look at today and though the php code seems trivial finding where to put it is that hard part ( -:
Basically I see one place so far that is rendering the css token line 295.
But not sure the best function to to process the token(s) that may exists in that area (if this is the correct area)

After this is done I can apply the same logic/function to the ID etc as needed for the Body and for the per pane classes/IDs and update the form fields instructions.

I found this function ctools_context_token_convert but ran out of time before I could get anywhere with it.

Any suggestions?

hixster’s picture

Would love to use this, has there been any progress?

fledev’s picture

found out that the Body css is parsed at panels/panels.module line 1770:

$vars['classes_array'][] = check_plain($panel_body_css['body_classes_to_add']);

The function that converts the substitution tokens into values is:

ctools_context_keyword_substitute($panel_body_css['body_classes_to_add'], array(), $context);

where the $context variable has to be provided. Any ideas how to get this one via call into the panels_preprocess_html() function?

I've also found the functions: ctools_include('context'); & ctools_include('context-task-handler'); which I have no idea how to handle.

It would be great if anyone could help me out to finish this patch.


davidwhthomas’s picture

Patch could perhaps be to panels_panel_context_render which has

// Remove and add body element classes
$panel_body_css = &drupal_static('panel_body_css');

and has $context available.
$panel_body_css = &drupal_static('panel_body_css');

Is used later in panels_preprocess_html


davidwhthomas’s picture

Version:7.x-3.0» 7.x-3.x-dev
Status:Active» Needs review
new2.73 KB

Patch attached!

fledev’s picture

Version:7.x-3.x-dev» 7.x-3.0
Status:Needs review» Active
new986 bytes

Thanks to dekita the line 295 of panels\plugins\task_handlers\ has to be changed to:

$panel_body_css['body_classes_to_add'] = ctools_context_keyword_substitute($handler->conf['body_classes_to_add'], array(), $contexts);

... see patch bellow.

davidwhthomas’s picture

Version:7.x-3.0» 7.x-3.x-dev
Status:Active» Needs review

Note, the patch in #12

1. Allows context keywords in raw Panels CSS textarea
2. Allows context keywords in body CSS classes to add
3. Provides the form element description text for those fields "Keywords from context are allowed".

Ready for review.


davidwhthomas’s picture

@frizi, could you please test/review the patch in #12? Thanks.

fledev’s picture

Thank you David, could this patch be implemented into the newest Panel version please?

davidwhthomas’s picture

Hi frizi, I rolled the patch against latest -dev?
The rest is up to the module maintainers.

fledev’s picture

Status:Needs review» Closed (fixed)


can confirm that the patch [css_substitution]-[1441218]-[6764646].patch is working just fine in both, Body CSS and Custom CSS field. Great work! thank you for your support (especially davidwhthomas).

If you don't mind I will close this thread as fixed due the provided solution.

davidwhthomas’s picture

Status:Closed (fixed)» Reviewed & tested by the community

frizi, please don't close the issue, the patch still needs committing.

davidwhthomas’s picture

Status:Reviewed & tested by the community» Needs review
suldan’s picture

Thanks guys for a great work. Tested patch and it's working for me. But we have to deal with whitespaces (replace with '-') for a clean css output. For example a two-word taxonomy term 'great patch' should be 'great-patch'.


davidwhthomas’s picture

Thanks for the update suldan.

I'm not sure how we can process the final class names to avoid spaces.
I thought about using drupal_html_class but because there may be more than one body class being added there, it's difficult to tell after keyword replacement what space is meant to be there, e.g between multiple classes, and what space comes from the context keyword replacement.

It seems like the context keywords may need to be extracted first, keyword replaced, css sanitized and then the css built again from there...

fledev’s picture


just for the record, in case that anyone would try to set the background image in panel, the $filename variable from the patch has to avoid filtering so the correct line would be:

$filename = ctools_css_store($css_id, $css, FALSE);

CogitoSrl’s picture

Version:7.x-3.x-dev» 6.x-3.10
Assigned:Unassigned» CogitoSrl

we have transalted the #13 for Drupal 6.
It works for CSS ID field.
In panels/plugins/task_handler/, function panels_panel_context_render, line 263

$display->css_id = $handler->conf['css_id'];

with this:

$display->css_id = ctools_context_keyword_substitute($handler->conf['css_id'], array(), $contexts);

Please review.

merlinofchaos’s picture

Version:6.x-3.10» 7.x-3.x-dev
Assigned:CogitoSrl» Unassigned

This issue primarily contains a patch for the 7.x version. Please don't change the issue back to 6.x. Even if you had attached a patch, 7.x will always be first, and 6.x can come afterward.

fledev’s picture

While using this patch on Node Template Panels, it get stuck at the first page which is called after clearing cache. You have to understand it like this: Having nid: 2,4,7 with an image field as background, each of these pages will have the background image of the first called page.

For ex having separate background images for those nodes and node 7 is called as first, the nodes 2 and 4 will have the keyword of node 7.

Any ideas how to avoid this issue? Can the keyword - image be set separately for each node or even disable caching?

Thank you.

fledev’s picture

Found out that the node template cache is build up after clear cache so the node from the first node template display is generated - it's css keywords are used and stuck there. This has to be workaround via: if (!$filename || true) { .... so the cache will be rebuild even if there is a file.

merlinofchaos’s picture

Status:Needs review» Needs work

Frizi: The patch only seems to allow classes on the body classes to add, not on the general CSS area? That seems like a valuable addition.

For the body class, I can see where we would want an option to make it safe. We do something similar to this in views, but to do it here we'd need a CTools patch to modify ctools_context_convert_context() to have an option to use convert to a class.

We could add, right before the return $value in that function, something like this:

  if (!empty($converter_options['css safe'])) {
    $value = drupal_clean_css_identifier($value);

Then we can just add array('css safe' => TRUE) to the options argument of ctools_context_keyword_substitute(). What's more, we can add that option in safely and if CTools doesn't have the necessary patch, it will just fail to clean the string but at least it won't totally break and crash.

davidwhthomas’s picture

Thanks Merlin, it's worth noting the patch in #12 includes ctools_context_keyword_substitute in the general CSS area.

I think the hard part is removing spaces from context keywords added and replaced in the general CSS textarea.

malberts’s picture

Status:Needs work» Needs review
new6.86 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch panels-css-keywords-1441218-30.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

Patch for #28 is at #1944712: Allow context keyword replacement to return CSS-safe value. That is required for the attached patch to work.

The patch attached here includes the patch by davidwhthomas in #12 along with some more changes.

In total, this patch adds context keyword replacement support and field description updates for:
- Remove body CSS classes
- Add body CSS classes
- CSS code
- (pane) CSS ID
- (pane) CSS class

I am not sure about the use case for replacements in the general CSS code section. If you want the raw value (like maybe a font family or raw CSS code) then it is going to return something with dashes and without spaces. If you want to use it to add classes/IDs then you will possibly get (title-cased) values like "My-Node-Title" because the value is not processed further to be either a valid HTML ID or a valid class. I don't think either of those is advised, but we need to decide which case to support. At the moment, the latter is implemented.

All the other changes in this patch do take the ID/class usage into account, so you will always get lowercased and valid ID values.

svajlenka’s picture

The patch in #30 is wonderful, thank you!

fledev’s picture

Version:7.x-3.x-dev» 7.x-3.3
new6.84 KB

Thank you @malberts for the patch.

For the ones that install the release module versions (drush wise), attached bellow is an adjusted version for the Panels 7.x-3.3 patch from malberts.

malberts’s picture

Version:7.x-3.3» 7.x-3.x-dev

@frizi: official patches should always be against the latest dev version ( It is then up to the maintainer to decide if it should be backported to a stable version.

Please note: The patch in #30 is the patch that needs to be reviewed. We should get a few more reviews before it can be marked as RTBC.

nicholaswyoung’s picture

I can confirm that the patch in #30 works properly. When can we expect to see this in the dev branch?

fledev’s picture

I'm fully aware of that but the thing is that you will use the release - latest version (as it is also recommended and automatized via drush) on your production project instead of unstable dev version. So there is a gap between the release and dev version which I was trying to fill with my proposed patch.

roberttstephens’s picture

The patch in #30 works well for me. Is there any way we can get this merged into the latest dev branch?

roberttstephens’s picture

Status:Needs review» Reviewed & tested by the community

I've been using the patch from #30 and it seems to work for nicholaswyoung and svajlenka as well. Therefore I'm changing the status to "reviewed & tested by the community".

B-Prod’s picture

Patch #30 works as expected.

shortspoken’s picture

Great! Works like a charme!

zabelc’s picture

I can confirm that the patch in #30 works against the stable version

kissmedve’s picture

Applied #30 against 7.x-3.3. Works as expected.

japerry’s picture

Issue summary:View changes
Status:Reviewed & tested by the community» Needs work
Related issues:+#1944712: Allow context keyword replacement to return CSS-safe value

Adding a dependency on #1944712: Allow context keyword replacement to return CSS-safe value before we can commit this.

For housekeeping, I'm marking as needs work until that other one is resolved. I'm personally not a fan of postponed, but that could work here as well.

MustangGB’s picture

Version:7.x-3.x-dev» 7.x-3.4
new6.89 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 7.x-3.4-panels-css-keywords-1441218-43.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

#30 ported to 7.x-3.4

MustangGB’s picture

Version:7.x-3.4» 7.x-3.x-dev

And back to dev

afoster’s picture

#43 - Tested and confirmed working in panels 7x-3.4 - thx for the patch.

fox mulder’s picture

Hi all!

the solution works perfect, but there is a problem for me. I need a css class in the next form: "node-NID-field-name" (dc_cart_ajax module needs it to update commerce fields if a commerce attribute field changed). If I type in css class input field the next: "node-%node:nid-field-name", I get this:"node- ". Any other than "-" works ok, "node_%node:nid_field-name" returns: "node_123_field-name". How can i solve this?

jibran’s picture

paskainos’s picture

Using #43 I noticed the label is output on key|label list item pairs, regardless of which entity token is chosen (i.e. %node:field-FIELD-NAME or %node:field_FIELD_NAME). Am I missing something?

BillyTom’s picture

I am using #43 to allow tokens in the field "Add body CSS classes". So far it seems to work in Panels 7.x-3.4

DamienMcKenna’s picture

Status:Needs work» Needs review

The last submitted patch, 30: panels-css-keywords-1441218-30.patch, failed testing.

Michelle’s picture

Status:Needs review» Needs work

I tested the patch in #43 against the current dev code (not 7.x-3.4) and it applies cleanly. I tried it out with %node:type and it worked fine. I don't know what #48 is referring to so didn't test that.

Even though this worked for me, I am setting it to "Needs work" as per japerry in #42 as #1944712: Allow context keyword replacement to return CSS-safe value has not yet been committed.

DamienMcKenna’s picture

Status:Needs work» Postponed

I don't think "needs work" is the appropriate status, I think "postponed" is.

maxplus’s picture


thanks for this great new Panels feature!
I have used #43 against Panels 7.x-3.4, but I applied it manually because it gave errors after auto apply.

It works great for me, hoping this will get committed sometime.

Status:Postponed» Needs review

Status:Needs review» Needs work

The last submitted patch, 43: 7.x-3.4-panels-css-keywords-1441218-43.patch, failed testing.

jantoine’s picture

Status:Needs work» Needs review
new7.42 KB
PASSED: [[SimpleTest]]: [MySQL] 0 pass(es).
[ View ]

Re-rolled for the latest dev.

smilne23’s picture

A great addition to Panels! Incredibly useful.

DamienMcKenna’s picture

@japerry: Should it explode() the string and execute drupal_clean_css_identifier() on each element before outputting the CSS class values?

gstout’s picture

new1.94 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch ctools-all-terms-w-spaces.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]


I think I see what you are getting at. I wanted to add all terms on a node as body classes. I was able to use the context...

"%terms:names_dashed --> Term name of all terms, separated by + or , and lowercased and spaces converted to dashes"

to get a list of all term on a article but then it was also out putting + signs in between each class. I patched Ctools to create a...

"%terms:names_dashed_spaces --> Term name of all terms lowercased and spaces converted to dashes, separated by spaces"

which works great, but that may be the wrong approach. Frankly I feel a little unworthy to be patching anything made by @merlinofchaos

Let me know you thoughts.

PS. Loving Panels Everywhere on my new site. It's my first panels experience and it's a very impressive system.

I'll include the patch here in case it helps someone with this specific issue.

Status:Needs review» Needs work

The last submitted patch, 62: ctools-all-terms-w-spaces.patch, failed testing.

DamienMcKenna’s picture

Status:Needs work» Needs review

@gstout: You'd need to add a new issue for CTools to handle that patch, and also update it to follow the Drupal coding standards.

Putting it back to "needs review".

axel.rutz’s picture

Status:Needs review» Reviewed & tested by the community

The patch in #57 fixes the issue for me.

as to damien's comment:

Should it explode() the string...?

Right now i don't see the value of spending cpu on doing this.

...and execute drupal_clean_css_identifier()...?

I see use cases for identifiers that don't pass that filter. (think underscores)

So setting RTBC (#57, NOT the unrelated #62).

japerry’s picture

new7.61 KB
PASSED: [[SimpleTest]]: [MySQL] 0 pass(es).
[ View ]

The patch in 57 needed rerolling so here it is.

smilne23’s picture

My comments from a separate issue ...

I think that terms should be lowercased and hyphenated and that multi term fields should keep terms separate.

"Term one, Term Two, Term number Three" Should probably appear in the CSS as "term-one term-two term-number-three", not as "term-one-term-two-term-number-three".

For me this is important when integrating jQuery projects where taxonomy terms are utilised as CSS selectors.

japerry’s picture

Status:Reviewed & tested by the community» Fixed


  • japerry committed c117538 on 7.x-3.x
    Issue #1441218 by fledev, davidwhthomas, japerry, malberts, MustangGB,...

Status:Fixed» Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.