Monday, December 11, 2006

Related Posts

I first got the idea for this after seeing Hoctro's similar hack. Unfortunately his requires that you change all your post titles to have the same prefix for related articles. I wanted one that would show related posts based on labels. I also wanted to do something with the new JSON format. I also looked at some of the already made hacks from Beautiful Beta to figure out how to parse the JSON properly.

FYI, this probably won't work correctly if your labels use any reserved url characters, like question marks (?) or the slash character (/). I'm not url encoding anything here.

First of all, go to Template -> Edit HTML and paste the following into the page header:

<script type="text/javascript">
//<![CDATA[
var relatedTitles = new Array();
var relatedTitlesNum = 0;
var relatedUrls = new Array();
function related_results_labels(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
relatedTitles[relatedTitlesNum] = entry.title.$t;
for (var k = 0; k < entry.link.length; k++) {
if (entry.link[k].rel == 'alternate') {
relatedUrls[relatedTitlesNum] = entry.link[k].href;
relatedTitlesNum++;
break;
}
}
}
}
function removeRelatedDuplicates() {
var tmp = new Array(0);
var tmp2 = new Array(0);
for(var i = 0; i < relatedUrls.length; i++) {
if(!contains(tmp, relatedUrls[i])) {
tmp.length += 1;
tmp[tmp.length - 1] = relatedUrls[i];
tmp2.length += 1;
tmp2[tmp2.length - 1] = relatedTitles[i];
}
}
relatedTitles = tmp2;
relatedUrls = tmp;
}
function contains(a, e) {
for(var j = 0; j < a.length; j++) if (a[j]==e) return true;
return false;
}
function printRelatedLabels() {
var r = Math.floor((relatedTitles.length - 1) * Math.random());
var i = 0;
document.write('<ul>');
while (i < relatedTitles.length && i < 20) {
document.write('<li><a href="' + relatedUrls[r] + '">' + relatedTitles[r] + '</a></li>');
if (r < relatedTitles.length - 1) {
r++;
} else {
r = 0;
}
i++;
}
document.write('</ul>');
}
//]]>
</script>

Save it, and then click the Expand Widget Template checkbox. Scroll down to the blog1 widget, and find the following:
        <b:if cond='data:post.labels'>
<data:postLabelsLabel/>
<b:loop values='data:post.labels' var='label'>
<a expr:href='data:label.url' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != "true"'>,</b:if>
</b:loop>
</b:if>

It'll probably be down in the post-footer-line section (whether that be line-1, -2, or -3)

Change that to:
        <b:if cond='data:post.labels'>
<data:postLabelsLabel/>
<b:loop values='data:post.labels' var='label'>
<a expr:href='data:label.url' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != "true"'>,</b:if>
<b:if cond='data:blog.pageType == "item"'>
<script expr:src='"/feeds/posts/default/-/" + data:label.name + "?alt=json-in-script&amp;callback=related_results_labels&amp;max-results=10"' type='text/javascript'/>
</b:if>

</b:loop>
</b:if>

The 3 lines in bold are what I added ;)

Save it, and now go to Template -> Page Elements and add a new HTML/Javascript widget. I added mine underneath the main blog posts widget. You'll need to add it after (in the page) the above codebox for it to work correctly. Paste the following into it:
<script type="text/javascript">
removeRelatedDuplicates();
printRelatedLabels();
</script>

Now go back to Template -> Edit HTML, check the checkbox to expand the template code, and find the HTML/Javascript widget you just added. It'll look something like the following. Add the lines in bold:
<b:widget id='HTML13' locked='false' title='Related Posts' type='HTML'>
<b:includable id='main'>
<b:if cond='data:blog.pageType == "item"'>
<!-- only display title if it's non-empty -->
<b:if cond='data:title != ""'>
<h2 class='title'><data:title/></h2>
</b:if>
<div class='widget-content'>
<data:content/>
</div>

<b:include name='quickedit'/>
</b:if>
</b:includable>
</b:widget>


There's a few numbers you can tweak to show more or less related posts. In the first codebox there's a part that says i < 20 and the 3rd codebox has a part that says max-results=10. You can play around with these numbers if you want. After playing around a little these numbers seem to give a good trade-off between the speed of page-load and the number of related posts displayed.

40 comments:

咖啡鱼 said...

Good show,and i traslate it into chinese.Are you mind it ?

PurpleMoggy said...

No, I don't mind, go for it

LOUI$$ said...

purple,wanna exchange links with me?

TonNet said...

I was madly awaiting for this one. Thx Purple. I am posting a note about your "Related Post" in Spanish.

LOUI$$ said...

Hi purple?any respond for my offer?changing link?i have added yours,and how about you?

Can i ask you i more thing?Is about your "More Links",the submenu got underline dot dot stlye,how to do it?thanks!

PurpleMoggy said...

@TonNet... glad you like it

@LOUI$$... you got a link now

to get the dots just add some css something like the following:

.menutitle span{
border-bottom:1px dotted #999;
cursor:pointer;
}

the cursor:pointer part makes the mouse cursor behave like a link when hovering over it (which lets the user know they can click on it)

phydeaux3 said...

Very nice work.

LOUI$$ said...

Thanks a lot,purple.Late i will post something about your work!Cheer up togather!

Singpolyma said...

Of course, freshtags-singpolyma has done this for some time. I need to get the 2-del.icio.us-and-trackback for BETA working... and a FreshTags version that doesn't require del.icio.us...

vï†æ said...

you are so good at this purple! i tried a few of your hacks and have been kinda succesful with them. and i'm not really a techie. am overjoyed! keep it up!!

禾草唐楷 said...

Thanks for your hack,but there is a problem,I've used my own sidebar,I mean I've use the second sidebar,but there is nothing appeared when I accessed to the "index.html",but there will be ok when otherpages address be accessed,should you please tell me why???how can I defined a default tag??because the "index.html" has no tag information

PurpleMoggy said...

@ 禾草唐楷

The last codebox adds an if statement (in bold) that makes it only show up on the permanent link pages

The Frugal Law Student said...

Whenever I try to place the widget under the postbody, it won't let me. There's no dotted square for me to put it in. What can I do to fix this?

The Frugal Law Student said...

I fixed it. My next question is if there's anyway to show your related posts on the main page?

PurpleMoggy said...

@The Frugal Law Student

The whole point to related posts is to show posts that are somehow related to the current post (on the permalink page). The question becomes, what related posts should we show from the main page... which usually is showing the most recent X number of posts (and not one specific post)?

Yan Sniim said...

Man thnx for putting up this hack. I followed your every instruction closely. But nothing seems to happen! :(

PurpleMoggy said...

@Yan Sniim


If this one's not working for you, Hoctro has a similar hack

http://hoctro.blogspot.com/2007/01/killer-hack-related-articles-by-labels.html

arjuna said...

nice hack!i added it to my blogger.one question? how to change the black dot in front of related posts? i prefer my own design,my THX.

PurpleMoggy said...

@arjuna

It's showing a little disc because that's the default for an <li> tag.

Take a look at these pages for ideas on how to modify this with CSS

1
2
3

3dx said...

Works fine... many thanks!

Guradian said...

"Related Posts" in Chinese

Royce Wells said...

just wanted to know if there is a way to exclude one of your labels from the related posts search.

-Royce

Pankwood said...

Existe uma versão deste código para o velho layout do Blogger ?

Bollywood said...

its not working at all

Adam said...

Thanks a lot. Before this I had always envied WP powered blogs that had this feature.

To think that I have been doing it manually all this time.

Komail Noori said...

I like it.

Regards,
Komail Noori

Web Site Design - SEO Expert

Neel said...

Really Nice post.

Helped me a lot.. Can't thank you enough.

sara2002 said...

thx a lot
i have tried many code...none of them works...
your workls like charm
u can see my site
http://allthefunny.blogspot.com

Dutt said...

Very very good post. I have been searching for this post since many days.

Now I have implemented the same for my site

http:\\msdotnetsupport.blogspot.com

http:\\msdotnetsupport.blogspot.com

Thanks for you post.

I would like to have an article from you regarding

how to remove bellow 4 links from these are taking more space and finding no much use

Newer Post Home Older Post
Subscribe to: Post Comments (RSS)

shyam_rocks said...

Can you plz tell the significance of those two numbers the one in the loop of the java script (i.e 20) and the one called max-result="10" ...what they basically signify...

My blog:http://shyamkol.blogspot.com

Diego Cabai said...

Hi, great hack and great Blog, here is a Spanish translate and in the bottom some tips on how to change the look of the results. Thanks !!

Posts Relacionados en Blogger/Blogspot

FF said...

hi purple,

i follow what you teached exactly. however, there is not any related entries show up. there is no error though. any suggestion? thanx. =)

my blog is http://technobizs.blogspot.com/

Vlada, Czech Republic said...

Hi,
thank you very much for this trick. I've implemented successfuly.
Nevertheless I set max 5 posts it shows more than 5 (even more than 10). But for other posts it is just 5.
Here is example:
http://www.stockweb.blogspot.com/2008/04/google-acquires-skype.html

Thanks for any comment

Pablo Luján Fernández aka SSTRM said...

Hey, thank you very much for this neat trick. Good job bringing this usaeful tool to Blogger.

Keep it up!!

Ben said...

The thing wouldn't let me save the template. Something about "span" not having a matching end tag. help?

Diego Cabai said...

PurpleMoggy, hi, is there a reason for this to stop working? I have this installed on some Blogger Blogs but a few days ago stop working in all of them and I didn't make changes.

Could be a change on the code of Blogspot that make this? Thanks

Helen Fernanda said...

For portuguese speakers, this tutorial is translated here.

Para quem prefere em português, este tutorial está traduzido aqui.

EasyAdsenseVn said...

Thanks Purple for this useful post!
I prefer to use your code than Hoctro's widget.
However, when I use your widget, the related posts lie on the right-side, and the word "Related Post" does not appear. You can see here, for example:
http://easyadsensevn.blogspot.com/2008/09/how-to-add-blogger-read-more-expandable_02.html

Could you help me to solve this problem?
Thanks!

dcloud said...

Hi Purple. I followed all of your instructions step by step, got the codes installed right where they should be, and saved my template. I didn't get any errors, and I have triple checked everything to make sure it's correctly placed, but the "related posts" do not appear anywhere on my blog (dcblog.net).

Just curious if you would know why they don't appear?

Thank you.

dcloud said...

Ok, nevermind - now I understand. Your reply about the "permanent link pages" woke me up.

Unfortunately, this isn't what I'm looking for. I want "related posts" to appear on the main pages, not just on the page with the article.

Too bad, too, because this is the first related posts hack I've found in two weeks of searching that actually worked. Bummer.

Thanks anyway.