I wanted to put a comma separator between the node term anchors. Unfortunately in my theme_links function I could find no way of knowing which set of links I was rendering, which makes that theme hook effectively global. I also only want comma separators on the node terms and not the primary links, secondary links etc which all go through the same theme hook.

I know I could put the node terms in a css identifiable <div> wrapper and use a background-image of a comma, but didn't want to as I want the commas to be visible to clients without css.

To get around this I created a theme_preprocess_node function, copied the core code and just added another class attribute, node-terms, to the node terms list :

$variables['terms'] = theme('links', $variables['taxonomy'], array('class' => 'links inline node-terms'));

This allowed me to isolate the node terms in my theme_links function and render the comma betwen each term link :

if(strpos($attributes['class'], ' node-terms') != false) {
      $separator = ', ';
      }
    else {
      $separator = '';
      }

This feels like a large amount of copy and pasting from core just to make two little tweaks. Is there another way to do what I want? Or is this level of theme function work common for fairly complex sites? Also the code in theme_preprocess_node feels slightly core in that I think it might change in Drupal 7 which means my theme function might as well be a hack to core that I merge in when I upgrade to 7

Or do I just want the moon on a stick? By the way I'm not bitching against Drupal, it TOTALLY NAILS the vast majority of my needs

In my mind this kind of problem could be solved by adding an identifier to theme() that could be picked up by the presentation layer. Eg;

$variables['terms'] = theme('links'=>'node-terms', $variables['taxonomy'], array('class' => 'links inline'));

'comment-node-terms' could then be passed to the template/theme function as $origin or similar

Comments

nevets’s picture

Sometimes that is the way things are when you only want a small difference. Personally I would do things slightly different, I would start by copying theme_links to theme_links_with_commas (or some name) and then in theme_preprocess_node do

$variables['terms'] = theme('links_with_commas', $variables['taxonomy'], array('class' => 'links inline'));

then modify theme_links_with_commas to use a comma for the separator.

(I don't like unneeded string compares)

barful’s picture

Thanks nevets you are 100% very right about using a specific theme function - I'll change it now and make it a habit to think that way for future theme hooks

barful’s picture

What do you think about my idea to change theme() so that an identifier token can be passed to the theme template/function?

I frequently have the problem where I want to target a particular instance of a box/comment/links etc, but can't identify the instance, it's too generic at the tpl.php.. if I make a change for one "links" it changes all.. I often only want to make a change for one

For example, I put a link to #comment-form at the top of the node so the user can jump to the comment form. When you select this link the browser scrolls down to the comment form, but this means the header "Leave a comment" isn't displayed because it is before the comment form. So I want to edit box.tpl.php just for the comment form and put an id on the header there so I can #reference it in the link - I would change the "Jump to comments form" link to link to the header now it has an id, and jumping to the comment form would also display the header

But I can't target a specific instance of box!

This is what I wrote originally :

In my mind this kind of problem could be solved by adding an identifier to theme() that could be picked up by the presentation layer. Eg;

$variables['terms'] = theme('links'=>'node-terms', $variables['taxonomy'], array('class' => 'links inline'));

'node-terms' could then be passed to the template/theme function as $origin or similar

So in this example with box.tpl.php the core function comment_form_box() would look like this :

function comment_form_box($edit, $title = NULL) {
  return theme('box'=>'comment-form', $title, drupal_get_form('comment_form', $edit, $title));
}

Changing theme() to handle this would mean it is still backwardly compatible with the current method eg; theme('box'...), as it would just is_array() the $hook parameter. The string 'comment-form' would be passed along to the theme template/function where I would have a bit of code that says :

<?php if($origin == 'comment-form') {?> id="comment-form-header" <?php } ?>

That would make me happy