Blogger Hacks, Categories, Tips & Tricks

Wednesday, April 26, 2006
Blog Navigator: Previous and Next Post Links
The other navigation drawback of Blogger (apart from the lack of categories) is the absence of next/prev post buttons. Freshblog has seen an ingenious earlier solution via ecmanaut, though it apparently requires daily archiving plus a complete re-publish each time. I've gone for the Pareto 80/20 rule: 80% as good, for 20% of the effort.

This hack requires the publisher to link to a small (3K) JavaScript file and put a whole lot of code into their template. If you've got a standard blog, it takes about 5 minutes. Once done, you get next/prev links (or buttons) next to each item (posts and comments) on your main, archive and post pages. This means readers can simply jump up and down the page from post to post, and between pages when they "fall off" the top or bottom of the page. For a demo, check out Vent or Speccy.

Prequisites: This blog hack makes certain assumptions about your blog. I think these will be met by the majority of blogs, but still, you should check. Firstly, it assumes that you have anchors defined for each post item (where the NAME is the <$BlogItemNumber$>). It also assumes that each comment has an anchor too (where the NAME is c<$BlogCommentNumber$> ie using a leading c). Further, it requires knowledge of your archive (set of URLs pointing to your archive pages). At the moment, it works with the FreshTags archive, drop-down menu archives and normal list archives. If your blog is like 99% of blogs and in reverse chronological order ("latest post first"), then your archive should be in chronological order ("earliest first"). This is usually the case, unless you've applied the reverse archive hack. (In which case, reverse it after this script has run.)

Implementation: Simply visit the setup page, enter your blog details and paste the code into the designated parts of your template. Once it's working, you can tidy it up and customise it to your blog. You can use the function provided - jumpNav(postID, direction) - to set buttons or links to jump anchors ('up', 'down'), within the page ('top', 'bottom') or between archives ('earlier', 'later'), for whatever makes sense for your blog.

Troubleshooting: If you're having problems, try using the "development" version of the script to aid with troubleshooting. (This is also the "human readable" code.) Find where the external script calls "/blog-nav/blog-nav.js" in the header and replace that part with this URL.

Advanced Usage: I've been playing around with some "fixed" buttons on my blog to let readers scroll up and down from any element. I'm not sure if I like it, but FWIW you can replicate it by putting this in your header:

<style>
div.fixed { position: fixed; }
</style>

<!--[if lte IE 6]>
<style type="text/css">
html, body
{ height: 100%; overflow: auto; }
div.fixed { position: absolute; }
</style>

and this in your body section:

<div class="fixed" style="top: 50px; right: 20px;">
<input type="button" value="&and;" onClick="jumpNav(window.location.hash, 'up');"><br/><br/>
<input type="button" value="&or;" onClick="jumpNav(window.location.hash, 'down');"></div>


Thanks to Brett Merkey for the "faking position: fixed; in Internet Explorer" hack.

As usual, please direct your questions, suggestions and other feedback (including working code!) to the comments below. Also, if you've got it working and looking good, please post a pointer in the comments too!

Filed in: , , ,
Posted at 4:20 AM by Greg.
46 Comments:
<    >
Blogger Aditya said...
Man, I'm going to read this when I can understand all the stuff you said there... you were right, it is a little hard because of all the code one has to add.

I'll look into this more closely in the morning, definitely (9:19 PM here). But tell me, are you planning to discontinue freshtags? No updates?

<    >
Blogger Greg said...
Hi Adi,

Yeah, it might be best to sleep on it :-)

Seriously though, you enter your blog main URL (http://the-lastword.blogspot.com/), the archive URL (in your case, the same ie http://the-lastword.blogspot.com/), select the archive method (FreshTags - good on you!) and paste in four massive chunks of template goodness.

Honestly, what could be simpler? The other stuff about magic floating buttons is only for the curious and is an optional (dubious) part of the hack.

Yes, FreshTags is still actively under development. I know my credibility here is shot, but we'll be seeing a new release ... soon :-)

<    >
Blogger Sam said...
This is an interesting solution... to a really frustrating problem. Many high-fives to the creator!

I'm taking a php class this semester and I feel that I could whip up a similar solution IF ONLY THERE WAS ANY RHYME OR REASON TO BLOGGER'S POST ID NUMBER!!! Sorry about that. But really, can anyone figure out what is going on in Blogger's post ID numbering scheme?

Here is info from one of my posts:
Posted on 4/25/2006 10:46:26 PM
blogID 19936365
postID 114601959085100372

How did they possibly come up with that number? Any ideas?

Anyway, way to go on the prev/next implementation!

<    >
Blogger John said...
Implemented here for testing and demo purposes. Once again, I prove that I never saw a script I didn't like!

One thought (in the interests of useability / transparency)... Could the arrows say "next" & "prev" or similar so that it is obvious even to a noob what they're intended to do?

<    >
Blogger Enviroman said...
I am using the standard Blogger Minima template and not using Freshtag (haven't figured out what it is all about yet). What archiving system am I using? Menu or List?

<    >
Blogger John said...
Greg,

I've hit a wall w/ the format of my archive URL's, which helpfully seem to have the dynamic bit (the date) smack in the middle, viz:

http://blogfresh.blogspot.com/2004_12_01_blogfresh_archive.html

I think that's why some of the code isn't working. Thoughts?

<    >
Blogger Greg said...
@Sam - Blogger's postIDs are probably handed out centrally by their server, rather than being a cunning combination of blogID and timestamp. But if they are figuroutable - well, I'd love to know how!

@Peter - Sorry, not familiar with blog template names. How about a link?

@John - Should be fine with archive URL of http://blogfresh.blogspot.com/ (note trailing slash). Might be tougher for the script to figure out which are the archive links for those using the plain link list method. If so, I might need to make some changes to the script to look for the word "archive" somewhere as well.

Oh - and by all means make the URLs say next/prev or former/later or whatever makes sense for your blog. That stuff's entirely in the template, not the script, so can be freely changed.

<    >
Blogger Peter @ Enviroman said...
@Peter - Sorry, not familiar with blog template names. How about a link?

Blogger Help

<    >
Blogger Greg said...
Hi Peter,

Thanks for the pointer. You're using the "list archive" approach. However, you've also got the archive URL (archURL) of "http://bloggerfordummies.blogspot.com/". ie no archive directory. Which means that the archive detection script, in listing through all the links on your page, will find about 35 URLs instead of the required 4.

To get around that, you (and everyone else without an archive path) will need to select the "list" method, but make the following simple change:

var rexp = new RegExp(archURL, 'i');

will now become:

var rexp = new RegExp(archURL+'.+_archive.html$','i');

You're effectively saying "give me all the links that start with my URL (archURL), are followed by any number of characters (.+) and ends with _archive.html" This should catch all (and only all) the archive URLs on the page.

If your blog uses a different archive file name, please modify the regular expression to reflect that. Or, bite the bullet and install FreshTags!

Regular expressions are a bit of arcane art - and one in which I'm barely a novice - so please post any difficulties here and I'll see what I can do.

You can test your efforts by pasting this into your address bar:

javascript:archURL="http://bloggerfordummies.blogspot.com"; var links = document.links; var rexp = new RegExp(archURL+'.+_archive.html$','i'); archives=new Array(); for (var i=0; i<links.length; i++) if(links[i].href.search(rexp)==0) archives.push(links[i].href); alert(archives.length+': '+archives);

(changing the archURL and RegExp as required)

You should see a popup box with the count of archives found, followed by a list of them.

Good luck!

<    >
Blogger Aditya said...
i slept over 8 new comments!? woah...!

greg! why are the arrows opening a blank new tab for me? 0_0

<    >
Blogger Greg said...
You mean here, right? These links are opening in a new window for me too ... but then, all Freshblog hyperlinks seem to open in a new window (for me at least).

I think it's this line in the CSS:

<base target="_blank" />

Presumably, this is the way John wants it to work. But does anyone know of a way to override this setting, at least for JavaScript links?

<    >
Blogger John said...
I'm just going to change the target over to self, or take the whole tag out & let the browser default carry the load. Hope to have time to try again today.

<    >
Blogger Greg said...
Cool. I guess you could just mod the template so that the navigation links have a target of self, leaving the rest to pop up in new windows?

(Just to let you know, at the mo' the comment arrows are still in but the script has been taken out, meaning the arrows are broken.)

<    >
Blogger Greg said...
Woo-hoo! Looking good ...

You've gotta hand it to John - there's no hack he won't say no to. :-)

Here's as good a spot as any to make a few notes for the knowledge base:

1) There's a design flaw in my script that means that when the page is still loading and the reader clicks an arrow, the "NavLadder" (array or archive/anchor links) is not yet built and causes an error. This is because the NavLadder gets built once the page is loaded (ie once all the posts and anchors are safely written out).

The next release will test for the existence of NavLadder, and wait until it's built. This will be transparent to users ie happen entirely on my end with script changes. I'll hold off until a few more bugs shake loose before making the fix. Sorry folks, my fault!

2) If you're using FreshTags (and honestly, why wouldn't you?), then you need to ensure that this month is archived. This is so that readers can click the "More ..." link on the main page and go to the appropriate archive - which may well be this month.

3) When you're positioning the arrows, buttons, links etc, it's probably a good idea to place them in such a way as they're guaranteed to vertically and horizontally align with the anchor. This is so that when a reader clicks the arrow and the page jumps, their cursor should already be positioned over the next anchor. Hence, readers can smoothly scroll up and down without moving their mouse. It's tricky and fiddly but I think worth it.

<    >
Blogger John said...
Greg,

Thanks for the pointer about the archiving. I was about to ask you about the last link on the page! Have archived March & April & we're good to go. I assume I can re-archive April w/ the right post-count in a couple of days?

I'll mess w/ the anchor alignment in my test blog this week, when I try to get the fixed buttons working....

<    >
Blogger Greg said...
Yep ... you can update the post-count in the archive with the magic archive bookmarklet as often as you like.

My new thing is to update last month's at the start of each month, and create this month's at the same time. Err, if you catch my drift.

<    >
Blogger redpig said...
Sorry to comment so much later than the original post - hopefully this is useful.

I just added (yesterday) my own version of the previous-posts navigation to my own blog. (I avoid regexes and the dom api where possible.)

In the process, I noticed the postid for the first time. It appears to be just like a UNIX timestamp - time in seconds from the epoch except with either extra precision (milli/micro) or some randomness thrown in by blogger. Not sure which.

This was useful for me because I could let someone click previous-posts, then check to see if the last post they could have seen is older than the last post on the archive page that was just loaded and forward to the next archive page if so.

It can also be parsed with javascript's builtin Date() object. This could let a blog dynamically format post dates based on user preference, for example.

W.

<    >
Blogger Johan Sundström said...
A note to Sam and Greg: the Blogger PostID is not a combination of the date and the BlogID, it is the timestamp alone, in (ten-)nanosecond precision, of the time when you started to write the post.

<    >
Blogger Hannes Couvreur said...
Hi Greg,

your blog really helped me out with some Blogger-stuff I was having trouble with. Thanks a lot.

About the prev/next-navigation: it works fine, but only in Firefox. When I load my pages in IE6 I get an errormessage saying "Navladder" is undefined. What does it mean and how can I fix this?

Thanks a lot and keep up this splendid work.

<    >
Blogger Hannes Couvreur said...
Ok Greg,

The problem is solved. How? I don't now, but after reloading the whole thing a couple of times it apparantly works again.

Arne

<    >
Blogger Greg said...
That was my fault - I was tweaking another hack that was interacting with Blog Nav when I accidentally overwrote the "live" script. Woops! Sorry 'bout that.

Picked it up and fixed it, thinking I'd gotten away with it. But thanks for the feedback. It's good to know people are using this stuff, even when it's because I break something.

:-)

-Greg.

<    >
Blogger abcd... said...
I read all the instructions and modified the code a bit and then on testing it, it returned all the archives correctly. But as I embedded the code into my template, everything according to instructions, I found the following error:
1. On the Item pages, the next and the previous buttons gave me "cannnot find page" error.
2. Html error in archive pages.
3. Nothing happens on clicking the prev and next buttons. ( probably due to the html error ).
4. Nav buttons fail with embedded video content as they don't work until entire video is downloaded which usually takes quite a bit if time.
I don't know what I did wrong. My blog is

Here is the code which I tested and returns correct values:

javascript: archURL="http://freakyvids.blogspot.com"; var tagtype='select'; var tagname='ArchiveMenu'; var els=document.getElementsByTagName(tagtype); var archives = new Array(); var len = els[tagname].length; for(var i=1; i\<\len; i++) archives.push(els[tagname][i].value);; alert("Archive count: "+archives.length+"\nFirst Archive: "+archives[0]+"\nLast Archive: "+archives[archives.length-1]);

Ps: please remove the \ \ before and after the " i less than len" in the for loop as, whitout that, posting this javascript sniippet was giving me a broken tag error here.

<    >
Anonymous Anonymous said...
What the commenter said above also goes ditto for me, friend.

<    >
Blogger Greg said...
Hi guys,

Sorry for delay, I hope this helps.

@rational ahmand: It seems that your archives array isn't getting built. This might be due to the variable being defined inside a function, so it's not global. To fix it, please try removing this line of code from the function "buildArchives()":

var archives = new Array();

and placing it just before the line:

function buildArchives()

(ie move archives array definition outside of the function.)

the weirdo stalker: I'm not sure what's going on, since I can't replicate your problems. It could be that the implementation isn't working for you since the script only triggers once the page load event happens. If you have a very heavy page, then users will start interacting with it before all the elements have downloaded.

To see if it's not this, please try using the "development version" ie find where the external script calls "/blog-nav/blog-nav.js" in the header and replace that part with this URL.

Good luck!

-Greg

<    >
Anonymous Anonymous said...
Thanks for the help. I'm probably doing something wrong, but it still didn't work.

Best,

rational ahmand

<    >
Blogger Greg said...
Hi rational ahmand:

Don't give up - you're nearly there!

In your blog-nav code, you set your
archURL = "http://ahmandishere.blogspot.com/archive/"

But, in fact, your archives aren't in a directory of their own; their in the main directory. So, change the line to:

archURL = "http://ahmandishere.blogspot.com/"

That should do it.

Cheers,

-Greg.

<    >
Anonymous Anonymous said...
Thanks again. Unfortunately, it still isn't working. Perhaps, I'm not following your directions correctly or there is some further problem.


Best,

rational ahmand

<    >
Blogger Greg said...
I've had another look, and it's a bit of a puzzler. Would you mind swapping in the development version (see above instructions to the weirdo stalker) and telling me what error messages you get? You can swap it back straight afterwards so as not to disturb your readers.

The more descriptive you can be about what messages pop up under what conditions, the better I'll be able to figure out what's going on.

-Greg.

<    >
Anonymous Anonymous said...
Sure. I hope that I can do this one right. ;)

<    >
Anonymous Anonymous said...
Hi-

When I replaced the code with the url you've supplied here, it failed to respond at all on my page.

<    >
Blogger Greg said...
Hi again,

So, it didn't work at all when you replaced this line:

<script type="text/javascript" src = "http://ghill.customer.netspace.net.au/blog-nav/blog-nav.js">
</script>

with this:

<script type="text/javascript" src = "http://ghill.customer.netspace.net.au/blog-nav/v02/blog-nav-v02-dev.js">
</script>

That's very odd - can you tell me what sort of errors you got? I mean, JavaScript etc?

Also, please try typing:

javascript: alert(NavLadder)

into the address bar and tell me what it says.

-Greg.

<    >
Anonymous Anonymous said...
Hi-

I made a mistake replacing the url last time. So I replaced the line as you said in the last comment and pop up boxes with strings of code in them opened when I loaded the page. I hope that's not too vague. However, the tweak still didn't work at the lowest and highest arrows.

And when I put in "javascript: alert(NavLadder)" as you also suggested, it said "?Nav=top," followed by a long string of numbers.

I hope that made sense.

Best,
rational ahmand

<    >
Blogger Greg said...
Hi there - you're going to have to be a fair bit more specific if I'm to diagnose what's going wrong.

BTW, I just noticed that your blog is Blogger Beta - don't they have built-in next/prev links?

<    >
Anonymous Anonymous said...
Yes, I thought so. Sorry about that. On the post pages, however, the "next" and "prev" links now work.

And nope, I don't already have the built-in prev/next links. I would've had to switch the template from classic to beta to get them. And I'm too lazy to try to find and rebuild all my prior tweaks for the revised template.

Besides, I have a natural skepticism when using anything with 'beta' appending the title. You know, doing the programmer's dirty work for him.

When I replaced the url, I saw the following messages in pop-up boxes:

in doNav

in buildLadder: PageType=Main

buildNavURL: path= dir=top hash= targetURL=?Nav=top

buildLadder: currPos=-1

in getPos: -- View Arhives --, http://ahmandishere.blogspot.com/2005_04_01_archive.html, etc, etc.

getPos: nothing found

buildNavURL: path=undefined dir=down hash#8491266552761862393
targetURL=undefined?Nav=down#8491266552761862393

getNavDir: =

When I pressed the prev. post link button on the main page:

in getPos:
?Nav=top,#60011439391211750666, etc, etc.

in jumpNav

…then it went to: “Page Not Found”
The requested URL was not found on this server. Please visit the Blogger homepage or the Blogger Knowledge Base for further assistance.

I hope that was enough detail.


Best,
rational ahmand

<    >
Anonymous Anonymous said...
Nothing's happening when I click on the links. Am I using the correct code?


<script type="text/javascript">
// Blog Navigator v0.2
// http://www.greg-hill.id.au (Creative Commons)
// See http://blogfresh.blogspot.com for details

// Define archURL path --archURL--

var links = document.links; var rexp = new RegExp(archURL+'.+_archive.html$','i'); archives=new Array(); for (var i=0; i<links.length; i++) if(links[i].href.search(rexp)==0) archives.push(links[i].href);
<MainOrArchivePage><script type="text/javascript">
// Main and Archive Page Only

PageType = "Archive";

function buildArchives()
{
// Archive building code --Arch--

}
</script></MainOrArchivePage>

<script type="text/javascript" src="http://ghill.customer.netspace.net.au/blog-nav/blog-nav.js">
</script>


I have no archive directory, btw.

<    >
Blogger M said...
I placed the code at the header and footer parts only as I only want the "MORE" or NEXT PAGE at the bottom of the page.
But when I click "MORE", it goes to the second post of the same page, not of the next page.
I tried changing the number at the footer part from:
jumpNav(NavLadder[NavLadder.length-2], 'down');">More...
to
jumpNav(NavLadder[NavLadder.length-9], 'down');">More...
It does jumps to the post number 15 when I click "MORE", but can't make it go to next page.

any suggestion?

<    >
Blogger Greg said...
G'day,

It's going to be pretty hard for me to troubleshoot your implementation - you don't want broken code on your high-traffic blog, which is fair enough. But I can't see what's going on ...

Briefly, BlogNav works by building an array of your archives (ie a URL for each archive page), and an array of your anchors (ie the "#..." on the current page). It then stitches them together into a "Nav Ladder":

{earlier archive}
{anchors}
{older archive}

Hence the NavLadder[NavLadder.length-2] is a reference to the second last rung.

My tip is to re-implement the code (as-is), then type the following into the browser address bar:

javascript:alert(archives.join('\n'))
javascript:alert(anchors.join('\n'))
javascript:alert(NavLadder.join('\n'))

Send me the results in an email and we'll take it from there.

-Greg.

<    >
Blogger KizzDaLipz said...
I added the code to my blog and while I see the arrows, when I click them , nothing happens. i'm using the old blogger templates with a list archive listed by month and year. When I click on an archive listing i see

http://bringindanoize.blogspot.com/2005_02_01_archive.html

but when I click the arrows i see nothing.

<    >
Blogger woof nanny said...
I tried this, but I got arrows at each post, when I really want just arrows and/or an older posts link on the bottom of the page. Clicking on the links didn't seem to work anyway, and for whatever reason I lost my banner. Thank God I saved my info, so I was able to recapture it. Initially I switched from my classic template to a layout, but I hated that, and went back to classic. It seems adding an older post link wouldn't be that hard, is it??? I'm so frustrated!

<    >
Anonymous Anonymous said...
Does the Blog Navigator work with self hosted Blogger sites?

<    >
Anonymous Anonymous said...
Is there a newer version of the code?

I think it was mentioned before somewhere in the comments, Greg, you were going to ammend the code to include - if a user clicks on a link before the page has had chance to load, the code would still work.

<    >
Anonymous Anonymous said...
Hi,

I was wondering if someone could take a look at my blog regarding the Navigator as I have spent quite a while on this, I am nearly there with the code and determined to get it working.

My blog URL is http://www.andywhiteley.com/blog

I am using a classic template, on my web host.

When I preview the template in Blogger, before publishing, the code seems to work.
Yet when I then publish via ftp I get the following error in the Firefox javaScript error console.

----------------------------------------------------------------------
Error: NavLadder is not defined
Source File: http://ghill.customer.netspace.net.au/blog-nav/blog-nav.js
Line: 8
----------------------------------------------------------------------

I am presuming that the code wasn't written for a blog published on an ftp web host.
Is there any code I can add or change to get this working?

Any help would be appreciated,

Thanks.

<    >
Blogger Takashi said...
Hi Greg,

First of all, thank you so much for sharing such a nice script!!! I was longing for this for ages and am happy to have come across to your site.

As I was installing this onto my blog (URL: http://www.studiosugi.com/blog), there was something that i couldnt figure out.... I looked through all the comments and your instruction, tried the "development" version, but didnt work. so i guess this is time to ask you a couple of question.

believe me, i tried and tried... and most of the things are working fine now. but there is still some errors that almost makes me cry...

well, I am using classic template via FTP and my archive method is "list". of course "daily".

Q1. On the top page, when i click the "more..." link , it just goes to the top of the page. I think it needs to jump to SECOND previous post in order to jump to the previous page. How can I do it??

Q2. Whenever I click on Previous/Next links, it jumps to the Previous/Next page, but the page is displayed from the very bottom, not from the top... I see "?Nav=bottom" at the end of the html. Is there anyway I can change it? is this something i have to change in javascript?? I would rather jump to top of the page.


just in case you need, i will give you the result i got from these tests;

javascript:alert(archives.join('\n'))
http://www.studiosugi.com/blog/archive/2009_03_03_archive.html
http://www.studiosugi.com/blog/archive/2009_03_04_archive.html
http://www.studiosugi.com/blog/archive/2009_03_05_archive.html
http://www.studiosugi.com/blog/archive/2009_03_06_archive.html


javascript:alert(anchors.join('\n'))
#1845206978456974901
#3393911001996819032
#7539577935313646921
#250426146015101714
#8845480049810170541


javascript:alert(NavLadder.join('\n'))
?Nav=top
#1845206978456974901
#3393911001996819032
#7539577935313646921
#250426146015101714
#8845480049810170541
http://www.studiosugi.com/blog/archive/2009_03_04_archive.html?Nav=down#8845480049810170541


hope this makes sense to you. please please please get back me when you get a chance! I really want this for my blog.

again thank you so much and sorry for long blah blah blah.

take care,
TAKASHI

<    >
Blogger Andy Whiteley said...
Hi, just need someone to tell me why I am still getting the error "NavLadder is not defined" Thanks.

My blog URL is http://www.andywhiteley.com/blog

<    >
Blogger Andy Whiteley said...
Given up on the Blog Navigator. I went with Pagination using JavaScript. Until I find a way around it, the only drawback is that you have to rename the archive files to page1.html, page2.html etc...

http://www.softcomplex.com/forum/viewthread_3681

<    >
Anonymous ganool said...
thx for the tutorial..
but its not working for me


eXTReMe Tracker