2

To preprocess the node title field is obviously not the easiest. It has its place in the node.tpl.php and in the page.tpl.php by default and it has its own status in Drupal core, which makes it not fieldable as simply as other fields and entities in a given content type bundle.

That's why there are many discussions going on at drupal.org and some little helper modules are also around already, to make the title field more flexible in different scenarios like field translation, label design, field order and much more. So if this is your problem you will easely find a little module helping you.

But what if you don't want to touch the behaviour of the title field as designed in core but only want to preprocess the title to change the markup dynamically? Suddently google keeps silent. Unlike others I agree with some core contributors who explain wisely why the title field has its reasonable difficulties and why the decision to make it simply a "field like others" is not THAT easy to make. So for some reasion I need a solution in template.php

This is how the page.tpl.php looks like in my case:

// page.tpl.php    

<?php print render($title_prefix); ?>
    <?php if ($title): ?>
        <?php if ($page): ?>
            <!-- This is where we want to get in with template.php -->
            <h1 <?php print $title_attributes; ?>> 
                <?php print $title; ?>
            </h1>
        <?php endif; ?>
    <?php endif; ?>
<?php print render($title_suffix); ?> 

And this the place where we obvisously should try to make it happen:

// template.php

function YOURTHEME_process_page(&$variables) {
    if ($variables['view_mode'] == 'full' && 
        node_is_page($variables['node'])) {
            // do something with $variables['title']['attributes'][];
    }
}

But to be honest, I am a little bit lost here, since I only want to change the rendering of <h1> to <h1 class="my_css_class">. Does anybody has an idea of how to achieve this?

The attributes class seems not to exist this way, because I get an Unknown index warning and the class gets not attached. Or maybe I have to point to $title another way? Maybe something like $node->title ? I know how to wrap the title with a new container, or how to change the suffix/prefix. But here would really appreciate your thoughts. Thank you very much ...

4
  • I think this is going to be impossible to answer here - $title_attributes is not added by Drupal core (see the source of page.tpl.php), so it must be a theme/module specific to your installation that's adding it. WIthout knowing what the theme/module is I don't see how this can be answered
    – Clive
    Jun 25, 2013 at 12:02
  • Thanks Clive. So you think there is also no chance to achieve this rather in preprocess_node or preprocess_field? It is an own custom theme. So nothing where I have to stick with the way the tpl. files are build. I can change it to the needs. In Bartiks node.tpl.php there is a title_attributes placeholder but this doesn't affect the full node page title anyway, so I also will have no luck with the two other preprocess functions, I guess. :(
    – nilsun
    Jun 25, 2013 at 12:19
  • If it's there, and it's got there in any sort of 'Drupal' accepted manner, then you should be able to alter it in either hook_preprocess_page() or hook_process_page(), depending on which one's actually been used in the first instance. I'd search through your custom theme/modules for the term $vars['title_attributes'] or $variables['title_attributes'] to see if you can find where it's being set. From there it should be easy
    – Clive
    Jun 25, 2013 at 12:21
  • 1
    Okay, another idea: a little bit dirty since this is far away from the way it is supposed to be, but hiding '$title' in page.tpl.php and removing the IF NOT PAGE condition from the standart node.tpl.php (like in Bartik) makes it possible to access the title-attributes array, since node.tpl.php seems to know title-attributes, page.tpl.php not (as you sad) - But in this case I have to reimplement the node is page node list switch between h1 and h2 programmatically in template.php somehow again, sonce $title in page.tpl.ph did this before. Let's wait and see if this makes sense. I'll try.
    – nilsun
    Jun 25, 2013 at 12:34

4 Answers 4

2

Okay, as commented under the question, I've tried out another idea: a little bit dirty since this is far away from the way it is supposed to be, but hiding '$title' in page.tpl.php and removing the IF NOT PAGE condition from the standart node.tpl.php (like in Bartik) makes it possible to access the title-attributes array, since node.tpl.php seems to know title-attributes, but page.tpl.php not...

But in this case I have to reimplement the programmatically "node is page OR node list switch" toggling of h1 and h2 again, since if-page $title in page.tpl.php did this before:

After removing the complete if-title-title part (in Bartik it looks like this, near the $content) from page.tpl.php,

<?php print render($title_prefix); ?>
  <?php if ($title): ?>
    <h1 class="title" id="page-title">
      <?php print $title; ?>
    </h1>
  <?php endif; ?>
<?php print render($title_suffix); ?>

... I have added (exchanged) this in the node.tpl.php:

//node.tpl.php

// usually we have something like the following here
/*
<?php if (!$page): ?>
   <h2<?php print $title_attributes; ?>>
      <a href="<?php print $node_url; ?>"><?php print $title; ?></a>
   </h2>
<?php endif; ?>
*/

// but we exchange it with this ...

<?php print render($title_prefix); ?>

  <?php if ($page): ?>
    <h1<?php print $title_attributes; ?>>
       <a href="<?php print $node_url; ?>">
          <?php print $title; ?>
       </a>
    </h1>
  <?php endif; ?>

  <?php if (!$page): ?>
    <h2<?php print $title_attributes; ?>>
      <a href="<?php print $node_url; ?>">
         <?php print $title; ?>
      </a>
    </h2>
  <?php endif; ?>

<?php print render($title_suffix); ?>

Now I do have my title inside of my wanted scope, where I can theme it programmatically inside the main content container. Thanks to Clive for his support on my question, and special thanks to Digidog from drupal.org, who gave me the final hint per mail.

2

This is how I add classes to titles from page.tpl.php:

In page.tpl.php:

<?php if ($title): ?><h1 <?php print $title_attributes; ?> id="page-titles"><?php print $title; ?></h1><?php endif; ?>

Note that $title prints the title itself. Note that $title_attributes prints out class='' where included classes are found in $title_attributes_array['class'][].

You can add classes the following way. In template.php:

/**
 * Implements template_preprocess_page().
 */
function hook_preprocess_page(&$vars) {

  $vars['title_attributes_array']['class'][] = 'element-invisible';

}

Note that the hook_preprocess_page function should be [your_theme_name]_preprocess_page.

What's interesting is that $title_attributes does not exist in the available variables. Drupal does some magic to allow $title_attributes to print as class='class1 class2' based on what $title_attributes_array contains.

1
  • I'm on my tablet, but I think $title_attributes comes from a hook_process and not a preprocess, so that is why you don't see it.
    – mpdonadio
    Jan 30, 2014 at 2:14
1

If you are okay with using jQuery, then you can achieve this using the addClass method.:

 function YOURTHEME_process_page(&$variables) {

   if ($variables['view_mode'] == 'full' && node_is_page($variables['node'])) {

       drupal_add_js('
       jQuery(document).ready(function(){
            $('jQery SELECTOR OF H1').addClass('my_css_class');  
        });

    ', 'inline');

}

}

2
  • 1
    Thanks sandesh yadav. This is a very smart solution, but sadly I have to care about accessibility and users who have js turned off. The new markup I need in here is sadly essential for the readability of the node. But it's a very nice solution and it will help me on other questions. :) Thank you
    – nilsun
    Jun 25, 2013 at 11:43
  • welcome.Most of the users have js turned on now a days. But still you cant rely 100% on it. :) Jun 25, 2013 at 11:46
1

This is how I made it work:

template.php

/**
 * Implements template_preprocess_page.
 */
function my_theme_preprocess_page(&$vars) {
  $node = isset($vars['node']) ? $vars['node'] : '';
  // Set class name for the page's title.
  $vars['class_name'] = node_is_page($node) && $node->type == 'node_type' ? ' title-class-name' : '';
}

page.tpl.php

<?php if ($title): ?>
  <h1 id="page-title" class="title<?php print $class_name; ?>"><?php print $title; ?></h1>
<?php endif; ?>

Alternatively you may use the Display Suite module which, of course, exceeds the limits of just adding a class to a title.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.