2

I have a bespoke Content Type pertaining to venues. These are not user-creatable; they are all created from importing a trusted third-party feed, which sanitised the titles before they come to me (so there's no risk of XSS or SQL Injection here). The titles might, however, contain accented characters (é, ô etc), apostrophes (') or ampersands (&); these are coming out as HTML escapes (so ' instead of an apostrophe, & instead of an ampersand, etc).

The Content Type Venue has a field title, which is a Node module element, so doesn't allow me to mess with its display settings. In the Node template page, I can use substitutions in the display of this title, but I can't work out how to make it be the raw text version. The title is currently set to display as %node:title and I tried using %node:title:raw and %node:title-raw in case one of those would magically work, but they had no effect.

I saw something that looks like a potential solution at Custom HTML in Drupal Node Titles on zerotodrupal.posterous.com, which attaches to the hooks hook_preprocess_page and hook_preprocess_node, creating a new method like

function hhhdarkelegance_custom_title($node) {  
    return check_markup(strip_tags($node->title, '<em><em>'));  
}

but, while that blog post looks like it will work well for named HTML tags, I'm not sure it will necessarily deal with HTML entities, which are what my problem is here. I suppose I could do the opposite to the blog-post code and replace out &amp; to & before display, but that feels really kludgy and, frankly, it would be nice to be able to do this just using a substitution, if possible.

Is there some way of achieving this that doesn't involve cutting code? If so, is strip_tags what is causing the HTML escapes? (The function description reads as though it's only causing the removal of HTML tags, which I am fine with either way — they won't occur in my node titles. I am wanting to stop escaping the HTML escapes, however.)

So how can I (on a specific Content Type, without worrying about security concerns) prevent Node titles from rendering HTML escape characters to the usual and just write the damn output to the page?

I did scan through several pages of similar-looking questions before posting and I couldn't find one that addressed this, so my apologies if someone has asked this already; if you point me towards it I'll be suitably embarrassed and try even harder next time. Thanks for your help, everyone!

4 Answers 4

3

Whilst Jon's suggestion of htmlspecialchars_decode got me part of the way there, it turns out that the sample code from Custom HTML in Drupal Node Titles was less helpful.

Whereas that blog post suggested I do something like:

function modulename_preprocess_page(&$vars, $hook) {  
    $node = &$vars['node'];  
    if($node->type == 'my_content_type') {  
            $vars['title'] = htmlspecialchars_decode($vars['title']);  
            $vars['head_title'] = $vars['title'];  
    }  
}

I actually needed to do this:

function modulename_preprocess_page(&$vars, $hook) {
    $node = &$vars['node'];

    if ($node->type == 'my_content_type') {
        drupal_set_title(htmlspecialchars_decode(drupal_get_title()), PASS_THROUGH);
    }
}

Problem solved!

3

I've been searching for a solution to this for a client project i've been asked to help out on. Sometimes it's just not feasible to go around using htmlspecialchars_decode() if the data is supposed to contain HTML entities, such as medical articles etc. Or entities are being introduced by a Triggered Rule configured to create a node and setting the title causes entities to be encoded in the node title. (These are the two situations I seem to run into in D6) Yes I could go around trying to work around all these things, but really it's sometimes just easier to have HTML entities being displayed properly so things work as they should.

I was looking for a solution to handle node titles on the node pages plus and also in Views.

Thankfully it looks like the module HTML Title appears to provide exactly this functionality now. Looking at the code it covers both the node page and displaying the title in Views.

Note that it looks like this module only appeared around July 2012, which is after some of the other answers here. For others looking for a solution this module might be an easier route than writing code to try and catch things. It's available for both D6 and D7. Note: I haven't tried it at all, I just found it and scanned the code right before I found this post, it looks promising and thought it might be useful for anyone else searching for a solution to this.

2

Would htmlspecialchars_decode() be relevant then?

3
  • Ooh yeah, that looks like it's precisely what I need if I do go for a code-based solution. I'm still holding out hope for a substitutions-based answer, though ;o) Commented Mar 20, 2012 at 9:46
  • (Translation: I'll give you a green tick if I don't get any better answers and the Custom HTML in Drupal Node Titles blogpost is the right hooks to attach to ;o) Commented Mar 20, 2012 at 9:47
  • Specifically for &#039; instead of an apostrophe, you need to use the ENT_QUOTES flag, otherwise it is ignored. Commented Aug 25, 2015 at 17:32
2

First off, there is no such thing as catch-all method to sanitise your data (at least not without losing some of your data) - you need to sanitise it separately for each use case. That means you HTML-escape it before outputting it to a web page, SQL-escape before including it in a database string etc.

The title field is designed to store plain text, so you shouldn't be including HTML entities in it at all - change your import process to call htmlspecialchars_decode() before they are saved in the field. That way Drupal can HTML escape the field and everything will be good. You're actually introducing a potential XSS vulnerability if someone did find an alternative way of editing the title field.

Your Answer

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

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