February 5, 2007

Expandable archive list for MovableType

I'm blogging since March 2003 and as time goes I noticed my blog archive list became way too long and ugly. Finally I figured out how to generate it in a nice expandable list form you can see on the right. Here is a my small how to for MovableType powered blog. It's a little bit hacky, but works fine.

...

1. Install Archive Date Header Plugin from Adam Kalsey. This allows to generate year headers.

2. Insert this piece of Javascript somewhere - if you have common js file that would be the best, but at worse just paste it before </head> in your template. It's a function to handle expand/collapse year clicks.

<script type="text/javascript">
  function ec(e) {
    var targ;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ) {
      rows = targ.parentNode.getElementsByTagName("DIV");
      collapsed= targ.className == "year-hdr collapsed";
      targ.className = collapsed?  "year-hdr expanded" : "year-hdr collapsed";
      for(i=0; i < rows.length; i++)
        rows[i].style.display = collapsed? "block" : "none";
    }
  }
</script>

3. Use the following snippet in your template to generate expandable archive list. It generates nested list of archives with year headers.

<div class="side">
  <div>
    <MTArchiveList archive_type="Monthly">
      <MTArchiveDateHeader>
        </div><div>
        <p class="year-hdr collapsed"
          onclick="ec(event)"
          id="archive<MTArchiveDate format="%Y">">
             <MTArchiveDate format="%Y">
        <p>
      </MTArchiveDateHeader>
      <div class="month-row">
        <img src="images/folder.gif" align="middle"/> <a
          href="<$MTArchiveLink$>"><MTArchiveDate format="%B"></a>
       </div>
    </MTArchiveList>
  </div>
</div>

4. If you prefer the current year to be expanded by default, insert this piece of javascript after above template:

<script type="text/javascript">
  year = document.getElementById("archive" + (new Date()).getFullYear());
  if (year) {
    year.className = "year-hdr expanded";
    rows = year.parentNode.getElementsByTagName("DIV");
    for(i=0; i < rows.length; i++)
        rows[i].style.display = "block";
  }
</script>

5. Define CSS styles. Here are my definitions:

.year-hdr {
  cursor: pointer;
  cursor:hand;
  font-size: 120%;
  font-weight: bold;
  background-repeat: no-repeat;
  background-position: top left;
  padding:2px;
}

.collapsed {
  background-image: url(images/plus.gif);
 }

.expanded {
  background-image: url(images/solid.gif);
}

.month-row {
  display: none; 
  padding-left: 2em;
}

Done.