Monkey Raptor

Monday, June 17, 2013

Blogger Conditional Tag — b:if and b:else

Blogger has special <b:if> and <b:else/> tags.
The <b:if> and <b:else/> only work if you put them in the XHTML of the Blogger blog, not in the HTML/JS widget (via layout).

List of <b:if> conditions #
Techniques list #

Show content only on item page (every single post):
<b:if cond='data:blog.pageType == "item"'>...content...</b:if>

Show content only on static page(s):
<b:if cond='data:blog.pageType == "static_page"'>...content...</b:if>

Show content only on index page (sorted by label and date):
<b:if cond='data:blog.pageType == "index"'>...content...</b:if>
For instance, try this URL pattern:
[your_blog_url]/search/label/[YOUR_LABEL]
It will show your post(s) list with a particular [YOUR_LABEL] label.
  • change the [your_blog_url] with your own blog URL, such as: mysupersweetblog.blogspot.com or your custom domain blog URL.
  • change the [YOUR_LABEL] with your own label.

Show content only on archive page (your blogroll — sorted by date):
<b:if cond='data:blog.pageType == "archive"'>...content...</b:if>
For instance, try this URL pattern:
[your_blog_url]/2014/11
It will show your post(s) list you wrote in November ( 11 ) of 2014.
Also, change the [your_blog_url] with your actual blog URL.

Show content only on homepage URL of the blog:
<b:if cond='data:blog.url == data:blog.homepageUrl'>...content...</b:if>

Show content only on a specific URL on the blog:
<b:if cond='data:blog.url == "specific-URL-on-the-blog"'>...content...</b:if>
We need to put complete URL and protocol for that, such as:
http://mysupersweetblog.blogspot.com/2002/01/hello_hoho.html

Do not use relative URL, like just /2002/01/hello_hoho.html.
Show content on the error page of the blog (404 - not found page):
<b:if cond='data:blog.pageType == "error_page"'>...404 note content...</b:if>
There's the predefined elements and styling provided by Blogger for that.
They're the elements starting with class name status-msg-.
You can search them on your XHTML.

But, if you wanna modify the custom error page, use that conditional statement to make the additional element(s)/CSS/JS appear/run only for that criteria.
Show content only on post(s) which is/are showing backlink:
<b:if cond='data:post.showBacklinks'>...content...</b:if>

Show content only on post(s) which is/are showing specific display name (such as the post's author):
<b:if cond='data:displayname == "specific-name"'>...content...</b:if>

Show content only on post(s) which has/have specific number of comment(s):
<b:if cond='data:post.numComments == [number_here]'>...content...</b:if>

Show content only on post(s) which has/have jump link (the "read more" link):
<b:if cond='data:post.hasJumpLink'>...content...</b:if>

Show content only on post(s) which is/are comment enabled:
<b:if cond='data:post.allowComments'>...content...</b:if>

There are plenty other of conditions. But they're "deeper", sort of speak.
These are some of them:
  • <b:if cond='data:blog.metaDescription'>
  • <b:if cond='data:mobile'>
  • <b:if cond='data:title'> or <b:if cond='data:title != ""'>
  • <b:if cond='data:showThumbnails == "false/true"'>
  • <b:if cond='data:showSnippets == "false/true"'>
  • <b:if cond='data:post.thumbnail'>
  • <b:if cond='data:display == "list"'>
  • <b:if cond='data:blog.url == data:label.url'>
  • <b:if cond='data:showFreqNumbers'>
  • <b:if cond='data:useImage'>
Plus others...
Escaping quotation mark #
Remember to escape the " (double quote mark) with &quot;
Because it's required by the Blogger's XHTML parser.

Example for the item condition

From this
<b:if cond='data:blog.pageType == "item"'>...content...</b:if>
Into this
<b:if cond='data:blog.pageType == &quot;item&quot;'>...content...</b:if>
The examples in here didn't escape the quotation marks within the b:if to make them easy to read.

Actually, the quotation marks (double or single) will automatically be replaced by Blogger, but, you know, just in case.

We can also use CDATA section for escaping characters but not for b:if. It's for the characters within CSS and/or JavaScript. Read some more on this post


Comparing operators #

There are conditions that using double equals (comparing method), and just direct statement. You can see on the list above.

The double equals == means TRUE for non-numeric statement, and equal to for an integer (numeric).

Numeral #

The == operator can be replaced by:
  • != other than that integer.
  • < less than.
  • > greater than.
  • <= less than or equal to.
  • >= greater than or equal to.
The [number_here] (as you can see on number of comments) must be replaced by a non-negative integer (0, 1, 2,... , 200, etc).
Escaping
We need to escape the less than (<) and the greater than (>) marks.
  • less than (<) is &lt;
  • greater than (>) is &gt;

Example for escaping greater than operator

From this
<b:if cond='data:post.numComments > 1'>...content...</b:if>
Into this
<b:if cond='data:post.numComments &gt; 1'>...content...</b:if>

Non-numeral #

We only have two options for the operator:
  • == TRUE
  • != FALSE

Example of using negation (!=) for homepage statement:
<b:if cond='data:blog.url != data:blog.homepageUrl'>
    ...content...
</b:if>
It means do not show a specific content on homepage URL, but show the specific content on page which isn't homepage URL.

How about <b:else />? #
It's placed within the <b:if>
Let's take a look at the conditional tag using double equals.
For example:
<b:if cond='data:blog.url == data:blog.homepageUrl'>
    [...content1...]
    <b:else />
    [...content2...]
</b:if>
It means show content 1 on page which is homepage URL. If the page isn't homepage URL, then content 2 will be shown.
Different <b:if> conditions can be stacked #
Example:
<b:if cond='data:blog.pageType == "item"'>
    <b:if cond='data:blog.url != "specific-URL-on-the-blog"'>
        [...content1...]
        <b:else />
        [...content2 -- inner b:if...]
    </b:if>
    <b:else />
    [...content2 -- outer b:if...]
</b:if>
It means that content 1 will be shown on item page, but not on specific item page (URL). And when the page is an item page and it has the specific URL stated, it will then show the content 2.
That stacking example is very much redundant. We can just use the [specific URL] condition for that.

Nevertheless...
Neat, isn't it?
Using b:if for a widget #
To actually use the <b:if> and <b:else> to control the widget appearance, we need to:
  1. Open the Blogger HTML Template.
    • Go to TemplateEdit HTML
    • Or shortcut, using URL pattern (if you're logged in):
      https://www.blogger.com/blogger.g?blogID=[your_BLOG_ID]#templatehtml
      the [your_BLOG_ID] is your Blogger blog ID number.
  2. Then go (jump) to a specific widget.
For instance, if we wanna tinker the appearance of widget with the ID HTML1, we'll need to open our Blogger HTML Template (using either way above), then jump (there's the widget button on top of the HTML template) to HTML1, expand it, and you'll be seeing these lines:
<b:widget id='HTML1' locked='false' title='' type='HTML'>
    <b:includable id='main'>
      <!-- only display title if it's non-empty -->
      <b:if cond='data:title != &quot;&quot;'>
          <h2 class='title'><data:title/></h2>
      </b:if>
      <div class='widget-content'>
          <data:content/>
      </div>
      <b:include name='quickedit'/>
    </b:includable>
</b:widget>
To control the whole HTML1 widget appearance, you can put the <b:if> right after the <b:includable>, and close the tag, using </b:if>, put it right before the closing </b:includable>.

Example:
<b:widget id='HTML1' locked='false' title='' type='HTML'>
    <b:includable id='main'>
        <b:if cond='data:blog.pageType == "item"'>
            <!-- only display title if it's non-empty -->
            <b:if cond='data:title != &quot;&quot;'>
                <h2 class='title'><data:title/></h2>
            </b:if>
            <div class='widget-content'>
                <data:content/>
            </div>
            <b:include name='quickedit'/>
        </b:if>
    </b:includable>
</b:widget>
That example means, the widget HTML1 will only be shown on item page. That is the post/article page itself, and not on any other, like homepage or blogroll or static page or other.
Tinkering the content of a widget #
You can put the custom content of the widget HTML1 via Blogger layout - or just change the <data:content/> with your custom content - not highly recommended though. Do this if you're confident about tinkering Blogger template.
Example:
<b:widget id='HTML1' locked='false' title='' type='HTML'>
    <b:includable id='main'>
        <b:if cond='data:blog.pageType == "item"'>
            <!-- only display title if it's non-empty -->
            <b:if cond='data:title != &quot;&quot;'>
                <h2 class='title'><data:title/></h2>
            </b:if>
            <div class='widget-content'>
                Your thingy here - script or whatever.
            </div>
            <b:include name='quickedit'/>
        </b:if>
    </b:includable>
</b:widget>

Example with <b:else />
It can be placed like so:
<b:widget id='HTML1' locked='false' title='' type='HTML'>
    <b:includable id='main'>
        <b:if cond='data:blog.pageType == "item"'>
            <!-- only display title if it's non-empty -->
            <b:if cond='data:title != &quot;&quot;'>
                <h2 class='title'><data:title/></h2>
            </b:if>
            <div class='widget-content'>
                <data:content/> or Your thingy 1
            </div>
            <!--[#1] place it here-->
            <b:else /> 
            Your thingy 2
            <b:include name='quickedit'/>    
            <!--[#2] or here-->
            <b:else />
            Your thingy 2
        </b:if>
    </b:includable>
</b:widget>

Global CSS and/or script #
The conditional <b:if> can be used as conditional styling (CSS) or script not only for a particular widget - it can also be used for the entire blog layout.
You can place it (the CSS/script) in the body or head section of your Blogger HTML.
Rule of thumb for placement:
  1. CSS is always placed on top of the elements being styled. Placing on top of body or on the bottom of head is the common practice.
  2. The script usually is placed at the bottom of the body. But then again, it depends on how you constructed your JavaScript.

Example for styling (CSS) - it's the same thing with the scripting (JavaScript/jQuery):
<b:if cond='data:blog.pageType == "item"'>
     <style>
          /*your styling here*/
     </style>
</b:if>

Mobile template #
This method, by default, only works for desktop template. If you need to make it work for desktop and mobile:
  • Go to your Blogger TEMPLATE setting.
  • On the Mobile setting, you can either choose:
    1. Yes. Show mobile template on mobile devices.
    2. No. Show desktop template on mobile devices.
  • If you choose the first one, then pick the Custom option. Afterward, you need to work on the desktop view and mobile view. It's still using your (desktop) global template, but with slightly different Blogger data tags layout, sort of.
  • If you choose the second option, then you'll only need to work on one template, the desktop. This template will be shown on desktop or mobile.
This blog uses the first one. But with the provided theme, not using the custom theme.
I only tinkered the desktop template and put some conditional JavaScript on certain posts/static pages on mobile view. Each condition is embedded on each page, it's scoped.
Not for the entire Blogger XHTML because it will be stripped.

Read some more about Blogger's mobile template on this post


External References #

Resources for more information about special Blogger tags:

The Blogger special operators:

Additional:

Blogger Conditional Tag — b:if and b:else
http://monkeyraptor.johanpaul.net/2013/06/blogger-conditional-tag-bif-and-belse.html

20 comments

  1. Great explanation!

    I would like to use data:post.allowComments or data:post.showBacklinks because i'm making a menu that indicates which page we are reading. But i've got a error:
    "TEMPLATE ERROR: Invalid data reference post.allowComments: No dictionary named: 'post' in: ['blog', 'skin', 'view']".
    What i've to do to resolve this?

    ReplyDelete
    Replies
    1. Hi there Raquel, thanks for stopping by.
      Actually, to display the link (and the title) of the page you're reading, don't use those data tags.
      To display the TITLE of the post use : <data:post.title/>
      To display the URL of the post use : <data:post.url/>
      You need to put those in the body section of the blog (not in the widget).

      For instance, to create stuff like my sharer above, do this :

      <div style='text-align:center'>
        <p>Title : <data:post.title/></p>
        <p>URL : <data:post.url/></p>
      </div>

      I hope it will help. :)

      Delete
  2. Hello, I've been learning to use bif in my html..
    My question is, How can I make the social network share button count appear in the homepage and varies the count according to each post and not based on the homepage count..

    ReplyDelete
    Replies
    1. Hi there Nourel!
      For that, you need to separate the elements.
      If you use the share buttons I posted on this blog, then you need to add another different buttons for your homepage (home blogroll).
      The buttons example I shared here are the ones which show the different count for each post.

      Adding the homepage buttons :
      You don't need to go to HTML editor to add those.
      Just create a widget via layout ➝ then paste the elements and scripts from the original social networks in that element (without any b:if) ➝ save, and that's it.

      Anyway, you need to manually replace the URL of each button with the blog's homepage URL (not capturing the current page URL).
      You can find out how to do that on the original social network documentation and button generator page:
      1. Twitter : dev.twitter.com/docs/tweet-button
      2. Facebook : developers.facebook.com/docs/plugins/like-button
      3. Google+ : developers.google.com/+/web/+1button/

      If you want to make the homepage buttons only appear on homepage, then go to HTML editor ➝ jump to the widget you created for the buttons ➝ finally implement the b:if above.

      Hopefully that helps.

      Delete
  3. I wold like to use label name check ..how to write

    ReplyDelete
    Replies
    1. There's a Q&A about that on Stack Overflow. Here's the link: stackoverflow.com/questions/28060776/how-to-hide-blogger-posts-with-specific-label

      Delete
  4. Very useful! Thanks for sharing!

    ReplyDelete
  5. Thanks for sharing the useful information! How if I need to combination labels with at least including one key label, such as:
    Label: ABC+EFG, ABC+XYZ
    That means any combination if label ABC is existed, will show up.

    I understand for single label, it is
    For combine 2 labels is

    So if I want ABC+EFG and/or ABC+XYG will show up, I don't use this because I have more than a dozen of combinations. So I think this way might work: with an asteric* but it's not working?

    Do you have any idea?
    Thanks!

    ReplyDelete
    Replies
    1. Hi,
      I never tinkered that kinda technique. So I have no clue. Sorry.

      Delete
  6. Great!

    I've added a label widget just below the main blog widget as opposed to the right or left menu.

    Is it possible to use this code to modify the label widget to have each post only display its own labels rather than displaying all the blog's labels. For example, if post 1 has labels a,b,c and post 2 has labels d,e,f then currently both posts with shows labels a,b,c,d,e,f. I'd to change this so that label widget only shows label a,b,c on post 1 and label d,e,f on post 2.

    ReplyDelete
    Replies
    1. I don't know if you will read this, Anonymous.

      The label widget has its own setting from the Blogger to display all the labels.
      If you wanna show some labels related to the post, then just show the bottom post labels list.
      Go to Settings ► Layout ► scroll down and find the "Blog Posts" ► click edit. You'll see there are blog post settings you can set.

      The other method is by requesting manually via Blogger API V2/V3 using JavaScript (XHR) to Blogger server for the current post. But of course, that will be super long to talk about right now. :)

      Delete
  7. Lots of good info, nice article!

    How would you suggest going about making a gadget appear exclusively on two specific URLs? In this case, a contact form that would appear on a services pages and the standalone contact page. I can't think of how to make it work. Two if cond URLs collide with eachother so that doesn't work. and I cant find anything that would work in the syntax like an 'or' statement, so it could read if 'this url' or 'this url'. Any ideas?

    ReplyDelete
    Replies
    1. The suggestion idea is on your second comment. :D

      Delete
  8. Bump. Forgot to check notify box to see ur reply haha..

    ReplyDelete
    Replies
    1. Hey Josh, thanks for visiting!

      Blogger has new syntaxes for "or" operator and "else if" and bunch others. So we now can have more than two conditions to compare. Here's the link: https://support.google.com/blogger/answer/46995?hl=en

      I'd suggest like so:
      <b:if cond='data:blog.url == "specific-URL-1"'>
          this is your gadget code / or JavaScript to control the gadget appearance
      <b:elseif cond='data:blog.url == "specific-URL-2"'/>
          this is your gadget code / or JavaScript to control the gadget appearance
      <b:elseif cond='data:blog.url == "specific-URL-3"'/>
          this is your gadget code / or JavaScript to control the gadget appearance
      <b:else/>
          something else...
      </b:if>

      You could use only b:if and one b:elseif and close it with b:else.

      Hope that helps. Cheers!

      Delete
    2. Yes sir! Works like a charm

      Delete

Tell me what you think...