Inserting HTML into node titles

Last modified: February 21, 2008 - 12:33

Drupal strips all HTML from node titles when they're displayed to prevent XSS exploits. However, there are some cases where inline HTML elements are needed, such as when titles contain scientific names.

To work around this, we will use pseudotags like [i] and [/i] which Drupal will safely translate into real HTML tags when the page is displayed.

The PHPTemplate file page.tpl.php will need to be edited in order to make this trick work. Specifically, we need to add two new functions.

<?php
function bb2html($text) {
 
$bbcode = array(
                 
"[strong]", "[/strong]",
                 
"[b]""[/b]",
                 
"[u]""[/u]",
                 
"[i]""[/i]",
                 
"[em]", "[/em]"
               
);
 
$htmlcode = array(
               
"<strong>", "</strong>",
               
"<strong>", "</strong>",
               
"<u>", "</u>",
               
"<em>", "</em>",
               
"<em>", "</em>"
             
);
  return
str_replace($bbcode, $htmlcode, $text);
}

function
bb_strip($text) {
 
$bbcode = array(
                 
"[strong]", "[/strong]",
                 
"[b]""[/b]",
                 
"[u]""[/u]",
                 
"[i]""[/i]",
                 
"[em]", "[/em]"
               
);
  return
str_replace($bbcode, '', $text);
}
?>

This is how you make a phrase in the title italicized:

My title [em]rocks[/em]!

One problem with this approach is that node title also shows up in the page titles, and page titles are not allowed to have any markup. That's where the above bb_strip function comes in. Between the HTML title tags in page.tpl.php, add the following:

<?php print bb_strip($head_title); ?>

And whenever you reference the node title in your template use this:

<?php print bb2html($title); ?>

NOTE: If you use books, this mechanism has a problem unless you are willing to patch book.module. book.module, in the function book_tree_recurse, creates links to nodes by their title, and of course doesn't know to use your code

regexes

wholcomb - August 21, 2006 - 05:59

If you want to guarantee that tags are closed, you can use the clichéd regex with a backreference:

<?php
function bb2html($text) {
 
$bbcode_regex = '/\[(strong|cite|em)\](.*)\[\/\1\]/';
  return
preg_replace($bbcode_regex, '<$1>$2</$1>', $text);
}
?>

One correction

sander-martijn - August 21, 2007 - 20:04

If you want/need to access these functions from node.tpl.php or any other file you will need the function to live in template.php. Even if you are only calling it in page.tpl.php it's probably a better idea to keep it in template.php for the sake of code separation. Other than that, great fix for an annoying problem. Now if only we can find a solution for special characters.

so no one ever got the special characters in node title solved..

redhatmatt - February 5, 2009 - 05:20

almost seems like replacing say [amp] with & would maybe kinda work???

Bummer, maybe not...

Newlines

felipensp - September 4, 2007 - 11:00

Use the modifier 's' in regex to match newline inside of tags.

Using Views...

r00lnyi - March 6, 2008 - 14:31

If you-re using views and want do highlight one or some titles in views-result page or block .....

1. First of all you need edit view.module
Take this function

function theme_views_view_list($view, $nodes, $type) {
  $fields = _views_get_fields();

  foreach ($nodes as $node) {
    $item = '';
    foreach ($view->field as $field) {
      if (!isset($fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
        if ($field['label']) {
          $item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";
        }
        $item .= "<div class='view-field ". views_css_safe('view-data-'. $field['queryname']) . views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view) . "</div>";
      }
    }
    $items[] = "<div class='view-item ". views_css_safe('view-item-'. $view->name) ."'>$item</div>\n"; // l($node->title, "node/$node->nid");
  }
  if ($items) {
    return theme('item_list', $items);
  }
}

and replace by this

function theme_views_view_list($view, $nodes, $type) {
  $fields = _views_get_fields();

  foreach ($nodes as $node) {
    $item = '';
    foreach ($view->field as $field) {
      if (!isset($fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
        if ($field['label']) {
          $item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";
        }
        $item .= "<div class='view-field ". views_css_safe('view-data-'. $field['queryname']) ."' id='v".$node->nid."'>" . views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view) . "</div>";
      }
    }
    $items[] = "<div class='view-item ". views_css_safe('view-item-'. $view->name) ."'>$item</div>\n"; // l($node->title, "node/$node->nid");
  }
  if ($items) {
    return theme('item_list', $items);
  }
}

So every view element item has id="number of node" anywhere. Do not forget you cant use digits only in css id's so i added "v" as prefix.

Then just css. For example ...

#v3640 a:link, #v3640 a:visited  {
color: red;
font-weight: bold;

}

submitted as a patch

christefano - May 1, 2008 - 21:28

This proposed modification has been submitted as a patch. Please review it at http://drupal.org/node/253686 when you have a chance.

Special Characters in Node Title solved / example

redhatmatt - February 5, 2009 - 08:46

Ok so here is a little clearer instructions on implementing the previous snippet AND how to add special characters for those of you who did not follow what was here:

Go to your template.php file in your themes folder for the them you are using and open it... right after the initial php opening tag line 1:

<?php
function bb2html($text) {
$bbcode = array(
"[strong]", "[/strong]",
"[b]", "[/b]",
"[u]", "[/u]",
"[i]", "[/i]",
"[em]", "[/em]",
"[amp]", "[theta]", "[degree]", "[prime]", "[doubleprime]", "[squareroot]"
);
$htmlcode = array(
"<strong>", "</strong>",
"<strong>", "</strong>",
"<u>", "</u>",
"<em>", "</em>",
"<em>", "</em>",
"&amp;", "&theta;", "°", "&prime;", "&Prime;", "&radic;"
);
return
str_replace($bbcode, $htmlcode, $text);
}

function
bb_strip($text) {
$bbcode = array(
"[strong]", "[/strong]",
"[b]", "[/b]",
"[u]", "[/u]",
"[i]", "[/i]",
"[em]", "[/em]",
"&amp;", "&theta;", "°", "&prime;", "&Prime;", "&radic;"
);
return
str_replace($bbcode, '', $text);
}

Save it...

then open up page.tpl.php and find the lines that mention $title... basically we want to slip in

<?php print bb2html($title);
?>
there but modify what is actually in YOUR page.tpl.php file... in my instance I was using plain old Garland (yippee!)

so I found:

<?php
if ($title): print '<h2'. ($tabs ? ' class="with-tabs"' : '') .'>'. $title .'</h2>'; endif;
?>

around line 68
and replaced it with:
<?php
if ($title): print '<h2'. ($tabs ? ' class="with-tabs"' : '') .'>'. bb2html($title) .'</h2>'; endif;

Finally put this (as he said before) between the title tags at the top to strip the [whatever] items out of your title...

<?
php print bb_strip($head_title);
?>

Ok so that's it, hopefully you can get through the patterns now... if you still have issues I will subscribe to this thread or just contact me, for my instance I needed only scientific special characters... so I am going to make a completed list of characters and post the whole thing here when I am done, so whomever will not have to do the same work again...

 
 

Drupal is a registered trademark of Dries Buytaert.