Advanced Archive Widget

| 4 Comments

Anil ArchivesMie has been blogging every month since 2003 on kokochi.com, the list of 57 monthly archives in her sidebar was getting really long.

Mie asked if I could add an archive widget to her blog’s sidebar like the one Anil sports on dashes.com. After looking at the source HTML I realized that coding it in MTML was gonna be kinda complex. In MTML typically for each year in your archives you’d list all the months, but—because of the way that html tables are built—I’d need to list all the months for each year. For example, I need to list all the Jan archives, then all the Feb archives, etc. etc.)

So I asked Anil for his code. Doh! He admitted he was manually updating it. =P

mie-archives.gifI mentioned this to Brad, and he got so excited that he wrote a rough draft. I added the code to the sidebar on Kokochi.com, but the code wasn’t working. =/ After some testing, I realized that there were a few limitations (year’s w/o posts, and the inability to output the month as a number w/o a “0” prefix on single digit months), but then after consulting with Brad, solutions were found!

Follow the below code and you too can have this advanced archive table widget as seen on kokochi.com and dashes.com/anil.

Update: The blog must be publishing a yearly archive file. This file can have zero content, but needs be published in order for the Yearly ArchiveList block tag to output content. 2008 Oct 7

Update 2: Added a comment regarding default output when a month doesn’t have any entries and added a note about the use of the sprintf attribute to ensure that the month number contain two digits. 2009 Jun 22

The MTML Code

<table id="archives-table">
<mt:ArchiveList type="Yearly" sort_order="ascend">
    <mt:ArchiveListHeader><tr><$mt:ArchiveDate format="%Y" setvar="start_year"$></mt:ArchiveListHeader>
    <th><$mt:ArchiveDate format="'%y"$></th>
    <$mt:ArchiveDate format="%Y" setvar="archive_year"$>
    <$mt:SetVar name="is_posts_year_{$archive_year}" value="1"$>
    <mt:ArchiveList type="Monthly">
        <$mt:ArchiveDate format="%m_%Y" setvar="month_year"$>
        <mt:SetVarBlock name="links_{$month_year}"><a href="<$mt:ArchiveLink$>"><$mt:ArchiveDate format="%b"$></a></mt:SetVarBlock>
    </mt:ArchiveList>
    <mt:ArchiveListFooter></tr><$mt:ArchiveDate format="%Y" setvar="end_year"$></mt:ArchiveListFooter>
</mt:ArchiveList>
<mt:For var="month" from="1" to="12">
    <tr>
    <mt:For var="year" from="$start_year" to="$end_year">
        <mt:If name="is_posts_year_{$year}">
            <mt:SetVarBlock name="month_year"><$mt:Var name="month" sprintf="%02d"$>_<$mt:Var name="year"$></mt:SetVarBlock>
        <td><$mt:Var name="links_{$month_year}" default="&nbsp;"$></td>
        </mt:If>
    </mt:For>
    </tr>
</mt:For>
</table>

The Code Explained

Here’s a play-by-play on the MTML code used to produce this list…

Open the table.

<table id="archives-table">

List yearly archives in an ascending order (2001, 2002, 2003, etc).

<mt:ArchiveList type="Yearly" sort_order="ascend">

Open the TR; set the $start_year variable.

    <mt:ArchiveListHeader><tr><$mt:ArchiveDate format="%Y" setvar="start_year"$></mt:ArchiveListHeader>

Output the two-digit year in a TD.

    <th><$mt:ArchiveDate format="'%y"$></th>

Set $archive_year variable with the current year in the archive list.

    <$mt:ArchiveDate format="%Y" setvar="archive_year"$>

Set $is_posts_year_{$archive_year} using $archive_year variable set above. This is a boolean variable that determines if there are posts within the year in context.

    <$mt:setvar name="is_posts_year_{$archive_year}" value="1"$>

List monthly archives for the current year.

    <mt:ArchiveList type="Monthly">

Set the $month_year variable after removing the “0” from the front of the month if it exists (eg. 1_2005, 2_2005 ... 12_2005).

        <$mt:ArchiveDate format="%m_%Y" regex_replace="/^0/","" setvar="month_year"$>

Set the links_$month_year variable. This variable name is dynamically set using the $month_year var set above. The value will be a month linked to the correct archive (eg. <a href="http://kokochi.com/archives/2004/05/">May</a>).

        <mt:SetVarBlock name="links_{$month_year}"><a href="<$MTArchiveLink$>"><mt:ArchiveDate format="%b"$></a></mt:SetVarBlock>

Close monthly archive list.

    </mt:ArchiveList>

Close the TR. Set the $end_year variable.

    <mt:ArchiveListFooter></tr><$mt:ArchiveDate format="%Y" setvar="end_year"$></mt:ArchiveListFooter>

Close the yearly archive list.

</mt:ArchiveList>

For months 1 thorugh 12 do the following.

<mt:for var="month" from="1" to="12">

Open TR.

    <tr>

Loop through the years between $start_year and $end_year.

    <mt:for var="year" from="$start_year" to="$end_year">

If there is posts in the current year, then continue.

        <mt:if name="is_posts_year_{$year}">

Set the $month_year variable using the $month and $year variables from the above for loops. (sprintf will pad the month number with a zero if the number is not a two digit number.)

            <mt:SetVarBlock name="month_year"><$mt:Var name="month" sprintf="%02d"$>_<$mt:Var name="year"$></mt:SetVarBlock>

Use the $month_year variable to output the links_$month_year set in the archive lists above.

        <td><$mt:var name="links_{$month_year}" default="&nbsp;"$></td>

Close all the MTML loops, MTML conditionals, and HTML tags.

        </mt:if>
    </mt:for>
    </tr>
</mt:for>
</table>

Scaleable?

As long as your sidebar is wide enough, you’ll have room for this widget as it get’s wider. But by hacking the above code it shouldn’t be to hard to break the table into two vertically stacked tables or add some javascript to produce a solution involving hiding/showing of content.

If you hack the above, I’d love to hear about it.

Enjoy.

And thx again to Brad Choate, Mie Yaginuma, and Anil Dash for the instigation and assistance to produce this advanced example of MTML.

4 Comments

Thank you so much for doing this. I’ve been really wanting this nifty format I first saw on dashes.com for quite some time. I’m very happy and can now blog for many years to come without dragging down my sidebar. :)

Is there a sane way to get it to also display months for which there are no entries, but to have them unlinked?

The reason I ask is that on a new project, the first month of entries is April, and hence there are large gaps.

The below <mt:For> loop will display an un-linked month:

<mt:For var="month" from="1" to="12">
    <$mt:Var name="month" sprintf="%02d" setvar="month"$>
    <tr>
    <mt:For var="year" from="$start_year" to="$end_year">
        <mt:If name="is_posts_year_{$year}">
            <mt:SetVarBlock name="month_year"><$mt:Var name="month"$>_<$mt:Var name="year"$></mt:SetVarBlock>
        <td>
            <mt:If name="links_{$month_year}">
                <$mt:Var name="links_{$month_year}"$>
            <mt:Else>
                <mt:SetVarBlock name="ts"><$mt:Var name="year"$><$mt:Var name="month"$>01000000</mt:SetVarBlock>
                <$mt:Date ts="$ts" format="%b"$>
            </mt:If>
        </td>
        </mt:If>
    </mt:For>
    </tr>
</mt:For>

Or if you just want a different default output when there is no month—such as a n-dash—change the value of the <$mt:Var$> default attribute:

<td><$mt:var name="links_{$month_year}" default="&ndash;"$></td>

Wow, it’s to complicated for me but I share for my developper member.

Leave a comment