<?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>Devon Hillard Tech Blog</title>
	<atom:link href="http://www.digitalsanctuary.com/tech-blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.digitalsanctuary.com/tech-blog</link>
	<description>Java, ATG, Seam, and related Technologies</description>
	<lastBuildDate>Thu, 02 Jul 2009 19:14:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JavaScript Speeds</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/javascript-speeds.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/javascript-speeds.html#comments</comments>
		<pubDate>Wed, 01 Jul 2009 03:55:10 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=453</guid>
		<description><![CDATA[The JavaScript engines of popular web browsers vary greatly in performance.  The variance in performance is surprising.
Running this test: http://celtickane.com/labs/web-browser-javascript-benchmark/
On my laptop, here are my results (lower is better, your results my vary):
Safari 4: 128
Firefox 3.5: 233
Camino: 615
IE 7: 1181
IE 7 is almost 10 X slower than Safari 4.  With more and more [...]]]></description>
			<content:encoded><![CDATA[<p>The JavaScript engines of popular web browsers vary greatly in performance.  The variance in performance is surprising.</p>
<p>Running this test: <a href="http://celtickane.com/labs/web-browser-javascript-benchmark/">http://celtickane.com/labs/web-browser-javascript-benchmark/</a></p>
<p>On my laptop, here are my results (lower is better, your results my vary):</p>
<p><strong>Safari 4</strong>: 128<br />
<strong>Firefox 3.5</strong>: 233<br />
<strong>Camino</strong>: 615<br />
<strong>IE 7</strong>: 1181</p>
<p>IE 7 is almost 10 X slower than Safari 4.  With more and more sites building rich interfaces and AJAX driven interaction this can be a serious issue.  Recently I was working on a redesign of some category navigation pages.  The new interface used AJAX loaded content and multiple tabs to display content.  It worked great under Firefox, IE 6, IE 8, Safari 3, Safari 4, but was painfully slow under IE 7.  Slow enough that in deference to the high number of customers still using IE 7, and the potential sales loss, we had to remove much of the rich interface.</p>
<p>Be sure to test your rich interfaces in IE 7 and pay attention to performance.  Until people move off of IE 7, we are all somewhat hamstrung with regards to how much JavaScript and AJAX we can use on eCommerce sites.  </p>
<p>One thing to keep in mind is to try to limit the number of AJAX requests.  IE 7 (and many other browsers) limit concurrent requests to 2, meaning if you're loading 12 fragments via AJAX, it will take 6 full requests/response cycles, each one taking ~200-500 ms.  That adds up very quickly.  You can pull everything down in one large AJAX request, parse that response's DOM tree, and extract the pieces you need, but A) that's more JavaScript you're using, and B) at some point you're better off just loading a new page.</p>
<p>Another thing to consider is that while JavaScript and AJAX allow us to build better interfaces for our users, allowing them to be better served by our sites, it's often easy to get distracted by what you can do, and by buzzwords, and lose sight of what actually benefits your users and what doesn't.</p>
<p>Friends don't let friends use IE 7.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/javascript-speeds.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hard Drive Fail</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/hard-drive-fail.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/hard-drive-fail.html#comments</comments>
		<pubDate>Tue, 16 Jun 2009 14:29:01 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/general/hard-drive-fail.html</guid>
		<description><![CDATA[The hard drive in my server failed in a nasty way.  So things may be slightly broken for a few more days, while I fix up things one by one.
Lessons learned:  while backing up your data stuff is important (/var/www, /opt, etc...) DON'T forget to back up things like /etc and the list [...]]]></description>
			<content:encoded><![CDATA[<p>The hard drive in my server failed in a nasty way.  So things may be slightly broken for a few more days, while I fix up things one by one.</p>
<p>Lessons learned:  while backing up your data stuff is important (/var/www, /opt, etc...) DON'T forget to back up things like /etc and the list of the installed apt packages. </p>
<p>So please, be patient.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/hard-drive-fail.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I like jQuery (over Dojo)</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/why-i-like-jquery-over-dojo.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/why-i-like-jquery-over-dojo.html#comments</comments>
		<pubDate>Mon, 08 Jun 2009 23:43:46 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=442</guid>
		<description><![CDATA[With the caveat that I'm not an expert with Dojo/Dojox/Dijit, I'm currently switching a site off of Dojo onto jQuery.  I've used jQuery on a few other sites, but typically just simple effects type stuff.  This site has a lot of AJAX driven stuff going on: AJAX catalog navigation where we replace about [...]]]></description>
			<content:encoded><![CDATA[<p>With the caveat that I'm not an expert with Dojo/Dojox/Dijit, I'm currently switching a site off of Dojo onto jQuery.  I've used jQuery on a few other sites, but typically just simple effects type stuff.  This site has a lot of AJAX driven stuff going on: AJAX catalog navigation where we replace about 12 elements on the page with AJAX loads of other URLs serving back fragments, dynamic tabs which hide themselves if the AJAX source URL returns certain stuff instead of other stuff, etc...  I've been writing lots of this JavaScript based on the Dojo framework, as that's what was handed to me, so I've done a lot of on the job Dojo learning.  I was able to get things to work, so that was good.  However, now that we're transitioning off of Dojo and onto jQuery, I'm amazed at how much easier the jQuery framework makes things.  Aside from being smaller, simpler, and easier to understand (for me at least) I'm able to do the things I want to do, much more easily.</p>
<p>*note: some of the examples might be bad Dojo coding (some mine, some inherited) or might be due to me missing the "best" way to do something, however with both Dojo and jQuery I'm mostly using their documentation and/or Googling for how to do something, so any failings in the Dojo implementation are related to the quality and clarity of the documentation and available related pages.*</p>
<p>For instance, the Dojo code that was handed off to AJAX load a page into a div looks like this:</p>
<pre class="brush: javascript">
	dojo.xhrGet( {
	    // The following URL must match that used to test the server.
	    url : url2,
	    handleAs : &quot;text&quot;,
	    timeout : 5000, // Time in milliseconds

	    // The LOAD function will be called on a successful response.
	    load : function(response, ioArgs) {
		dojo.byId(&quot;brandsDiv&quot;).innerHTML = response;
		return response;
	    },

	    // The ERROR function will be called in an error case.
	    error : function(response, ioArgs) {
		console.error(&quot;HTTP status code: &quot;, ioArgs.xhr.status);
		return response;
	    }
	});
</pre>
<p>That times 12 for the 12 divs we're updating via AJAX.  With jQuery I'm replacing that block with:</p>
<pre class="brush: javascript">
$(&quot;#brandsDiv&quot;).load(url2);
</pre>
<p>Simpler, no?</p>
<p>Also, with Dijit tabs, there's no easy way to hide a tab and resurrect it later.  You have to save off the panel into a JavaScript variable, and reinstate it from that variable later.  See how I handled <a href="http://www.digitalsanctuary.com/tech-blog/general/hiding-and-showing-a-dijit-contentpane-in-a-tabcontainer.html">hiding Dijit Tabs/ContentPanes in a TabContainer</a>.</p>
<p>With jQuery Tabs I just use the built-in disable and enable methods along with one line of CSS to solve the same problem.  Much easier.</p>
<p>I'm also loving the looks of the new<a href="http://flowplayer.org/tools/"> jQuery Tools library from the FlowPlayer folks</a>.  Hopefully I'll be using that library soon on a few projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/why-i-like-jquery-over-dojo.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seam 2.x Web Development</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-2x-web-development.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-2x-web-development.html#comments</comments>
		<pubDate>Wed, 03 Jun 2009 00:14:02 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Seam]]></category>
		<category><![CDATA[book]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=431</guid>
		<description><![CDATA[Packt Publishing just sent me a copy of their new Seam book entitled Seam 2.x Web Development.  Authored by David Salter, it seems to be a well laid out practical guide to building web apps with Seam 2.  I've only skimmed it so far, but will be posting an in-depth review once I'm [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_432" class="wp-caption alignright" style="width: 160px"><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/06/184719592x.jpg"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/06/184719592x-150x150.jpg" alt="Seam 2.x Web Development by David Salter" title="Seam 2.x Web Development" width="150" height="150" class="size-thumbnail wp-image-432" /></a><p class="wp-caption-text">Seam 2.x Web Development by David Salter</p></div>
<p>Packt Publishing just sent me a copy of their new Seam book entitled Seam 2.x Web Development.  Authored by David Salter, it seems to be a well laid out practical guide to building web apps with Seam 2.  I've only skimmed it so far, but will be posting an in-depth review once I'm able to read through it.  </p>
<p>It's great to have a book that covers the new features of Seam 2 and provides examples of common Web 2.0 requirements such as OpenID integration, AJAX/RIA interfaces, and multi-tabbed browsing support using conversation scoped components.  Personally I'm interested in reading about the new(ish) Identity Manager API (which I haven't played with yet) and trying to add OpenID support for the application I am currently building.</p>
<p>You can read the second chapter online here: <a href="http://www.packtpub.com/files/seam-2-x-web-development-sample-chapter-2-developing-seam-applications.pdf">Chapter 2: Developing Seam Applications</a> and let me know what you think of it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-2x-web-development.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MSSQL, jTDS, NVARCHAR and Slow Indexes</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html#comments</comments>
		<pubDate>Sun, 24 May 2009 04:02:50 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=423</guid>
		<description><![CDATA[An application I've built is going into production soon.  It's the first application I've been involved with which will be using MSSQL server in production, I have some learning about MSSQL to do.  After some research, I ended up using the  jDTS JDBC driver instead of the Microsoft JDBC driver (which is [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_424" class="wp-caption alignright" style="width: 250px"><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/05/1276854575_6aa8a88b40_mjpg.jpeg"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/05/1276854575_6aa8a88b40_mjpg.jpeg" alt="Mr. Slow" title="Mr. Slow" width="240" height="238" class="size-full wp-image-424" /></a><p class="wp-caption-text">Mr. Slow by <a href='http://www.flickr.com/photos/vox/'>Vox</a></p></div>
<p>An application I've built is going into production soon.  It's the first application I've been involved with which will be using MSSQL server in production, I have some learning about MSSQL to do.  After some research, I ended up using the <a href="http://jtds.sourceforge.net/"> jDTS JDBC driver</a> instead of the Microsoft JDBC driver (which is feature incomplete and has some serious open issues).  </p>
<p>We recently began performance testing and saw some odd behavior.  Initially the application was performing well.  However after few runs of the stress test the performance went from good to awful.  The main web service call went from 600 ms to 23,000 ms.  The database server's CPU was pinned, and the app servers were barely loading, spending all their time waiting for the database server to return queries.  Stranger still, my local instance (running against PostgreSQL) performed well with the same code and same stress tests.  Luckily a smart MSSQL DBA was able to figure out why the database was burning so much CPU and responding so slowly.</p>
<p>One of the primary queries is against a table which has been growing.  The select query is simple and had an indexed column in the WHERE clause.  Even as the table grew to over a million rows, it should have been a very quick query.  Unfortunately it was taking several seconds to complete.  My local instance had over 30 million rows in the same table in PostgreSQL and the query was lightening fast.  The DBA discovered that the query execution was converting the indexed varchar column into nvarchar values for comparison with the query parameter used in the WHERE clause which was inexplicably coming over as an nvarchar.  This datatype mismatch between the column definition and the query parameter meant that MSSQL was doing a scan of the million+ record index instead of the almost instant seek it should have been doing.  </p>
<p>It turns out that jTDS sends String parameters over as Unicode (nvarchar) by default.  It's easily fixed by adding this property to your connection-url:</p>
<pre class="brush: plain">
sendStringParametersAsUnicode=false
</pre>
<p>That immediately fixed the performance issues.  </p>
<p>So, if you're using jTDS and are using indexed varchar columns in your queries, you should add the property above to avoid your indexes being wasted and your queries running slowly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Environment specific mail auth and Seam&#8217;s MailSession</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/environment-specific-mail-auth-and-seams-mailsession.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/environment-specific-mail-auth-and-seams-mailsession.html#comments</comments>
		<pubDate>Wed, 20 May 2009 02:13:32 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Seam]]></category>
		<category><![CDATA[email]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=416</guid>
		<description><![CDATA[If you are using Seam's MailSession to send out going e-mail from your Seam application you can run into trouble if you have a mail server in any environment (dev, test, stage, prod) that allows outgoing mail based on the client's IP address and does not use username and password based authentication.  
The standard [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using Seam's MailSession to send out going e-mail from your Seam application you can run into trouble if you have a mail server in any environment (dev, test, stage, prod) that allows outgoing mail based on the client's IP address and does not use username and password based authentication.  </p>
<p>The standard configuration for the MailSession is in the components.xml file and looks like this (if you've used SeamGen to create your project):</p>
<pre class="brush: xml">
	&lt;mail:mail-session host=&quot;@mailhost@&quot; port=&quot;@mailport@&quot; username=&quot;@mailusername@&quot; password=&quot;@mailpassword@&quot; /&gt;
</pre>
<p>Then each of your environments has a components-{env}.properties file, which is deployed out and used to populate the @variable@ placeholders in the components.xml file.  For instance your components.dev.properties file might look like this:</p>
<pre class="brush: plain">
jndiPattern=YourApp/#{ejbName}/local
debug=true
mailhost=mail.mydomain.com
mailport=25
mailusername=mailus3r
mailpassword=mailp4ss
</pre>
<p>Which works great.  However, if for instance your production environment uses IP based mail authentication for outbound e-mail, you might try to set your components-prod.properties file to look like this:</p>
<pre class="brush: plain">
jndiPattern=YourApp/#{ejbName}/local
debug=false
mailhost=prodmail.mydomain.com
mailport=25
mailusername=
mailpassword=
</pre>
<p>However, that ends up setting empty strings into the username and password member variables of the MailSession component, and unfortunately the logic which determines whether or not to authenticate with the mail server checks for nulls only.  So with empty strings, it attempts to authenticate with the mail server using a blank username and password.  Which fails, and causes an unhelpful Faces error (unless you turn on debug on the MailSession component).</p>
<p>I've logged a Jira ticket about it here: <a href="https://jira.jboss.org/jira/browse/JBSEAM-4176">JBSEAM-4176</a></p>
<p>You can do a simple workaround by overriding the MailSession component with your own sub-class of the MailSession class.  In your sub-class you can override the setUsername and setPassword methods, check for empty strings and set null into the member variable if the parameter is null or empty.  Luckily the Seam Install precedence system makes it very easy to override the default Seam component.</p>
<pre class="brush: java">
package com.myapp.mail;

import static org.jboss.seam.ScopeType.APPLICATION;

import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

/**
 * The Class MailSession. This is an overriding class designed to work around
 * https://jira.jboss.org/jira/browse/JBSEAM-4176
 */
@Name(&quot;org.jboss.seam.mail.mailSession&quot;)
@Install(precedence = org.jboss.seam.annotations.Install.APPLICATION, classDependencies = &quot;javax.mail.Session&quot;)
@Scope(APPLICATION)
@BypassInterceptors
public class MailSession extends org.jboss.seam.mail.MailSession {

    @Override
    public void setPassword(String pPassword) {
	if (pPassword == null || pPassword.trim().length() == 0) {
	    super.setPassword(null);
	} else {
	    super.setPassword(pPassword);
	}
    }

    @Override
    public void setUsername(String pUsername) {
	if (pUsername == null || pUsername.trim().length() == 0) {
	    super.setUsername(null);
	} else {
	    super.setUsername(pUsername);
	}
    }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/environment-specific-mail-auth-and-seams-mailsession.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing an SSD in a MacBookPro</title>
		<link>http://www.digitalsanctuary.com/tech-blog/apple/installing-an-ssd-in-a-macbookpro.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/apple/installing-an-ssd-in-a-macbookpro.html#comments</comments>
		<pubDate>Sat, 16 May 2009 01:38:11 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Apple]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=412</guid>
		<description><![CDATA[I just replaced my 17" Unibody MacBookPro's hard drive with a new Corsair 256GB SSD.  The SSD uses Samsung chips and controller.  It's VERY FAST!

First I made an image of my BootCamp partition using WinClone.
Next I ran one final Time Machine backup to my Time Capsule.
After that was complete, I shut the machine [...]]]></description>
			<content:encoded><![CDATA[<p>I just replaced my 17" Unibody MacBookPro's hard drive with a new Corsair 256GB SSD.  The SSD uses Samsung chips and controller.  It's <a href="http://www.guru3d.com/news/corsair-ultra-fast-256-gb-ssd-perf-surfaces/">VERY FAST</a>!</p>
<ol>
<li>First I made an image of my BootCamp partition using WinClone.</li>
<li>Next I ran one final Time Machine backup to my Time Capsule.</li>
<li>After that was complete, I shut the machine down.</li>
<li>I swapped the new hard drive for the old one.  <a href="http://support.apple.com/kb/HT3419">Apple has a great guide on how to replace the hard drive in the laptop</a>.  The SSD is MUCH lighter than the OEM hard drive.</li>
<li>I booted up with the Leopard OS X Install DVD.</li>
<li>I selected the disk utility from the menu, and formatted the new hard drive with an HFS+ partition.</li>
<li>I then had to reboot in order for the new partition to show up under the Restore option.</li>
<li>After rebooting to the Install DVD again, select the Restore option from the menu, and select your most recent Time Machine backup.  The step where it's calculating the size of the backup can take a VERY long time.  Be patient.  The restore itself can take a while.  My 220 GB took about 8 hours to restore.</li>
<li>Now you should be able to boot into your system from the new hard drive.</li>
<li>If you don't use BootCamp you can skip these steps:
<ol>
<li>Run the Boot Camp Assistant and recreate the Boot Camp partition.  Make sure it's the same size or larger than your previous one.</li>
<li>Start the Windows installation process using your WIndows install CD/DVD.  Make sure you format the Boot Camp partition.  Once it starts actually installing Windows, you can force a shut down.</li>
<li>Boot back into OS X, and use WinClone to restore your Boot Camp image to the partition on the SSD.</li>
</ol>
</li>
</ol>
<p>It's like having a new machine.  Booting used to take 60-90 seconds from off to 100% up and ready, including Quicksilver loading up, etc...  Now it takes about 5 seconds.  Applications load pretty much instantly, without bouncing in the dock.  Shutdowns and sleep happen instantly.  The whole machine feels amazingly faster.</p>
<p>It's not the cheapest thing, but it's a very worthwhile upgrade.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/apple/installing-an-ssd-in-a-macbookpro.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>ATG SEO &#8211; Tools and Traffic</title>
		<link>http://www.digitalsanctuary.com/tech-blog/debian/atg-seo-tools-and-traffic.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/debian/atg-seo-tools-and-traffic.html#comments</comments>
		<pubDate>Mon, 04 May 2009 13:52:04 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[ATG]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=406</guid>
		<description><![CDATA[SEO Tools
Other than using lynx to test your site, there are several other tools I would recommend utilizing in your quest for better SEO.  One great tool is the SEO Analysis Tool from SEOWorkers.com.  This tool quickly analyzes the page, and provides excellent reports on the size and relevancy of your meta tags. [...]]]></description>
			<content:encoded><![CDATA[<h2>SEO Tools</h2>
<p>Other than using lynx to test your site, there are several other tools I would recommend utilizing in your quest for better SEO.  One great tool is the <a href="http://www.seoworkers.com/tools/analyzer.html">SEO Analysis Tool from SEOWorkers.com</a>.  This tool quickly analyzes the page, and provides excellent reports on the size and relevancy of your meta tags.  It also provides data on the frequency of keywords, singly and in groups of two and three.  Here is a part of the a report for <a href="http://sparkred.com">sparkred.com</a>:</p>
<p><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/04/picture-12.png"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/04/picture-12-550x440.png" alt="Google Webmaster Tools for SparkRed.com" title="Google Webmaster Tools for SparkRed.com" width="550" height="440" class="aligncenter size-medium wp-image-407" /></a></p>
<p>I've already mentioned utilizing Google Analytics to monitor what keywords are bringing you good traffic versus bad.  I'd also recommend another Google tool, <a href="https://www.google.com/webmasters/tools/">Google Webmaster Tools</a>.  Google provides a TON of useful data here.  You can see things like the crawl frequency, page response times during the crawl, and page rank of your pages (including a by month breakdown).  You can also use quick links to see related pages, pages which link in to your site, all the indexed pages of your site, and more.  It also gives you diagnostics into any problems with the crawl or your meta tags.  </p>
<h2>How to Promote Your Site</h2>
<p>In order to drive traffic to your site and to increase your ranking in search engines, such as your Google Page Rank, you want high quality links pointing to your site.  By high quality links I <strong>don't</strong> mean spam links, link farms, or the like.  I mean links on relevant sites pointing your site, driving high quality traffic.</p>
<p>There are two halves to this.  The first is to provide really good quality content on your site.  This means having a great site, it means updating your site frequently, and it means providing non-core but helpful related content.  An example of that might be having a blog that provides related content.  For instance for MyShoeStore.com you might have a blog with posts about the latest fashions and how to match shoes to each look, the best sales you're currently running, the 10 most extreme shoes of all time, photos of the shoes worn by celebrities that week, etc...  You want something that will have people returning to visit your site more frequently, and something that will make other people link to your site in their blogs, tweets, Facebook pages, IMs to friends, and so forth.  If you have a blog post about the shoes on the red carpet at the People's Choice awards, people will link to that from tons of forums discussing fashion.  Those a great links!  Relevant high quality links bringing in high quality traffic.  And you just need a blogger.  A college fashionista who wants to get into fashion journalism will do it for cheap.</p>
<p>The second is to promote your site on other sites.  Find forums and communities that are filled with the people you want to attract to your site, signup, and contribute to the community conversation.  Note I didn't say spam the community.  Post useful stuff.  Even stuff that links to sites that aren't yours.  Be a real contributing helpful member of the site.  In your site profile, have a link to your site, and when it's relevant feel free to link to your site, your latest sale, whatever, as long as it's relevant.  Obviously if you're an ATG developer or a VP of IT, it's probably not you doing all this, but have someone do it.</p>
<p>Those two things are how you get traffic and a high page ranking in the search engines.  It's all about having good content and being an upstanding citizen of the relevant online communities.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/debian/atg-seo-tools-and-traffic.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ATG SEO &#8211; URL Formats and Crawler Limits</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/atg-seo-url-formats-and-crawler-limits.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/atg-seo-url-formats-and-crawler-limits.html#comments</comments>
		<pubDate>Fri, 01 May 2009 15:05:27 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ATG]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=401</guid>
		<description><![CDATA[URL Formats and Structures
By making your URLs expressive and relevant to the content and structure of the site, you help not only your search engine ranking but also your users, since they can easily tell what a given link will take them to.
This is a bad URL:

http://myshoestore.com/app/cat/browse.jsp?id=245345&#38;cat=234523

This is a good URL:

http://myshoestore.com/shop/mens-shoes/fluevog/size-12

It is chock full of [...]]]></description>
			<content:encoded><![CDATA[<h2>URL Formats and Structures</h2>
<p>By making your URLs expressive and relevant to the content and structure of the site, you help not only your search engine ranking but also your users, since they can easily tell what a given link will take them to.</p>
<p>This is a bad URL:</p>
<pre class="brush: html">
http://myshoestore.com/app/cat/browse.jsp?id=245345&amp;cat=234523
</pre>
<p>This is a good URL:</p>
<pre class="brush: html">
http://myshoestore.com/shop/mens-shoes/fluevog/size-12
</pre>
<p>It is chock full of descriptive words. The page allows you to "shop" for "mens shoes", more specifically "fluevogs" in "size 12". This makes it much easier for search engines to know the purpose of the page and also for users to know what a link will take them to.</p>
<p>In order to accomplish this, you should name your directories and pages as accurately and descriptively as possible. You should also structure your site's content and URLs in a logical hierarchical fashion.</p>
<p>Now your site may have a single actual JSP that handles displaying a category, and another one that handles displaying a product, any product. So you need to map the URL http://myshoestore.com/shop/mens-shoes/fluevog/size-12 to actually serve up the content from http://myshoestore.com/app/cat/browse.jsp?id=245345&cat=234523.</p>
<p>Depending on your technology there are different ways to do this.</p>
<p>If you're using JBoss Seam it's very easy to use rewrite patterns in the pages.xml mapping file. This not only handles mapping the incoming requests for pretty URLs to the actual resources on the backend, but also handles generating the pretty URLs within the site automatically, which is a huge time saver.</p>
<p>If you're using Apache you can use mod_rewrite to translate the pretty requested URLs to the ugly actual URLs. Of course in that case you need to ensure you're generating the correct pretty URLs on the pages of your site.</p>
<p>If you're using ATG you should read the chapter of the ATG Programmers Guide titled Search Engine Optimization (chapter 10 for ATG 2006.3). This covers the ATG support for URL Templates and the Jump Servlet. A few of the downsides to be aware of, are that it's not super simple to set up, and that it only displays the pretty URLs to search engines, not to all users. I really prefer solutions that give users the benefits of readable URLs as well. The out of the box ATG system has too much of a performance impact to use for all situations.</p>
<p>We'll be releasing a high performance open source solution for URL re-writing in ATG eCommerce applications as part of the <a href="http://developer.sparkred.com/confluence/display/ATGDC/Foundation">Open Source Foundation ATG eCommerce Framework</a> in the near future. </p>
<h2>Know Your Limits</h2>
<p>Search engine spiders, like the GoogleBot, have limits as to what they'll parse and consider. For instance the GoogleBot will only read in the first ~101kb of your page's HTML. Anything after that is ignored. So you need to ensure that your pages are smaller than 101kb. This is also a best practice with regards to performance: keep your HTML as small as possible.</p>
<p>Search engines will often display a small chunk of text with the search results, usually this is taken from the page's description meta tag. Most will only show the first 160 characters of the description, so you want to be sure that your description content is less than 160 characters and makes sense for a human to read.</p>
<p>Many search engines will ignore, or penalize you, for having more than 100 links on a given page. Keep the number of links on a single page to a reasonable level. If your primary navigation must have more than 100 links, you can load in the second, third, etc... level navigation via AJAX/Javascript.. This will let your users have access to the full navigation structure from any page, but keeps things more reasonable for the search engine crawler. You'll want to be sure that the crawler will be able to traverse through the complete site structure using the more limited navigational options it can see, the non-AJAX navigation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/atg-seo-url-formats-and-crawler-limits.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ATG SEO &#8211; Accessibility and GoogleBot</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/atg-seo-accessibility-and-googlebot.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/atg-seo-accessibility-and-googlebot.html#comments</comments>
		<pubDate>Wed, 29 Apr 2009 16:10:52 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ATG]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[GoogleBot]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=396</guid>
		<description><![CDATA[Semantic Tags
Use the right tags for the job.  For high importance headings use &#60;h1&#62;, for lists use &#60;li&#62;, and so on.  Don't JUST use CSS classes for styling, make sure you're also using the appropriate HTML markup for your content. By using semantic markup you can identify the importance and structure of the [...]]]></description>
			<content:encoded><![CDATA[<h2>Semantic Tags</h2>
<p>Use the right tags for the job.  For high importance headings use &lt;h1&gt;, for lists use &lt;li&gt;, and so on.  Don't JUST use CSS classes for styling, make sure you're also using the appropriate HTML markup for your content. By using semantic markup you can identify the importance and structure of the content and data on the page in a way that not only assists search engine crawlers, like GoogleBot, understand your content better, but also supports alternate browsers/web clients such as screen readers, other accessibility tools, and future applications.</p>
<h2>Accessibility</h2>
<p>By designing your site to be easily accessible to search engines, you also end up making it accessible to people with disabilities such as the blind or vision limited. Or you can look at it the other way: by designing your site to be accessible to people with disabilities and to be WAI or 508 compliant, you end up with an excellent site for search ranking.</p>
<p>It can often be hard to justify the cost and effort to make your site 508 compliant, even if it's a legal requirement, however if you view it as a SEO effort, it's much easier to assert a strong ROI on the project, and kill two birds with one stone.</p>
<p>You can read more about accessibility here:</p>
<ul>
<li><a href="http://www.afhill.com/blog/accessibility/" target="_new">Andrea Hill's Blog</a></li>
<li><a href="http://www.w3.org/WAI/" target="_new">WAI Homepage</a></li>
<li><a href="http://en.wikipedia.org/wiki/Web_accessibility" target="_new">Web Accessibility entry on Wikipedia</a></li>
</ul>
<h2>Standards</h2>
<p>Be sure you're following standards and best practices around your markup. This includes having nicely structured, valid, HTML/XHTML markup, and also being sure you have accurate helpful alt and title tags on your links, images, and other dom elements.</p>
<h2>See what GoogleBot sees</h2>
<p>First you have to be able to see the page the way GoogleBot sees it. The easiest way is to use a text based web browser like <a href="http://en.wikipedia.org/wiki/Links_(web_browser)">links</a> or <a href="http://en.wikipedia.org/wiki/Lynx_(web_browser)">lynx</a>.  GoogleBot is actually a customized version of lynx, and supposedly has been/is being improved to be able to cull some data out of Flash, and possibly even some Javascript driven content, however it's best to assume that what lynx shows you is what GoogleBot sees. </p>
<p>You'll want to design your page structure and dom tree to be logical in order, structure, and semantic. Here is a view of CNN.com in lynx:<br />
<div id="attachment_347" class="wp-caption aligncenter" style="width: 560px"><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/04/picture-1.png"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/04/picture-1-550x385.png" alt="The CNN.com homepage viewed using the lynx browser" title="Cnn.com under lynx" width="550" height="385" class="size-medium wp-image-347" /></a><p class="wp-caption-text">The CNN.com homepage viewed using the lynx browser</p></div></p>
<p>It's extremely usable. You can see the main navigation first thing, and if you scroll down you see the main headline stories, latest news, etc... This is what you want your site to look like to GoogleBot.</p>
<p>In contrast, here is what a large theatre's website looks like in lynx:?<br />
<a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/04/theatre.png"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/04/theatre-550x465.png" alt="theatre" title="theatre" width="550" height="465" class="aligncenter size-medium wp-image-371" /></a></p>
<p>The primary navigation on the real site doesn't even appear here. The images don't have titles or alt tags, and the structure is lacking and confusing. This is NOT what you want your site to look like to GoogleBot.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/atg-seo-accessibility-and-googlebot.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
