17.9.2011

How to show Blogger posts in chronological order

Lyhyesti suomeksi: Edellisissä blogeissani oli mahdollista lukea artikkelit myös julkaisu­järjestyksessä. Bloggerissa tällainen ei ole suoraan mahdollista, eikä toimivaa valmista ratkaisuakaan löytynyt. Tässä artikkelissa kerron (englanniksi), miten toteutin kyseisen ominaisuuden tähän blogiin.

How to show Blogger posts in chronological order

This trick needs javascript and is based on David Merriman's hack. Read more...

Although this version worked for me, I made a new version of the script:


Please use the new version, it is better. Thanks :)

Here's the old one:

New Blogger templates have more complex DOM model than the older ones, that's why I had to replace two date-header references with date-outer. This got the script working on Firefox, but not on Internet Explorer.

Script did not work on Internet Explorer, because IE handles the DOM model differently than FireFox, Opera and Chrome. To make it work, I replaced references to firstChild, nextSibling and childNodes[1] with calls to functions getNextSibling and getFirstChild.

Reversed order is shown only if url contains order=ASC. And if it does, the script also adds this parameter to Previous posts and Next posts links.

The actual code for reversing posts is inserted just before the </body> tag in the template. And here's the code:

<!-- post reversal code by mspotilas -->

<script type='text/javascript'>
//<![CDATA[

function getNextSibling(startBrother)
{
  endBrother=startBrother.nextSibling;
  while(endBrother && endBrother.nodeType!=1)
    endBrother = endBrother.nextSibling;
  return endBrother;
}

function getFirstChild(elm)
{
  if(!elm.childNodes.length)
    return;
  var children = elm.childNodes.length;
  for(var i = 0 ; i <= children ; ++i )
    if (elm.childNodes[i].nodeType == 1)
      return elm.childNodes[i];
  return;
}

if(window.location.href.indexOf('order=ASC') > -1) {

  var Blog1 = document.getElementById('Blog1');
  var postContainer = getFirstChild(Blog1);
  var first = getFirstChild(postContainer);
  var child = getNextSibling(first);
  var childNext = null;

  var dateHeaders = false;
  while (child != null) {
    if (child.className == 'date-outer') {
      dateHeaders = true;
      break;
    }
    child = getNextSibling(child);
  }

  child = getNextSibling(first);

  while (child != null) {
    if (child.className != null) {
      if (child.className.match('date-outer') != null) {
        childNext = getNextSibling(child);
        postContainer.insertBefore(child, first);
        first = child;
        child = childNext;
      } else if (child.className.match('post hentry') != null) {
        childNext = getNextSibling(child);
        if (!dateHeaders) {
          postContainer.insertBefore(child, first);
          first = child;
        } else {
          postContainer.insertBefore(child, getNextSibling(first));
        }
        child = childNext;
      } else {
        child = getNextSibling(child);
      }
    } else {
      child = getNextSibling(child);
    }
  }

  var lnk = document.getElementById('blog-pager-older-link');
  if(lnk) {
    lnk = getFirstChild(lnk);
    if(lnk) {
      var old = lnk.href;
      lnk.onclick = lnk.href = old+"&order=ASC";
    }
  }

  lnk = document.getElementById('blog-pager-newer-link');
  if(lnk) {
    lnk = getFirstChild(lnk);
    if(lnk) {
      var old = String(lnk.href);
      if(old.charAt(old.length-1) == '/' || old.indexOf('?') < 0)
          old = old+"?";
      else          
          old = old+"&";
      lnk.onclick = lnk.href = old+"order=ASC";
    }
  }
}

//]]>
</script>

<!-- end post reversal code -->

Finally I added a link to sidebar using a HTML/Javascript widget. Contents of this widget (you need to change the red date part for your blog to get to the page with your first post):

<script type="text/javascript">if(window.location.href.indexOf('order=ASC') == -1) document.write('<a href="/search?updated-max=2011-02-14T08%3A08%3A00%2B02%3A00&max-results=7&order=ASC" title="Show all articles in chronological order"><b>Articles in chronological order</b></a>');</script>

Link is shown only, if posts are not already shown in chronological order.

This works for me with a template based on the "simple theme". Hope it works for you, too. If it does not work for you, you fix it. :)
[Piilota kommentit] - [Näytä kommentit]
Yksittäisen kommentin klikkaus piilottaa/näyttää sen tekstin

7 kommenttia:

Peter @ Enviroman kirjoitti... [vastaa]

Hi,

You left a comment in my blog post Chronological order hack

I tested the hack at Shed weight fast but it wasn't working. If you can take a look and help make it work, I will publish a post in my popular blog the original Blogger Tips and Tricks with a link to your blog post.

MS-potilas kirjoitti... [vastaa]

@Peter @ Enviroman

Hi,

you should change the link in the sidebar code from:
/search?updated-max=2011-02-14T08%3A08%3A00%2B02%3A00&max-results=7&order=ASC
(which works with the dates in my blog's posts) to:
/search?order=ASC&updated-max=2011-09-19T12%3A08%3A00%2B02%3A00
(time is not accurate there but it does not matter, date is more important)

so you get the posts on the page when you click the link. That is important, otherwise you have nothing to reverse...

But then you have some javascript error earlier in your page, which prevents the script from running and reversing the posts. I could not pinpoint what was wrong, there was much code that is not in default template. Some google connect thing gave some errors. Hope you find the error and get this working.

MS-potilas kirjoitti... [vastaa]

@Eric Kamander

I think you have old style template, that's why you had Merriman's hack still working (except on IE) while many others did not. I'm not familiar with old templates, I just started on Blogger this month. :)

But if you want to make your script work on IE, you should add functions getNextSibling and getFirstChild, as in my source. Then replace references to firstChild, nextSibling and childNodes[1] with calls to functions getNextSibling and getFirstChild (same way I changed them). But don't change references of "date-header" to "date-outer", because you have old tempale. If you do so, script won't work on any browser. You should change/add nothing more to your script.

MS-potilas kirjoitti... [vastaa]

@Peter @ Enviroman:
It wasn't javascript error on your page, see the updated line if it makes the code work on your page.
@Eric Kamander:
You should also probably use the updated line.

I changed the line
var postContainer = getNextSibling(getFirstChild(Blog1));
to
var postContainer = getFirstChild(Blog1);
(i.e. removed the getNextSibling call)

Hope this helps.

Eric Kamander kirjoitti... [vastaa]

Thanks. When I do that, it doesn't work on any browser. Maybe its because I'm not reversing my entire blog? (Only a label search)

MS-potilas kirjoitti... [vastaa]

@Eric Kamander
It should work on label search, too, so maybe there was some error inserting/changing the code. You should insert the two functions from my code (getNextSibling and getFirstChild) after "<*script type='text/javascript'*>" line in your code. Then do a search and replace (manually), replace all xxxx.firstChild by getFirstChild(xxxx), all xxxx.nextSibling by getNextSibling(xxxx) and one Blog1.childNodes[1] by getFirstChild(Blog1).

MS-potilas kirjoitti... [vastaa]

I rewrote the script, here: Blogger posts in chronological order, 2011 version. Please use the new version.

Lähetä kommentti