The world according to GRP — Friday, February 23, 2007:
A comprehensive workaround for the Blogger "previous posts" bug
UPDATE (JUNE 19, 2007):
The bug has been fixed. The template described in this post is no longer used for this blog.
This blog [no longer] has the following unusual features:
- All posts are listed by title in the sidebar of the main page (with permalinks to the respective item pages). The method by which I have listed all posts can also be used to list the last n posts, where n is an arbitrary number.
- But only the ten latest posts are shown in the content column of the main page (and this number is fixed, i.e. independent of "n"). The same ten posts are listed by title (with permalinks) in the sidebars of the archive pages and item pages.
- The sidebar of each archive page also shows the titles of posts on that archive (with intra-page links to the respective posts, as in a table of contents).
- The "Archives" list is very compact and appears in the sidebar of every page.
The result is a highly navigable blog that doesn't use too much bandwidth on the main page. In this post I explain how I did it. But first I explain why I bothered.
The problem
In the Old Blogger, the "Previous posts" list was generated by the <BloggerPreviousItems> tag pair (in the template). This tag pair selected the last ten posts before the current post when used on an item page, and the ten most recent posts when used on a main or archive page.
But in the New Blogger, the <BloggerPreviousItems> tag pair always selects the ten latest posts — even on an item page. Of course you can acknowledge this by changing the "Previous posts" heading to "Latest posts" or "Recent posts". But that doesn't solve the main problem, namely that posts older than the last ten are linked only from archive pages, and are no longer linked through their titles.
To get some links with post titles for anchor text, you could turn all the post titles on the archive pages into links to the corresponding item pages, e.g. like this:
<a name="<$BlogItemNumber$>"></a> <BlogDateHeader> <h5 style="color: #800000; margin-bottom: 0;" ><i><$BlogDateHeaderDate$>:</i></h5> </BlogDateHeader> <h2><a href="<$BlogItemPermalinkURL$>" ><BlogItemTitle><$BlogItemTitle$></BlogItemTitle></a></h2>
(where the <$BlogItemPermalinkURL$> tag generates the URLs, and the placement of the <$BlogItemNumber$> label generator is to be explained in due course). This would help search engines to find your posts, but would not of itself help human readers to find them. Showing all your posts on the main page, and likewise turning all their titles into permalinks, would offer additional bait to search engines, but would still not greatly help human readers (who don't like scanning long pages).
Upgrading your "Classic" template to a "Layouts" template does not fix the bug, and (at least in the examples that I've seen) does not of itself help human readers to find your old posts. Moreover, it loses your customizations. So I haven't yet made the switch — but I welcome feedback (see below) on the extent to which the ideas presented here are applicable to "Layouts".
The solution
The workaround has two main components. The first, which is documented in the Blogger Help pages under "Blogger Hacks", is to use the <Blogger> tag pair in the sidebar. The second, which to my knowledge has not been documented before, is to use the <BloggerPreviousItems> tag pair in the content column of the main page — that is, to generate the posts on the main page using <BloggerPreviousItems> instead of <Blogger>.
(a) Sidebar
The <Blogger>... </Blogger> tag pair is normally used in the content column to display the posts, including the dates and titles and any comments or backlinks. This operation requires many other instructions between the tags. But (as explained in "How do I list the titles of all posts on a page?") the same tag pair can be used more than once on a page. So if you put this tag pair in the sidebar with no intermediate tags except those that generate permalinked titles, you get the permalinked titles of all posts on the current page. If the current page is the main page and you have chosen to display all posts on the main page (by logging in to Blogger and choosing "Show ... days" under the "Settings" and "Formatting" tabs), you get the permalinked titles of all posts on the blog (presumably with the usual limit of 999 posts).
Similarly, if the current page is an archive, you get the permalinked titles of the posts on that archive. But, as in this case the posts are already on the page, I have chosen to link not to the item pages, but to the date headers of the posts on the archive page. That explains the placement of the <$BlogItemNumber$> label generator in the code quoted above; in particular, notice that the label generator is outside the <BlogDateHeader> tag pair, so that the label appears even if the date header does not (i.e. even if the post is not the first for that date).
So, in my blog, the code for generating the lists of "All posts" and "Posts on this archive" is
<MainPage>
<h4>All posts</h4>
<ul><Blogger>
<li><a name="<$BlogItemNumber$>"
href="<$BlogItemPermalinkURL$>"
><BlogItemTitle><$BlogItemTitle$></BlogItemTitle></a></li>
</Blogger></ul>
</MainPage>
...
<ArchivePage>
<h4>Posts on this archive</h4>
<ul><Blogger>
<li><a href="#<$BlogItemNumber$>"
><BlogItemTitle><$BlogItemTitle$></BlogItemTitle></a></li>
</Blogger></ul>
...
</ArchivePage>
where the reference to "<$BlogItemNumber$>" on the archive page has just been explained. (But what about the corresponding label on the main page? Read on!)
One result of these decisions is that the sidebar of an archive page does not necessarily contain permalinks to the corresponding item pages. To compensate, I have indeed turned the post headers on archive pages into permalinks (as suggested above).
I have also chosen to list the titles of the ten latest posts (with permalinks) on the item and archive pages. The code for the item page, which happens to correspond to the first ellipsis (...) in the above listing, is
<ItemPage>
<h4>Latest posts</h4>
<ul>
<BloggerPreviousItems>
<li><a href="<$BlogItemPermalinkURL$>"
><$BlogPreviousItemTitle$></a></li>
</BloggerPreviousItems>
</ul>
</ItemPage>
and the code for the archive page, which corresponds to the second ellipsis, is the same except that the <ItemPage> tag pair is omitted, its place being taken by the <ArchivePage> tag pair. So the "Latest posts" code is standard except for the header.
The "Archives" list is generated by the code
<h4>Archives</h4>
<p style="margin-bottom: 1.2em;">
<BloggerArchives>
<a href="<$BlogArchiveURL$>"
><$BlogArchiveName$></a>
</BloggerArchives>
</p>
so that the list is a single wrappable paragraph with an extra space ( ) between the "words". Monthly archives are chosen (by the "Settings" and "Archiving" tabs) with index dates in the form YYYY/MM (under the "Settings" and "Formatting" tabs). The result is an archive list compact enough to be shown on every page.
If you want to display the titles of the last n posts (instead of all posts) in the sidebar of the main page, you choose "Show n posts" under the "Settings" and "Formatting" tabs, and change the "All posts" header to match.
(b) Content column
Listing the titles of all posts in the sidebar of the main page requires the "Show" option (under the "Settings" and "Formatting" tabs) to be specified in days rather than posts. This would normally cause all posts to be displayed in the content column of the main page. Similarly, listing a large number of post titles in the sidebar of the main page would normally cause the same large number of complete posts to be displayed in the content column of the main page. In either case, the resulting bandwidth demand from that page could annoy both your readers and your blog host.
The solution is the reverse of that used in the sidebar: just as <Blogger> can do what <BloggerPreviousItems> was meant to do — that is, generate a list of post titles with permalinks — so <BloggerPreviousItems> can do what <Blogger> was meant to do — that is, generate complete posts. More precisely, <BloggerPreviousItems> can generate the latest ten complete posts. In the content column of the main page, that's reasonable. But there are two complications to deal with.
First, the content column would normally be produced by numerous tags, some contained within conditional tag pairs, all bracketed by a single <Blogger> tag pair (except for any material that is inside the main column but outside the sequence of posts; this may include ads). So the <BloggerPreviousItems> tag pair substituted for the <Blogger> tag pair must be similarly all-embracing. This substitution is wanted only for the main page, and there is no "archive or item page" conditional tag. So the content columns for the main page, archive pages, and item pages must be specified separately in the form
<MainPage> ... <BloggerPreviousItems> ... </BloggerPreviousItems> ... </MainPage> <ArchivePage> ... <Blogger> ... </Blogger> ... </ArchivePage> <ItemPage> ... <Blogger> ... </Blogger> ... </ItemPage>
and there is no need for further conditional tags inside the outer conditional tag pairs. To fill in the contents of each <BloggerPreviousItems> or <Blogger> tag pair, you could start with a copy of the contents of your existing <Blogger> tag pair and delete the redundant parts. If you have internal conditional tags pairs that don't match the outer conditions, they and their contents are redundant and may be deleted. If you have internal conditional tag pairs that do match the outer conditions, the tags themselves are redundant but the enclosed contents are still needed.
Furthermore, my limited experience indicates that redundant internal conditional tags, even if they match the outer tags, can prevent the substitution of strings for variables, so that you get (e.g.) posts with titles like "<$BlogItemTitle$>" (which is probably not what you meant to write about). So "redundant" internal tags are not merely redundant, but harmful: there must be no nesting of conditional tags.
Second "complication": Inside the <Blogger> tag pair, the code that generates the date header for each post is normally something like
<BlogDateHeader> <h5 style="color: #800000; margin-bottom: 0;" ><i><$BlogDateHeaderDate$>:</i></h5> </BlogDateHeader>
(where the style details and <h5> header level are applicable to my blog but not necessarily to yours). But inside the <BloggerPreviousItems> tag pair, for reasons unknown to me, the above code is ineffectual (and if you omit the enclosing <BlogDateHeader> tag pair, the string substitution fails). So the corresponding code for generating the date headers on the main page (inside the <BloggerPreviousItems> tag pair) is
<h5 style="color: #800000; margin-bottom: 0;" ><i><$BlogItemDateTime$>:</i></h5>
where <$BlogItemDateTime$> is the tag that normally generates the timestamp at the end of the post (as in "Posted by ... @ ..."). So you'll need to choose a timestamp format (under the "Settings" and "Formatting" tabs) that is suitable for imitating the date header. You might then consider removing the duplicate footer timestamp from posts on the main page. (I have chosen the "Timestamp Format" to match the "Date Header Format", and removed the footer timestamps from all pages. Consequently the world can see the date, but not the time, of each post, and doesn't notice what scandalous hours I keep.)
A minor side-effect of the <$BlogItemDateTime$> hack is that multiple items posted on the same day get separate date headers on the main page (but still get a common date header on the archive page).
(c) Loose ends
It remains to explain the name="<$BlogItemNumber$>" label in the code for generating the "All posts" list (above). To prevent duplication on any single page, this label must appear only once within all occurrences of each conditional tag pair (<MainPage>... </MainPage>, <ArchivePage>... </ArchivePage>, or <ItemPage>... </ItemPage>). On the main page, I chose to place it in the sidebar because (i) that is the only place on the page where the full list of posts (generated by the <Blogger> tag pair) is found, and (ii) for all I know, there might be some Blogger function that requires the presence of the full set of post labels.
By the way, the conspicuous placement of the Google AdSense ads — right under the titles of the posts — obviously requires the AdSense code to be included in the Blogger code for each post. So how did I impose a limit of three ads per page in order to comply with the AdSense program policies? I didn't; the Google ad server enforces the limit automatically. I hope I'm allowed to rely on this mechanism!
What if Google fixes the bug?
On the main page, <BloggerPreviousItems> selects the ten latest posts and will continue to do so even if the bug is fixed. The same applies to archive pages. Only on item pages did the bug change the selection. So, if you are listing "Latest posts" or "Recent posts" on your item pages, and if the bug is fixed, you'll need to revert the relevant heading to "Previous posts". That's all. But of course you'll need to do that even if you don't use <BloggerPreviousItems> in the content column of the main page.
The behavior of the <Blogger> tag pair in the sidebar is also unaffected by the bug.
In short, the main ideas presented here do not rely on the bug; they are workarounds, not exploits. A fix — with the associated minor change to item pages — would be an improvement.
Any comments?
Comments are not enabled on this blog, but backlinks are enabled. (At the moment I'm dealing with spam links manually, so backlinks don't use the "nofollow" attribute; but I can't promise that this will always be the case.)
Moreover, I am willing to provide links (in the "updates" section below) to web pages or blog items or archived email messages that usefully add to the above discussion. If you write such a contribution, please keep it short and avoid needless repetition of what previous contributors (including me) have said. Then email me and I'll consider linking to it. If the result ends up looking like a blog carnival, so be it.
Updates
Feb.24: Avoiding truncation of titles
I noticed that the (unusually long) title of this post was truncated in each "Latest Posts" list, where it was generated by the <$BlogPreviousItemTitle$> tag, but not truncated in the content column of the main page, where it was generated by the <$BlogItemTitle$> tag. Inclined to regard the truncation "feature" as a bug, I changed the former tag to the latter in each "Latest Posts" list. The code for that list is now
<h4>Latest posts</h4>
<ul>
<BloggerPreviousItems>
<li><a href="<$BlogItemPermalinkURL$>"
><$BlogItemTitle$></a></li>
</BloggerPreviousItems>
</ul>
and this code appears twice: once for archive pages and once for item pages. So the "Latest posts" code is no longer "standard except for the header".
Feb.25: Making the "Posts on this archive" list point to posts within the page
The links on the "Posts on this archive" list, which previously pointed to the respective item pages, now point to the respective posts on the archive page (i.e. the same page). The code for generating the list was changed from
<ul><Blogger>
<li><a href="<$BlogItemPermalinkURL$>"
><BlogItemTitle><$BlogItemTitle$></BlogItemTitle></a></li>
</Blogger></ul>
to
<ul><Blogger>
<li><a href="#<$BlogItemNumber$>"
><BlogItemTitle><$BlogItemTitle$></BlogItemTitle></a></li>
</Blogger></ul>
and the main text of this post has been amended to reflect the change.
Feb.26: Redundant tag pair?
The reader may have noticed that, in the above discussion, the <$BlogItemTitle$> tag is sometimes enclosed by a <BlogItemTitle>... </BlogItemTitle> tag pair, and sometimes not. This is a legacy of the path by which my template has evolved. My limited experiments suggest that in the New Blogger, the enclosing <BlogItemTitle> and </BlogItemTitle> tags are redundant, i.e. defined as no-ops. But I wouldn't bet the house on it. Further information is welcome!
Feb.27: Limiting the number of post titles in the sidebar
Following an exchange with Chris Wright on Blogger User Support, I have made it clear (in the main text) that the method by which I have listed "All posts" can also be used to list the last n posts, where n is an arbitrary number.
Mar.5: Bug fixed!
The bug has been fixed. Although the article allowed for this possibility, some statements in it are now out of date, and more will become so as this blog evolves.
Mar.16: And yet it moves...
Even after the bug fix, this article was kindly featured in the carnival at Blog It and Earn It.
June: Template modified
Most of the above references to this blog are now out of date, following extensive modifications to the template.
Copyright © Gavin R. Putland except as otherwise attributed. Posted at The world according to GRP under the title A comprehensive workaround for the Blogger "previous posts" bug. You may republish this item verbatim on your website or blog provided that you include this notice (with hyperlinks).
Comment |
Email this post: ![]()
![]()
