Pages

Tuesday 3 January 2006

How to include categories for your blog (manual, expand-collapse)






UPDATE: if you want to get the expand / collapse code and instructions for New Blogger (Blogger in Beta), see this post.

This post explains how to include expand/collapse or show/hide categories (and even sub-categories) in your blog, i.e. listings of your old posts classified under topic or subtopic, as you can see in my sidebar (the "Posts from this blog on" section). It should work on all blogging platforms where you can edit your template. So it may be of interest to users of blogging platforms which don't have inbuilt categories, notably Blogger.

The system's based on Blogger's show-hide links script, adapted (and of course improved) by my Magical Sheep pardner, the ever-inventive CSS Caesar and King of Kode Truckspy/redryder52/KRS (I've yet to come up with a short name for him and can't even link to him now he has no blog, but I guess he wouldn't object to "Kode King"... beats "Hey you", dunnit, eh?!).

First, I thought it might help to outline the pros and cons of this system.

Pros and cons

Pros

  • It's manual - so you have complete control over what categories and sub-categories you want, what posts to list under which heading (including the same post under more than one category), the exact order of categories and posts etc, which posts to leave out from which list, etc.
  • It's simple to do once you know how.
  • It works even if Javascript is turned off (but see Cons below).

Cons

  • It's manual! You have to manually edit your template (and save, and republish your entire blog) everytime you want to list a new post under one or more categories.
  • So it can be time-consuming. I should update it after every post but I usually only do it once or twice a week.
  • Which means your categories can get out of date, unless you regularly update.
  • Readers with Javascript turned off will see the whole list fully expanded (an improvement over the original Blogger version of the code, suggested by Truckspy after Schika commented that the original script doesn't work at all for users who've disabled Javascript in their browsers - they see nothing). That can make your sidebar very long if you've turned off Javascript, but it's better than not working at all for those users (personally though, I think there's no point anymore turning Javascript off, too many websites need it on to get the most out of them or sometimes to use them at all. But this adaptation will help those who've done it).

Step by step howto

Head section

1. Copy and paste the following code into your blog template or webpage, between the <head> and </head> tags (just before the </head> line is fine) (.shown corrected from display:inline to display:block on 15 Jan 2006):
<style type="text/css">
.texthidden {display:inline}
.shown {display:block}
</style>

<script type="text/javascript">
document.write('<style>.texthidden {display:none} </style>');
</script>

<script type="text/Javascript">
function expandcollapse (postid) {
whichpost = document.getElementById(postid);
if (whichpost.className=="shown") {
whichpost.className="texthidden";
}
else {
whichpost.className="shown";
}
}
</script>

Sidebar

2. Now here's how to insert expand/collapse categories list in the sidebar section of your blog template (or wherever you want the categories list to appear, as long as it's between the and tags). There are two steps for each category:
  • add code for the heading or title of each category or topic name, so that when someone clicks on that heading, the list of posts that belong in that category will show in full (and when they click on it again, the list of posts will be hidden again), and
  • demarcate the list of posts that are to go with each particular category title. The bit that does this is invisible to the reader, but is needed to make sure that the content you list within it will be what is shown or hidden when the corresponding category title is clicked.
3. So for a category title you would use this code:
<a href="javascript:void(0);" onclick="expandcollapse('UNIQUENAME1')"> [+/-] CategoryTitle1</a>
You should give each category a unique identifying label of its own, which is UNIQUENAME1 in the above example (it needn't be uppercase, but a single clear word like "tech-drop" is best (in my case to signify that relates to the Technorati category) - a descriptive name is obviously the most helpful, as long as no other items in your template have been given the same name). UNIQUENAME1 will be invisible.

CategoryTitle1 is the bit that people can see, so change that to the appropriate category title e.g. "Technorati". (The "[+/-]" isn't strictly necessary but to me it's the easiest way to indicate to readers that they can click on the title to expand the list, and click it again to collapse it. I'm sure someone could change the code so that it shows a + only when the list is hidden, and a - when it's shown, but that someone will not be me!)

4. Then, to demarcate the list of posts that are meant to go with that particular category heading, use this code:
<ul class="texthidden" id="UNIQUENAME1">
<li><a href="Permalink1">Post1Name</a></li>
<li><a href="Permalink2">Post2Name</a></li>
</ul>
Note the UNIQUENAME1. It can be anything you like, but it must match whatever you used for the associated category title's code, because that's what fixes it so that clicking on the category title (CategoryTitle1 in this case) will display this particular list (and not some other list).

The next bit is just a clickable list of the posts you want to go under that category, with the associated links to the item page or post page of the individual post. Everything between the <ul> and the </ul> will be shown or hidden together on clicking the category title. So change Post1Name to the title of the first post in that category and Permalink1 to its permalink (URL of the individual post's unique page), do the same thing in the next line for the title/permalink of the next post you want to show in the list, etc. Just copy/paste and edit as many lines as you need for your posts. You don't even have to use the same titles as in your posts for Post1Name etc, you could abbreviate the post title here - but of course you must use the exact correct URL for the permalinks.

Also note that for my list of posts I used an HTML list (starting with <ul> and ending with </ul>, with <li> for each list item), but with a class="texthidden" within the <ul> tag. It's the class="texthidden" which does the showing/hiding (and the UNIQUENAME1 which pinpoints which other bit (CategoryTitle1 in this case, as it's associated with expandcollapse UNIQUENAME1) does the showing and hiding when clicked). However, you could use something else e.g. <p class="texthidden" id="UNIQUENAME1">, as long as you have the corresponding closing tag (such as </p>) to mark the end of the section that you want shown or hidden when someone clicks the matching category title (matched up by using UNIQUENAME1 in both bits of code, as I mentioned). For example this:
<a href="javascript:void(0);" onclick="expandcollapse('hello')"> [+/-] Show or hide me</a>
<p class="texthidden" id="hello">Well helloooooooooooo there, sailor or sailorette! (depending-on-your-gender-of-choice-as-this-is-a-modern-and
-non-discriminatory-blog-which-strives-not-to-be--ist)</p>
Would display as this:
[+/-] Show or hide me

Well helloooooooooooo there, sailor or sailorette! (depending-on-your-gender-of-choice-as-this-is-a-modern-and-
non-discriminatory-blog-which-strives-not-to-be--ist)

Subcategories

5. It's exactly the same for sub-categories. Just stick the subcategory title and demarcation code in the right place where you want the sub-category to appear (not forgetting to include the proper number and location of the matching closing tags, especially with lists within lists, which I personally find can get a bit confusing).

Here's some example code from this very blog, but abbreviated. I've deliberately included just two main categories, one of them with two sub-categories, so you can see more clearly how it works:
<ul>
<li><h2>Posts from this blog on:</h2></li>

<li>
<h2><a href="javascript:void(0);" onclick="expandcollapse('tutorial-drop1')"> [+/-] Tutorials, Guides; Blogging Tools and Tips; Technology</a></h2>
<ul class="texthidden" id="tutorial-drop1">
<li><a href="javascript:void(0);" onclick="expandcollapse('tech-drop1')"> [+/-] TECHNORATI</a>
<ul class="texthidden" id="tech-drop1">
<li><a href="http://consumingexperience.blogspot.com/2005/02/technorati-tags-introduction.html">Technorati tags: an introduction</a></li>
<li><a href="http://consumingexperience.blogspot.com/2005/07/technorati-tag-creator-for-multiple.html">Tag creator for multiple word tags, and more</a></li>
</ul>
</li>

<li><a href="javascript:void(0);" onclick="expandcollapse('blogadd-drop1')"> [+/-] BLOGGING ADDONS, HACKS, TOOLS</a>
<ul class="texthidden" id="blogadd-drop1">
<li><a href="http://consumingexperience.blogspot.com/2005/12/feeds-partial-or-full-how-to-have-both.html">Feeds: partial or full? How to have both</a></li>
</ul>
</li>

</ul>
</li>

<li>
<h2><a href="javascript:void(0);" onclick="expandcollapse('geek-drop1')"> [+/-] The Social Geek</a></h2>
<ul class="texthidden" id="geek-drop1">
<li><a href="http://consumingexperience.blogspot.com/2005/12/robert-scoble-london-geek-dinner-10.html">Robert Scoble London Geek Dinner 10 December 2005</a></li>
<li><a href="http://consumingexperience.blogspot.com/2005/11/molly-holzschlag-london-geek-dinner-24.html">Molly Holzschlag: London Geek Dinner 24 November 2005 report and podcast</a></li>
</ul>
</li>
</ul>
That would look something like this (though it needs tidying up of the formatting, spacing etc - you get the drift!):
7. And just to make life easier for you, you can copy and paste the following code into your own blog template, then edit it as mentioned above (including copy/pasting and editing additional lines for each extra post, and copy/pasting for sub-categories - or deleting lines or sections as desired to suit your own categories and sub-categories), then save and republish. I've used HTML unordered lists and heading 2s, but as mentioned above you don't need to. Just to emphasise again that if you use lists you <span style="font-weight: bold; font-style: italic;">must</span> remember to close each <ul> with a </ul> especially when using sub-categories, and similarly follow each <li> with a matching </li> at the end of the relevant element - I've indented the code so you can see more clearly which closing tags go with each opening tags.

Here's the code:
<ul>
<li><h2>Posts from this blog on:</h2></li>

<li>
<h2><a href="javascript:void(0);" onclick="expandcollapse('UNIQUENAME1')"> [+/-] CategoryTitle1</a></h2>
<ul class="texthidden" id="UNIQUENAME1">
<li><a href="javascript:void(0);" onclick="expandcollapse('UNIQUENAME2')"> [+/-] SubCategoryTitle1</a>
<ul class="texthidden" id="UNIQUENAME2">
<li><a href="Permalink1">Post1Name</a></li>
<li><a href="Permalink2">Post2Name</a></li>
</ul>
</li>
<li><a href="javascript:void(0);" onclick="expandcollapse('UNIQUENAME3')"> [+/-] SubCategoryTitle2</a>
<ul class="texthidden" id="UNIQUENAME3">
<li><a href="Permalink3">Post3Name</a></li>
</ul>
</li>
</ul>
</li>

<li>
<h2><a href="javascript:void(0);" onclick="expandcollapse('UNIQUENAME4')"> [+/-] CategoryTitle2</a></h2>
<ul class="texthidden" id="UNIQUENAME4">
<li><a href="Permalink4">Post4Name</a></li>
<li><a href="Permalink1">Post1Name</a></li>
</ul>
</li>
</ul>
It would look something like this (though again the formatting needs tidying up):
8. To add an item to more than one category I find it's easiest just to copy the line for it in the first category and paste it under the next category in the right place, exactly as is (no changes needed to individual post title lines). Tip (added 15 Jan 2006): if you have Firefox, use the Copy Link Text extension to copy the titles of posts more easily; when I update I do a week or two's worth at once by opening my archive page and then going through the posts listed there. And when you need to add a new item to a list in future, just copy/paste an extra <li> line in the appropriate place and edit the title and permalink to match the new item's.

As requested by several including Adam Graber, Jim/Edi Subandono, Diego Gomes (let me know if I've left anyone out!)

Do let me know if you make use of this system and find it helpful.

UPDATE: if you want to get the expand / collapse code and instructions for New Blogger (Blogger in Beta), see this post.


Technorati Tags: , , , , , , , , , , , , ,

50 comments:

Scott said...

This is pretty cool. I use a different method on Blogger that combines Google Blog Search and Technorati tags.
I gave a brief out line on this page: Blog redesign

Improbulus said...

Thanks Scott. Your method is neat too. I'm working on a categories system which is a lot less work, using Technorati tags also.

John said...

Very Cool...

On Technorati (just in case it will help) I have a bookmarklet that will make tags that point to a user account / tags from a claimed blog at Freshblog.

Skips the whole "bookmark to del.icio.us" bit, & has Technorati do the work for you....

Adam said...

Imp.
Thanks for the post! I'm excited to put this together for my blog. Thanks for the link to my website too.
Adam

Improbulus said...

Thanks John and Adam, glad you like...

Your method looks very useful John.

Adam said...

Imp.
My apologies. Thanks for your gracious correction to my implicit assumption about web gurus. Of course, you assumed, graciously, that I knew Latin.
Fronti nulla fides
2e

Improbulus said...

No probs 2e, though I am still an aspiring gurette (or should that be gura?). :D

Anonymous said...

Great stuff man... easy, simple yet powerful script, finally I can quit from msn spaces;)

Amanda said...

would you recommend javascript over DOM?

Improbulus said...

Anon, thanks for your comment, glad it's useful!

Dreamweaver - not quite sure what you mean? Javascript is one way to access and interact with the DOM or Document Object Model, which is an outline or tree-like structure of how all the elements on a webpage are organised. Every link, every element on a webpage is a "node" in the DOM, a branch of the tree. So in this case the script is told which DOM node it's being asked to expand or collapse, and then it does it. Hope that helps.

StyleyGeek said...

This is excellent. Thanks so much. And easy to implement too. I just have a couple of issues (which aren't caused by you, but maybe someone here has some ideas).

The first is that even when I don't use conditional tags around the whole lot of category code in the sidebar, the categories only appear on the main and archive pages (ie. never on the item pages). This happens even if I put ItemPage tags around it all! (I have MainOrArchive around it at the moment, but have tried without it too).

The other question/issue I have is whether you have any suggestions for when the blog has been running a while and there are LOTS of posts. The sidebar could just end up being stupidly long. Especially for people viewing it with Javascript turned off so that it doesn't show as collapsed.

So two things: first of all, maybe there's a way to detect if someone is using Javascript or not, and just not execute the categories code if they are? And secondly, is there a way to get the posts belonging to a particular category to list on a separate page when someone clicks on the category, rather than showing in the sidebar?

Anyway, thanks again for the excellent work. I'm very happy with my categories.

Improbulus said...

Cheers styleygeek, glad it helped.

Conditional tags - one gotcha is that you can't nest the mainorarchive page and itempage conditional tags. They work independently. You may have a section in your template that's just surrounded by itempage tags, after the main section where you've included your categories, for some reason, and the categories code may need to be there too? Which is tedious I know. Best to search your template for itemtag occurrences and take it from there. If you email me your raw template I'm happy to take a look.

Second, the instructions above already take account of Javascript/no Javascript. If someone has Javascript turned on, they get the expand/collapse. If they don't, they will see the lists, all of them, fully expanded (that was the easiest way, rather than not seeing anything at all). You can test it by turning off Javascript in your browser and viewing again.

Finally, yes you can get the link to go to a separate page. Create a special category post (backdated, ie. change the date/time on the post page, so it won't clutter up your main page - you can even go back to 1990!) for each category, and then put the category code in the post (obviously you can then list your category items in the main body of the post), then in your sidebar just link the category name to the URL of your category post. It's not really an expand/collapse thing (though you could do that with subcategories in your categories post if you want to). Hope that makes sense.

amit upadhyay said...

Cool. Also see this.

Improbulus said...

Thanks Amit. Interesting, but could you give more info on how it all works please?

jiaminn212 said...

Thanks. my blog is in chinese. it still works beautifully.
see here.

slipstream said...

i knew the blogs were configurable with this, but i know some html but i mainly know C,
i can't thank you enough for this excellent page Imrobulus
thankyou

Improbulus said...

Thanks for the comments, shinjian and slipstream. Glad it works for you! (link to your blog didn't quite work though, shinjian, so I fixed it. :))

kdr said...

Thank you for this hack, it is just what I wanted for my Poetry Website! I couldn't have come up with it on my own.

Improbulus said...

Thanks for your comment, Kayla, glad the hack was of help.

Anonymous said...

I used this to format a questionnaire and it works great!!! I looked forever and this is the only code that I could figure out how to use. Thanks so much!!

Improbulus said...

Glad it worked, anon, thanks for your comment. As you say, this technique can be used to produce show/hide sections for anything, not just category listings but stuff within the body of a post or webpage too.

Anonymous said...

nice tutorial here ;)

and could you make another one, on how when you click to select one of the archives, then the title of each post appears in the middle, and how can you get the title of the archive ? ex. May 2006 or Apr 2005 etc.

thx

Improbulus said...

Thanks for your comment qureyoon. Will add a tutorial on the archive to my Todo list!

ben said...

thank you very much for the excellent idea, and the extremely clear directions on how to incorporate categories. it's a great addition to my blogs, and I thank you for your generosity of time and effort. Ben D.

Improbulus said...

Mallikarjun, thanks for your comment, I'll take a look though it may not be for a while as I'm snowed under at the mo.

Ben, thanks for your comment, it's always nice to get feedback like yours - glad to have been of help.

Shaamil said...

Great work dude! I want to use this script to run another script.. So that when I click on a link, whatever is generated by my script is shown.. And when I click the link again It will vanish.. How do I achieve this result.

Actually I want to show/hide the ccomments.com comment box...

Cheers!

Improbulus said...

Ta C0ldEnd. Not sure exactly what you mean though about using this to run a script? To show/hide a cocomment box, you can use exactly the same script as above. Instead of "[+/-] CategoryTitle1" just insert e.g. "[+/-] Show/Hide CoComment Box" and instead of

<ul class="texthidden" id="UNIQUENAME1">
<li><a href="Permalink1">Post1Name</a></li>
<li><a href="Permalink2">Post2Name</a></li>
</ul>

just use something like

<div class="texthidden" id="UNIQUENAME1">
Cocomment stuff here
</div>

Hope that helps.

Roughstock Jess said...

This is brilliant—thanks for putting this together and sharing it.

I'm still working on fully implementing this on one of my blogs, but I already have a question: once the menu is expanded and the user clicks one of the expanded links, the menu automatically loads collapsed on the linked page. Is there any way to code it so that it stays expanded on load? That is, can you selectively choose which pages load it collapsed and which pages load it expanded? I'm thinking not, but hoping I'm wrong.

(You can see what I mean at Roughstock News: click "About Roughstock" and choose one of the links...you'll see the menu automatically loads collapsed on the next page that loads.)

Thanks again!
—JJ

Improbulus said...

Thanks for your comment Jessie Jane and I'm glad you found it helpful.

Could you clarify your question? I tried that Roughstock link you gave, but the menu doesn't stay expanded on load. And with the code I've given, the menu is automatically collapsed on the link page anyway, try my "Posts from this blog on" section in my sidebar e.g. any post under Life and Health. When the post loads, the same menu is collapsed.

Roughstock Jess said...

Not sure when you tried the Roughstock link, but I've been working on it for a while—it's where it should be now.

To clarify:

The menus work as they should (e.g. user clicks on "About Roughstock" and they get an expanded list of links). But once they click one of the expanded links, the menu reloads collapsed (it doesn't stay expanded on the following page when the user clicks through). Basically, every time a page is loaded, the menu loads already collapsed. Is there a way to keep the menu expanded when the user clicks through a (previously hidden) link?

Does that make more sense? Sorry if I'm being unclear.

Thanks,
JJ

Unknown said...

Hi ....I tried to put categories through this method but the links are not working when the page gets loaded fully & also if i right click & open link in new tab it works .......can you please help

Improbulus said...

JJ, sorry I must have completely missed your response at the time. Unfortunately I don't think there is a way to keep the menu expanded when the user clicks through, as far as I know - not unless you had it expanded on all pages.

Kunika - please post more info about what you did exactly, otherwise it'll hard to figure out what went wrong. I've had a look at your blog and it seems to be working fine. Have you sorted it out since, it seems?

Priit Parmakson said...

Your method is ingenious - with respect to the technological constraints of the New Blogger - but it translates into manual indexing of your blog - in XML. That's not an inviting proposition. Why the hell won't the Blogger offer decent widgets like RECENT POSTS, RECENT COMMENTS, CATEGORIES? WordPress obviously does. Of course, Blogger is free, and you get what you pay for.

Improbulus said...

Thanks Priit. Yes manual updating of the list is a real pain, though having the content hardcoded in seems incidentally to help from an SEO viewpoint. I'll probably stop doing that soon.

New Blogger does have Recent Posts as standard (as did Old Blogger) and a Recent Comments feed which you can display in the sidebar as text (see this for instance), as well as labels (categories). So to be fair to Blogger, I think they're finally starting to catch up with WordPress.

Maeven said...

I have scoured the internet looking for a way do this (see sidebar, "Ingredient" heading with the line beneath it, click to expand/contract).

I finally happened upon your page, and while I love this hack and want to use it for expanding/collapsing the contents of sidebar headings, I'm having one heck of a time trying to put it into New Blogger and their widget system.

For example, on this blog, on both of the sidebars I want only the headings to show with the [+/-] that, once clicked, would expose (on the left sidebar) what's under "Labels", "Blog Archive" (and do the same thing with the headings on the right sidebar).

I have placed your coding between the "head""/head" tags, and prepared the rest of your instructions (I tried to include it here to show to you, but I've gotten the error here that "Your HTML cannot be accepted: reference 'javascript:' is not allowed, etc." when trying to include it in this comment when I post it), but with widgetry, how/where should I insert it?

Please, if you have any suggestions, I would be greatly indebted.

(ravin') Maeven

Improbulus said...

Maeven, I've just posted a howto. Hope that helps.

Oxhomiya Jeet said...

That was easy! Even for a non-tech savvy person like me. Thx!

Improbulus said...

Oxhomiya, that's what I aim to do, to make things like this easy for non-techies, so I'm delighted to hear that it helped you. Thanks for your feedback!

Jade said...

This is a really good hack. Just one problem though, when I tried using it on posts with images, the images wouldn't hide. Is there any reason for that? Or does it totally not work with images?

Jade said...

by the way, sorry about that. i managed to figure it out already. ><

Improbulus said...

.Jade, no problem, glad you sorted it!

Admin said...

marvellous work buddy.. i have been looking this hack for 2 months... atlast found it.. Did a great job.....

j0e said...

i want to use this peek-a-boo technique for my main post instead of categories. I am a total newbie and only have very little knowledge of HTML. Can anyone walk me through this??

Thanks

j0e said...

got it..
http://hackosphere.blogspot.com/2006/09/expandable-posts-with-peekaboo-view.html

dfg said...

Great tip Improbulus! I used this to properly categorize tags in my blogger but with a bit of a problem. If you check my blog (http://boy-kuripot.blogspot.com) in Internet Explorer, every gadget/element that is under the gadget that uses this code drops at the end of the post. When I put the gadget, that uses this code in the middle column, only that widget shows. I tried playing around the locations of the gadgets and the problem still persists. My home page is a disaster but try going in one of my posts to see what I mean.

I'm not sure if the problem in the home page is because of this code or because of my layout BUT try visiting one of my posts and compare the page result with IE to Firefox or Safari and you will see the addressed problem. Most of my readers still use IE so if you could help me find a solution for this problem, I would greatly appreciate it! Thanks!

Do email me at shalomsiy@hotmail.com I will also be following the comments in this post!

-Boy-Kuripot

Tepi said...

I found your site two months ago and I was full of grace because I wanted this menu so much, but I have a problem, could you help me? I put it into my Blog of Forex (in spanish, but the section menu is findable) and was so happy I tried to put it into my Internet Blog (also in spanish, the section menu is in the same place). The problem is that (as you may see) in the Internet Blog doesnt align correctly. The style is Son of Moto, any ideas?

Tepi said...

I comment to tell you that I already fixed it, and I wanted to thank you so much for the menu that help my blogs too much.

THANKS YOU!!!

discofunk said...

Hey,

I managed to get one div to close as the other one opens in a blogger post, so you can toggle between headings using javascript.


You might want to take a look as I haven't seen anyone else do this blogger hack yet. See my post on the funk band "WAR" at

http://discofunk-atuneaday.blogspot.com

It's a bit untidy and you are restricted by a set number of DIVs so any help you can give me would be apreciated.... the normal javascript method just didn't seem to work with blogger but this works really well.

cheers

The Folks @PropTalk said...

Your post is a life-saver. My sincerest thanks!

heide abot said...
This comment has been removed by the author.