Wednesday 22 December 2010

Drupal: Collapsible blog archive (similar to Wordpress / Blogger) using Views

I was really surprised that after a lot of digging, I could not find any pre-built solution to this seemingly popular problem. Surely all big CMSs should have this functionality. It turns out it's not that hard to build something similar to the Blogger archive block on your own using Views. You can see mine in action at the bottom of the sidebar on this page. It will have the following structure (with collapsible months):
▼ December 2010
   Article 1
   Article 2
   Article 3
► November 2010
► October 2010
1) Create a new View
Give it a name and type=node and create a new block display

2) Fields
Add 2 fields; Node:PostDate (no label, and with custom format "F Y"), Node:Title (no label, and check "link field to it's node")

3) Filters
Add a filter on Node:Type and select the type(s) of nodes you want to include (e.g. Blog). Also add one on Node:Published (and select yes)

4) Sort Criteria
Add one on Node:PostDate and select descending

5) Basic Settings
Click style and select "HTML List", then click settings and group by post date. Now click CSS class and add your own custom class name which we will use later (I used jack-archive-block)

At this point you should save, and click preview. If you have 3 months of blog posts, then you should see 3 Month-Year titles, each with their own list of article links.

6) Block Settings
Admin name: what we will use to select it on the blocks page (I used "Jack Archive")

7) Tweaks
Now go back into the Node:PostDate field and click "hide from display" as we dont want it for every node, only for every group. Also check "re-write output" and enter the following:

 [created]

This will prefix each of the section titles (dates) with a little collapse icon, which we will manipulate later with jQuery. That should be it for coding up your View. So save, and go to the blocks admin page and whack it in your sidebar.

8) Style
Next, we style it. Here's the CSS I used:

div.jack-archive-block h3 {
 cursor: pointer;
 margin: 0;
 font-size: 1em;
 font-weight: normal;
 padding: 6px 0;
}
div.jack-archive-block ul {
 padding: 0 0 0 10px;
 list-style: none;
}
div.jack-archive-block ul li {
 background: none;
 line-height: 130%;
 padding: 3px 0 5px;
}

The first block deals with the dates; it says if you mouse over, it should look like you're hovering over a link. The second and third blocks remove any default list styling you may have, so you dont get any random bullet point graphics.

9) jQuery
Finally, the jQuery that makes the magic happen:

$(document).ready(function()
{ 
 // init: collapse all groups except for the first one
 $(".jack-archive-block ul").each(function(i)
 {
  if (i==0) $(this).siblings("h3").children(".collapse-icon").text("▼");
  else $(this).hide();
 });
 
 // click event: toggle visibility of group clicked (and update icon)
 $(".jack-archive-block h3").click(function()
 {
  var icon = $(this).children(".collapse-icon");
  $(this).siblings("ul").slideToggle(function()
  {
   (icon.text()=="▼") ? icon.text("►") : icon.text("▼");
  });
 });
});

That should be it. You should be able to click the dates, and have the relevant articles appear or disappear as desired, and have the nice little icon change accordingly. The next step would be another tier to the hierarchy, so you can collapse by year, and then by month... but I haven't got that far yet. Suggestions welcome.

REFERENCES
http://drupal.org/node/825052