<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Molindo Techblog &#187; SEO</title>
	<atom:link href="http://techblog.molindo.at/category/seo/feed" rel="self" type="application/rss+xml" />
	<link>http://techblog.molindo.at</link>
	<description>Molindo Techblog - formerly known as talk-on-tech.blogspot.com</description>
	<lastBuildDate>Fri, 05 Feb 2010 16:06:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Wicket: A Neat Url Encoding Strategy and some basic SEO</title>
		<link>http://techblog.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html</link>
		<comments>http://techblog.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html#comments</comments>
		<pubDate>Tue, 09 Dec 2008 09:03:00 +0000</pubDate>
		<dc:creator>Michael Sparer</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html</guid>
		<description><![CDATA[After a year of working extensively with Apache Wicket I want to share some stuff I&#8217;ve been using over and over again and might be useful for you as well. In this first post it&#8217;s a custom URL Encoding Strategy and some related basic SEO.
Pages often depend on entities &#8211; e.g. a Customer or a [...]]]></description>
			<content:encoded><![CDATA[<p>After a year of working extensively with <a href="http://wicket.apache.org">Apache Wicket</a> I want to share some stuff I&#8217;ve been using over and over again and might be useful for you as well. In this first post it&#8217;s a custom URL Encoding Strategy and some related basic SEO.</p>
<p>Pages often depend on entities &#8211; e.g. a Customer or a product and as those pages should be bookmarkable as well, there has to be a unique way to tell the page which entity to use. As entities either don&#8217;t have unique names or one wants to avoid having an (database) index over the name column, the index-ID is for most applications the way to go. As it&#8217;s usually undesireable to expose the database ID of an entity in the URL, it has to be encoded and decoded somehow to get from myshop.com/customer/12 to myshop.com/customer/ea34cff &#8230; or something like that.<br />
<span id="more-31"></span><br />
Using a custom Url-mounting strategy makes it a breeze:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> IndexedIdEncryptingUrlCodingStrategy <span style="color: #000000; font-weight: bold;">extends</span> LowercaseOnlyIndexedUrlEncodingStrategy <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> _encryptedParams<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// serverroot is e.g. http://www.mypage.com - required for 301 redirects in baseclass</span>
<span style="color: #000000; font-weight: bold;">public</span> IndexedIdEncryptingUrlCodingStrategy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> mountPath, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> serverRoot, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">Class</span> bookmarkablePageClass, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span>... <span style="color: #006633;">encryptedParmas</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>mountPath, serverRoot, bookmarkablePageClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_encryptedParams <span style="color: #339933;">=</span> encryptedParmas<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> IndexedIdEncryptingUrlCodingStrategy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> mountPath, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> serverRoot, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">Class</span> bookmarkablePageClass, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> pageMapName, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span>... <span style="color: #006633;">encryptedParmas</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>mountPath, serverRoot, bookmarkablePageClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_encryptedParams <span style="color: #339933;">=</span> encryptedParmas<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@SuppressWarnings<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;unchecked&quot;</span><span style="color: #009900;">&#41;</span>
@Override
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> appendParameters<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> AppendingStringBuffer url, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Map</span> params<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">:</span> _encryptedParams<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> indexStr <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span>index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> val <span style="color: #339933;">=</span> params.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>indexStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> val <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
params.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>indexStr, encodeId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span><span style="color: #009900;">&#41;</span> val<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">appendParameters</span><span style="color: #009900;">&#40;</span>url, params<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@Override
<span style="color: #000000; font-weight: bold;">protected</span> ValueMap onDecodeParameters<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> urlFragment, <span style="color: #000000; font-weight: bold;">final</span> ValueMap urlParameters<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">:</span> _encryptedParams<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> indexStr <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span>index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> val <span style="color: #339933;">=</span> urlParameters.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>indexStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> val <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
urlParameters.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>indexStr, decodeId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> val<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> urlParameters<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getEncryptedParams<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">return</span> _encryptedParams<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #003399;">String</span> encodeId<span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span> val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #003399;">Integer</span> decodeId<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This class&#8217;s baseclass is used for SEO only: it just checks if there are only lowercase letters in the URL and does a 301 redirect to the lowercase variant of the page if not.<br />
Why lowercase only: The first of the Ten SEO Commandments (if there was such a thing) is: &#8220;<span style="font-weight:bold;">Thou shalt only have one URL per page</span>&#8221; &#8211; and for bots <span style="font-style:italic;">http://www.myshop.com/customer/Foobar</span> and <span style="font-style:italic;">http://www.myshop.com/customer/fOoBar</span> are two different URLs &#8211; which is a bad thing as far as duplicate content is concerned. Well, it could also be uppercase only or camelcase only &#8211; but lowercase makes it easier to read for humans and is also easier to implement than camelcase.</p>
<p>Then just mount the page like that:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">mount<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> IndexedIdEncryptingUrlCodingStrategy<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/customer&quot;</span>, <span style="color: #0000ff;">&quot;http://www.mypage.com&quot;</span>, HomePage.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>and construct the page params like that:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">final</span> PageParameters params <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PageParameters<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
params.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span>, myEntity.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// add e.g. a link</span>
add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> BookmarkablePageLink<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;link&quot;</span>, HomePage.<span style="color: #000000; font-weight: bold;">class</span>, params<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Download the files:<br />
<a href="http://molindo.at/files/msp/IndexedIdEncryptingUrlCodingStrategy.java">IndexedIdEncryptingUrlCodingStrategy.java</a><br />
<a href="http://molindo.at/files/msp/LowercaseOnlyIndexedUrlEncodingStrategy.java">LowercaseOnlyIndexedUrlEncodingStrategy.java</a></p>
<p>In my next post I&#8217;ll get a bit more into Wicket &amp; SEO: Show a more SEO way to encode URLs, how to deal with the JSESSIONID and how to apply the code shown today on a Page. Stay tuned &#8211; and consider subscribing</p>
<p>PS: If &#8220;thou convet my code&#8221;: the code is public domain, feel free to do whatever you like to do with it. If you have any suggestions or implement enhancements, just post them in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
