Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to use Myanmar Unicode text on my blog. Unfortunatly, pseudo-Unicode Myanmar fonts are common. So, I am writing a plugin that will suround all Myanmar phrases with HTML span tags, and use css to select the proper font.

Everything works fine for content, comments, etc. However, after adding HTML using the the_title hook, that HTML gets escaped, and then included in the title attribute of the link tag in the recent posts section. In addition, I'm seeing the raw HTML tags in the post name on my admin post screen.

How should I go about solving this problem? I prefer to do everything from within my plugin, not change the theme files or something.

Here is my code:

add_filter( 'the_title', 'addThemSpans');
function addThemSpans($theTitle) {
  // functionality to add span tags to $theTitle so that a title that looks like this...
    // LatinTextHere ကကကကက​ MoreLatinText
  // becomes this...
    // LatinTextHere <span class="myText">ကကကကက</span> MoreLatinText
    // in the final output.
  return $theModifiedTitle;
}

As it is now, the title attribute for the link in the recent posts sidebar widget is set to:

LatinTextHere &lt;span class=&#039;myText&#039;&gt;ကကကကက&lt;/span&gt;<span class='myText'>ကကကကက</span> MoreLatinText

Which is not right.

share|improve this question
1  
It would help if we could see the actual functionality that's adding the <span>s. –  EAMann Jan 19 '13 at 15:01
    
I can give you the functionality if you really need it, but it's a big class and several functions. When finished, $theModifiedTitle looks like the example I gave. –  Ben Sharon Jan 19 '13 at 15:17
add comment

4 Answers 4

the_title is the correct hook. You can confirm that by checking the source.

What you are doing is a bit odd, but it makes sense. Clever solution but I don't think it was expected. The problem you having seems to be with this line:

http://core.trac.wordpress.org/browser/tags/3.5/wp-includes/default-widgets.php#L574

<a href="<?php the_permalink() ?>" title="<?php echo esc_attr( get_the_title() ? get_the_title() : get_the_ID() ); ?>"><?php if> (get_the_title() ) the_title(); else the_ID(); ?></a>

And there is no hook that will help you. The widget grabs the title with get_the_title and doesn't pass it through anything that you can manipulate.

I think you may need to rethink your approach.

  1. If this is a situation where you can edit the theme you can remove your filter before the sidebars runs and add it back afterwards. I think that is the most straightforward way to do it but may not be possible in you case.

  2. You could also write your own recent posts widget.

  3. You could manipulate your fonts with Javascript-- not sure it that would be robust enough for you.

You might be able to check for an $instance variable in your filte and sort out whether you are dealing with a widget or not.

add_filter( 'the_title', 'addThemSpans');
function addThemSpans($theTitle) {
  global $instance;
  var_dump($instance); // see if this works.
  // functionality to add span tags to $theTitle so that a title that looks like this...
    // LatinTextHere ကကကကက​ MoreLatinText
  // becomes this...
    // LatinTextHere <span class="myText">ကကကကက</span> MoreLatinText
    // in the final output.
  return $theModifiedTitle;
}

I don't know if that will work or not, but if so it will give you something to switch on and you won't have to edit the theme. Edit: Tested. Sadly, doesn't work.

share|improve this answer
    
Ok, I suspected that the answer would be somthing like that. I can, and probably will, end up editing my theme files. That just makes it harder to share with others who need to use Myanmar on their blogs. I'll leave this thread open incase anyone else has any ideas. –  Ben Sharon Jan 19 '13 at 15:47
    
Yes, I understand. Your plugin could include its own modified Recent Posts widget though. –  s_ha_dum Jan 19 '13 at 15:55
    
I'm seeing just now, it's not only the Recent Posts widgits. The tags are showing up in the admin posts page too. –  Ben Sharon Jan 19 '13 at 15:59
    
I was afraid the issue would show up elsewhere. Javascript is looking like your best option. –  s_ha_dum Jan 19 '13 at 16:12
add comment

So, what's happening is that the_title_attribute(), which outputs the title attribute in the Recent Posts widget links, calls get_the_title(); thus, your the_title filter is being applied to the string returned by the_title_attribute().

One idea would be to ensure that get_the_title is being called from within the main query loop (caveat: if you use WP_Query() loops, this approach would not work for them).

Perhaps something like this (untested).

Edit

This won't work as-written. If you could find some way to grab the current $query object from inside of get_the_title(), then you could do something like this:

function wpse82297_filter_the_title( $title ) {
    // Need some way to identify the current query object
    $query = '';
    // If this isn't the main query, return
    if ( ! $query->is_main_query() ) {
        return $title;
    } else {
        // Your $title filtering goes here
        return $modified_title;
    }
}
add_filter( 'the_title', 'wpse82297_filter_the_title' );

So, this would prevent your filter from being applied to Nav Menu items, Recent Posts Widgets, etc. - anything except for the main query loop.

I'll leave this here as an answer, in case anyone can think of a way to identify the current $query object.

share|improve this answer
    
This returns Notice: Undefined property: WP_Query::$is_main_query... what next? Also, I would like the spans inserted in those other places too, just not in the HTML attributes. –  Ben Sharon Jan 19 '13 at 15:27
    
Ok, so add () onto is_main_query, and it runs fine. The span tags are still in the html attributes though. Same as before... –  Ben Sharon Jan 19 '13 at 15:37
    
Ah, thanks for spotting the typo. :). And yeah, let me edit. calling the global $wp_query will always return true for is_main_query(). I need more coffee... –  Chip Bennett Jan 19 '13 at 15:41
    
Okay, stab in the dark, and if this doesn't work, then I don't think there's a way to make this approach work: what happens if you replace $wp_query->is_main_query() with just is_main_query()? –  Chip Bennett Jan 19 '13 at 15:49
    
Same as before... –  Ben Sharon Jan 19 '13 at 15:51
show 1 more comment
up vote 1 down vote accepted

Ok, I thought I'd post my final solution up here in case anyone else has the same problem. Basically, I have to add new hooks to my theme files, and then send the modified post title to those hooks.

My plugin code now looks like:

add_filter( 'the_html_safe_title', 'addThemSpansToPostTitles' );
function addThemSpansToPostTitles() {
  global $post;
  echo addThemSpans($post->post_title);
  // This is the same function I listed in the question.
}

Then, in the theme template files, where previously it was:

<?php the_title(); ?>

I change it to:

<?php do_action( 'the_html_safe_title' ); ?>

This is less than ideal for at least two reasons:

  1. The titles in places such as the Recent Posts widget don't get the spans inserted, meaning that, depending on the viewer browser, font settings, and installed fonts, the viewer will still see mangled text in those locations.

  2. This makes it much harder to share the plugin with other Myanmar language bloggers who may not have the technical skills to modify their themes, and may not want to use my theme.

Attention wordpress developers: I have seen a significant number of people online wishing they could include HTML in their post and page titles. Allowing us to do so makes lots of sense, not only for specialty situations like mine, but for users who want to change their titles in other ways. Please consider changing future wordpresses to allow HTML in titles.

share|improve this answer
add comment

You can convert them back simply using htmlspecialchars(), which is a native PHP function.

From the manual:

The translations performed are:

  • '&' (ampersand) becomes '&amp;'
  • '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
  • "'" (single quote) becomes '&#039;' (or &apos;) only when ENT_QUOTES is set.
  • '<' (less than) becomes '&lt;'
  • '>' (greater than) becomes '&gt;'

Anyway, I wouldn't do this if you don't know every user personally (and know that they care about internet security and don't reuse passwords) or this is for yourself only. As you convert back those characters, you're not save if anyone escapes your string and does funky stuff in your installation.

share|improve this answer
    
This doesn't help because I don't want html tags in link title attributes anyway. –  Ben Sharon Jan 19 '13 at 15:18
    
@BenSharon Ehm... you wanted to put <span>-Tags in the header, right? –  kaiser Jan 19 '13 at 18:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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