Saturday, 20 January 2007

New Blogger: expr - how to convert template tags to data tags for social bookmarking badges etc

(A.k.a. Data tags, and what's all this "expr:href" stuff in my New Blogger template??)

In the now feature complete fancy new Blogger, formerly known as Blogger Beta, old Blogger (classic Blogger) template tags are no more.

Template tags representing the current post's title, permalink or direct URL, date, unique ID, or your blog's title or blog URL etc, are often used in code to help people add your posts to, Furl and other Web 2.0 or social bookmarking sites like Digg or track who's linking to your post according to e.g. Technorati or BlogPulse or Bloglines, or appear in other add-ons like Haloscan trackback etc - that sort of code seems increasingly to be called "badges" or "widgets".

With new Blogger "layouts" you have to use "data tags" instead. E.g. <data:post.title/> instead of <$BlogItemTitle$> for a post's title, and <data:post.url/> instead of <$BlogItemPermalinkURL$> for its URL.

But they don't work in the same way as the old template tags. If you look at the data tags help you might be forgiven for thinking for instance that instead of [corrected mistake!] <$BlogItemTitle$> you now just substitute <data:blog.title/> or <data:post.title/>. Well that's not strictly correct, and if you try to do that it may not work.

Now, you could just copy and paste codes or follow instructions which others have kindly provided for New Blogger (e.g. Vivek's for social bookmarks and Logical Philosopher for Haloscan, or Web Messenger for Technorati link count). Or you could just quickly add a third party page elements widget that someone else has created, like my Technorati link count widget.

But if you want to understand how the new equivalent of template tags now works, and how to convert old template tags for New Blogger so that you can sort out for yourself other codes not already covered and add new badges or widgets to your New Blogger blog for other websites or services in future, here's my explanation and step by step howto, as Blogger still haven't documented this fully at the time of writing this post.

What and how: step by step howto

First, note that it matters whether the data tag e.g. <> is PART OF an HTML tag, inside the angle brackets (like <a href="templatetag">), i.e. whether it's part of an attribute's value - or whether it's outside of the HTML tag's angle brackets.

If it's not inside the HTML tag (i.e. between the angle brackets, the <> of the opening tag), you can just use the data tag as is - see further example below.

If it is inside an HTML tag, forming part of the value of an attribute like href (meaning it's included in the "stuff" part of href="stuff"), then you have to rewrite the tag, or rather any bit inside the tag that says something="somethingelse including template tag" (e.g. href="<$BlogItemURL$>").

Example for adding to Delicious

<a href="<$BlogItemPermalinkURL$>
&amp;title=<$BlogItemTitle$>" target="_blank"></a>


<a expr:href='"" + data:post.url + "&amp;title=" + data:post.title' target='_blank'>Add to</a>

Here's a howto, and trust me it's a lot simpler to do than to explain!

1. Change href= to expr:href= (the added bit is in bold black).

2. If it originally read href='stuff' using single quotes, that's fine till the next step. But if it's surrounded by double quotes, e.g. href="stuff", change those to single quotes i.e. href='stuff'. Marked bold red in the example above too. Change any double quotes you see inside 'stuff' to single quotes too. (Note: it might say href="stuff" target="somethingelse". You can ignore the target="somethingelse" bit, except to change the double quotes to single quotes (and any single quotes within the "somethingelse" to double quotes, confusing I know!). We're mainly concerned just with the stuff within the first set of quotes.)

3. You now have to look at what's inside the single quotes and separate out the old Blogger template tags. It's easiest to add a space before or after each old template tag as appropriate, so that you have separate blocks inside the single quotes. So

<a expr:href=' <$BlogItemPermalinkURL$> &title=<$BlogItemTitle$>' target='_blank'></a>

(don't put any spaces between the template tag and either the starting or the ending single quote, though).

4. Now make sure each block inside the single quotes which is NOT a template tag has double quotes surrounding it, by inserting double quotes in the right places. Marked bold purple below - don't forget the one just after the opening single quote. So now it's:

<a expr:href='"" <$BlogItemPermalinkURL$> "&title=" <$BlogItemTitle$>' target='_blank'></a>
Repeat after me: No curly quotes. Never ever ever. Kill all curly quotes (yes I'm talking to you, Microsoft Word). Curly quotes are the work of the devil and will mess up your code and template, stop things from working, and make you cry and tear out your hair. Eradicate them immediately and never, ever, ever let them darken your HTML/XML again.

5. Finally, change the old template tags to their equivalent data tags, but WITHOUT any angle brackets round them, and with + signs between them and the other blocks in the href. So, if, in the bit surrounded by single quotes, the data tag is at the start, add a + sign after it; if in the middle with other blocks, add a + sign before and after it; and if at the end just before the closing single quote, just add a + sign before the data tag (it's much easier to see/follow than explain!). Be careful not to accidentally delete the existing single quotes, and there should be no spaces between the single quotes and what they surround. It then becomes (in bold orange):

<a expr:href='"" + data:post.url + "&title=" + data:post.title' target='_blank'></a>

(note there's no space between the ending data:post.title and the closing single quote ').

6. Rinse and repeat (i.e., do that again for all the other attributes in the HTML tag whose value includes a template tag, such as somethingelse="morestuff". If there's no template tag inside the morestuff you don't have to do anything to the morestuff except change the double quotes to single quotes and vice versa. As we did with target='_blank'.)

(Note: yes maybe you can swap the double and single quotes and get it to work, but as New Blogger uses them in the order/way I've stated above, best to follow that.)

Another example - data tag not within HTML tag; escaping quotes

Remember that I said if it's not inside the HTML tag, you can just use the data tag as is? Here's an illustration, for Haloscan trackback code:

<a href="javascript:HaloScanTB('<$BlogItemNumber$>');" target="_self"><script type="text/javascript">postCountTB('<$BlogItemNumber$>'); </script></a>

now becomes

<a expr:href='"javascript:HaloScanTB(" + "\"" + + "\"" + ");"' target='_self'><script type="text/javascript">postCountTB('<>'); </script></a>

If you want to work through that further example to try it out, using the steps explained above, you should end up with the same thing too - with a couple of twists I'll now explain.

You will note that there's a <> with angle brackets around it (in the context of postCountTB('<>');). That's because it's inside a Javascript script as required by the Haloscan code, but that script is not actually inside an HTML tag within the value of an attribute (i.e. between the <> angle brackets of the a tag), so that's fine - and in fact, in a new Blogger template, if you use a data tag outside of an HTML tag, generally you will have to use the angle brackets or it won't work.

Here's a further twist. I included that example to point out something else you may need to do. It's bad enough fiddling with single and double quotes, but what if the code you are converting, which was originally inside the double quotes (i.e. inside the "stuff" bit of href="stuff"), itself contains quotes? Like the single quote ' in the Haloscan example above, which is bold green in the old Blogger version. Well, remember you have to first change that to double quotes ". Then, you have to do what programmers call "escape" it. Which in simple terms means that you separate that double quote " from the other stuff using spaces (like when we were splitting out the old template tags), then you change it to "\"" - note the backslash and extra double quotes around it - and again you have to insert + symbols as necessary to separate those quotes from the other blocks inside the overall single quotes. I'm running out of colours so the whole of that lot is bold green again in the final version.

Finally, note also that when you separate out the blocks that aren't template tags and surround them in double quotes, that really does mean you should separate out literally everything, even little snippets. Like the close bracket and semicolon in ");" above (and, of course, the green single quotes that got converted to double quotes and then escaped).

I'm not providing converted versions of code for displaying links to your posts e.g. on BlogPulse - I'll leave it to you to try that, and other code you might want to try to convert.

Recap or cheatsheet for new Blogger data tags from old Blogger template tags

In summary (particularly for aspiring coders):
  • In HTML tag attribute values, you use data tags without angle brackets. Elsewhere, use them with angle brackets and the closing /
  • New Blogger uses single quotes for attribute values, and double quotes within, so best change your code as necessary
  • If you include data tags in HTML tag attribute values, you must insert an "expr:" - i.e. change e.g. href="stuff" to expr:href='stuff'
  • This is the case for data tags used in any attribute values, not just href. I've seen expr:title, expr:id, expr:onClick and so on.
  • Change the old template tags to data tags
  • Within the attribute value, if there are extra single or double quotes as part of the original code, e.g. Javascript, you need to escape them.

Where can you put the new social bookmarking etc code?

You could put it in the top of each post, the bottom of each post, or your sidebar.

Bottom - post footer

The easiest is bottom. Find the line in your template that reads

<p class='post-footer-line post-footer-line-3'></p>


<p class='post-footer-line post-footer-line-3'/>

and change it to

<p class='post-footer-line post-footer-line-3'>YOUR NEW CODE HERE</p>

Obviously you can tweak the surrounding text etc as you wish and style it - different font size, etc.


You should be able to put it at the top of the post too - find the bit that reads:

<div class='post-header-line-1'/>

and change it to:

<div class='post-header-line-1'><p class='post-header-line-1'>YOUR NEW CODE HERE</p></div>


For the sidebar it might be easiest to use a HTML page element widget (how to add page elements widgets) then drag it around. For the title enter anything you want to describe the link, and paste the code into the Content box of the widget.

But beware - remember a lot of the code relates to the post body of individual posts, so it may not work in a sidebar and you may have to change the data tag to something more appropriate for that location.

Similarly you could put the code in the page footer section or the top of the page as well or instead of each individual post, and use variations on the code for that - but I won't deal with that here.


Erico Oliveira said...

Very good explanation! Thanks.

Improbulus said...

And thanks for your comment Erico, hope it helped!

Dario said...

Thanks, your explanation on how to write the statements will come handy to me eventually.

At the moment, I am trying to find out how to twick the template code for blogger so I can control individual posts. What happens is that I want to have fixed content inbetween posts. I've managed to do that. But I want the fixed content only for posts 4 thru 8 and not the initial 3 posts.

I saw that every post has an id but I dont see anything regarding the order (1st - or top or most recent post of the blog, 2 - second oldest, third...).


jdtangney said...

Wow! All these years later and I am only now about to sit down and convert my template.

Yours is the ONLY sensible documentation I could find. Thank you, thank you!


Jon said...

Cheers! This was really helpful for creating a working "print post" icon on my blog. Anyone that wants the code - help yourself -

Sean Daniel said...

awesome post, finally solved the mystery.