Inside Paulo Abrantes' head
[ start | index | login or register ]
start > 2006-11-29 > 1

Snipsnap SEO Hacking: Post title optimization

Created by pabrantes. Last edited by pabrantes, one year and 357 days ago. Viewed 1,342 times. #1
[edit] [rdf]
labels
attachments

Snipsnap SEO Hacking: Post title optimization

Yesterday while surfing on the web I found an interesting article about >>the importance of title tags in search engine optimisation (SEO). It's a good reading if you have a couple of minutes, and the main idea is that the <title> tag is important regarding SEO and in blogs is good that each post page has as it's title the post title.
On the following paragraphs, I'm gonna explain what kind of titles does snipsnap use by default and how you can improve them for SEO, with a minimum coding effort.

On SnipSnap each page has as it's title the string "blog name :: page name", for example, "pabrantes' Weblog :: start" if you are accessing the main page of my blog.

When it comes to blog post on snipsnap the developers - >>funzel and >>leo - to avoid collisions have chosen the format "DATE/number" for the post's name, for example, 2006-11-29/1 for the 1st post of 29 November 2006, 2006-11-29/2 for the 2nd and so on.
Now what this means is that when you access a direct post page, the page title will be something like " pabrante's Weblog :: 2006-11-29/1" and as you can imagine this is definitely not optimised for search engines.

Realising this I wanted to implement the underlying tip of the article I've previously mentioned, have as page title the posts subject. I've done it with some minor changes on the SnipImpl class and on the main.jsp. These means if you want to do this optimisations, you have to download the source, change it the way I'm suggesting, compiling and finally deploy the new version.

Let me introduce the changes on each file.

  • SnipImpl
  1. Description: This is one of the classes that implements the snip interface and it's the one that actually represents snipsnap pages (AKA snips).
  2. Location: org.snipsnap.snip
The snip interface has a getTitle although you'll need to change it a bit in order to give the posts subject when you are requesting it is a blog post.

The code by snipsnap devs:

public String getTitle() { if (null == nameFormatter) { nameFormatter = new PathRemoveFormatter(); nameFormatter.setParent(new WeblogNameFormatter()); } return nameFormatter.format(name); }

My code:

public String getTitle() { String title = null; Snip parent = getParent(); if (parent != null && parent.isWeblog()) { String postTitle = getContent(); return postTitle.substring(postTitle.indexOf("1") + 2, postTitle .indexOf("{")); } else { if (null == nameFormatter) { nameFormatter = new PathRemoveFormatter(); nameFormatter.setParent(new WeblogNameFormatter()); } title = nameFormatter.format(name); } return title; }
The main idea is to check if the snip in question has a parent and that parent is a weblog, if those conditions do happen we are requesting the title of a blog post, so we access it's content and strip out it's subject. Otherwise we just execute the old code.

While implementing this idea I found out that the code related to parents weren't working as I would expect, no snips had parents. Now this might be because I'm using the file system storage and there's a bug on the metadata materialisation or something. Anyway the closest fix I've made up, was to instead of relaying on possible metadata to find out the parent by ourselves.

To do this 2 methods were changed on the SnipImpl class, getParent and getParentName. Once again I'll present the old code and new code for each method.

Snipsnap developers code:

public Snip getParent() { if (null != parentName && !"".equals(parentName) && null == parent) { parent = SnipSpaceFactory.getInstance().load(parentName); } return parent; }

My code:

public Snip getParent() { if (null != getParentName() && !"".equals(getParentName()) && null == parent) { parent = SnipSpaceFactory.getInstance().load(parentName); } return parent; }

The change was minimal but you'll understand it when I'll show you the getParentName() method.

Snipsnap developers code:

public String getParentName() { return this.parentName == null ? parentName : this.parent.getName(); }

This is an interesting recursive solution. Although since parentName is never set (once again, maybe due to metadata problems… I really hadn't the time to go investigate that, maybe some other time) getParentName would always be null.

My code:

public String getParentName() { return this.parentName != null ? parentName : resolveParentName(); }

private String resolveParentName() { String[] snips = this.getName().split("/"); if (snips.length == 1) { return null; } else { setParentName(snips[0]); return snips[0]; } }

My code does the same although instead of using recursion to find out the parent's name I just grab the snipname split it by the character "/" and go fetch the first if the size of the string array is bigger than one. Keep in mind that for snip B which has A as parent B.getName() returns the string "A/B". Indeed it's a bit bigger but works in perfection.

Regarding java code that's all! Now we just need to do a minor change on the jsp that takes care of the pages titles.

  • main.jsp
  1. Description: Like the name says it's the main JSP.
  2. Location: You can find it on the apps/default folder
Search for the <title> tag in the main.jsp file you'll find the code that renders the format I've already discussed:

<title><c:out value="${app.configuration.name}" default="SnipSnap"/> :: <c:out value="${snip.name}"/></title>

You should change it to:

<title> <c:choose> <c:when test="${snip.weblog}"> <c:out value="${app.configuration.name}" default="SnipSnap"/> :: <c:out value="${app.configuration.tagline}"/> </c:when> <c:otherwise> <c:out value="${snip.title}"/> </c:otherwise> </c:choose> </title>

Which mainly does the following, if you are in a weblog snip the title becomes weblog name :: weblog tagline . Otherwise it will show the pages title, which in the case of the blogs becomes their subject.

Now you can run ant to compile the new modified snipsnap and you are ready to go!
As you can verify I already have this hack deployed on my blog and I'm not having any problems with it (at least for now).

And that's all folks!

Please login to www.pabrantes.net.
Who am I?
paulo-roca2My name is Paulo Abrantes AKA pabrantes and I'm a software developer. I'm currently employed at >>CIIST working as a Java developer in >>FenixEDU.

This blog is mostly about Java programming, domain driven design and snipsnap bliki developing. Everything written in this blog is my personal opinion and it may not reflect the opinions of my employer and co-workers.


Blog subscription
subscribe by rss subscribe by email

Links
>> Home
>> Paulo's Profile
>> Post History
>> Add to Technorati Favorites
>> Paulo's Photo Gallery
>> WishList
>> Posting without Login

Search Blog
Fellow Bloggers

Recent Posts

Java Programming: Bytecode Injection
Intermission: Sorry For Downtime
Software Developing: Studying The Bliki Domain Model
SnipSnap Developing: Trying to settle a roadmap
System Administration: Load Balancing with Apache
Blogging: Two years have passed
Software Developing: The SnipSnap Saga
Java Programming: Getting your code spicy with Groovy
Software Developing: Fluent Interfaces
Software Developing: Implementing a ShoutBox on SnipsSnip
Software Developing: SnipSnap, SnipIt and SnipSnip
Java Programming: Proxies and Access Control
Java Programming: Proxies and References
Java Programming: References' Package
YALM: Yet Another Layout Modification

For older posts, please refer to post-history for a complete Post History

Logged in Users: (0)
… and 2 Guests.
This is a modified version of snipsnap.org created by >>Paulo Abrantes