Tuesday, April 14, 2015

Add content to Blogger posts specific to a label

Mum uses her Blogger to post about dogs she has rescued and uses labels to mark which rescued Chihuahuas that are available to good homes, or have been happily re-homed etc. I created an expression of interest form for people to apply for the dogs that are available, and I wanted a link to the form to appear below the blog entries labelled with "Available now" only. Here is how to do it.

You need to edit your Blogger XML template by going to the dashboard, selecting your blog, going to the Template section and clicking on the "Edit HTML" button. Take a backup of this content before you change it so that you can always go back! I haven't found a single comprehensive reference on the XML grammar and really only worked this out by experimentation and reading examples.

In the template, search for <data:post.body/>. If you use the template for your mobile version as well, you will see two instances of that tag. I put my content under both instances because I wanted the same thing to appear on the desktop and mobile versions.

<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' itemprop='articleBody'>
   <!-- If the post has labels. -->
   <b:if cond='data:post.labels'>
      <!-- Go through all the labels attached to the post. -->
      <b:loop values='data:post.labels' var='label'>
         <!-- If current label is our target one. -->
         <b:if cond='data:label.name == "Available now"'>
            <!-- Display content I want to appear after the post. -->
            <div style="text-align: center;">
               <p><em>If you would like to adopt this dog, or any of our Chihuahua Rescue Victoria dogs, please fill out the <a href="http://www.chihuahuarescuevictoria.org/forms/adoption/Express-interest-in-adopting-from-Chihuahua-Rescue-Victoria.php">expression of interest form</a>.</em></p>
   <div style='clear: both;'/> <!-- clear for photos floats -->

Elements to note here.

  • <data:post.body/>
    • Indicates the body of each blog post.
  • <b:if cond='data:post.labels'>
    • Tests if the blog post has labels attached to it.
  • <b:loop values='data:post.labels' var='label'>
    • Loop through every label attached to this single post. The loop will place the current label in a variable named "label".
  • <b:if cond='data:label.name == "Available now"'>
    • Test if the current label's name is the label I am targeting.
    • I place my label-specific content within this tag.

So essentially what I am doing is looping through post.labels with each label in a variable called label, and for each one I examine label.name.

Look carefully at Google's description of what is in each post element to see what else you can access for each post:

  • posts: A list of all posts for this page. Each post contains the following:
    • dateHeader: The date of this post, only present if this is the first post in the list that was posted on this day.
    • id: The numeric post ID.
    • title: The post's title.
    • body: The content of the post.
    • author: The display name of the post author.
    • url: The permalink of this post.
    • timestamp: The post's timestamp. Unlike dateHeader, this exists for every post.
    • labels: The list of the post's labels. Each label contains the following:
      • name: The label text.
      • url: The URL of the page that lists all posts in this blog with this label.
      • isLast: True or false. Whether this label is the last one in the list (useful for placing commas).

References I found useful.