<?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>The Usware Blog - Django Web Development &#187; seo</title>
	<atom:link href="http://uswaretech.com/blog/category/seo/feed/" rel="self" type="application/rss+xml" />
	<link>http://uswaretech.com/blog</link>
	<description>Building Amazing Webapps</description>
	<lastBuildDate>Tue, 08 Jun 2010 14:59:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Generating pseudo random text with Markov chains using Python</title>
		<link>http://uswaretech.com/blog/2009/06/pseudo-random-text-markov-chains-python/</link>
		<comments>http://uswaretech.com/blog/2009/06/pseudo-random-text-markov-chains-python/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 05:07:16 +0000</pubDate>
		<dc:creator>shabda</dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://uswaretech.com/blog/?p=536</guid>
		<description><![CDATA[First the definition from Wolfram A Markov chain is collection of random variables {X_t} (where the index t runs through 0, 1, &#8230;) having the property that, given the present, the future is conditionally independent of the past. Wikipedia is a little clearer &#8230;Markov chain is a stochastic process with markov property &#8230; [Which means] [...]


Related posts:<ol><li><a href='http://uswaretech.com/blog/2009/03/finding-keywords-using-python/' rel='bookmark' title='Permanent Link: Finding keywords using Python'>Finding keywords using Python</a></li>
<li><a href='http://uswaretech.com/blog/2008/10/generating-pdfs-with-django/' rel='bookmark' title='Permanent Link: Generating PDFs with Django'>Generating PDFs with Django</a></li>
<li><a href='http://uswaretech.com/blog/2009/03/constraint-programming-in-python/' rel='bookmark' title='Permanent Link: Constraint programming in Python'>Constraint programming in Python</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p>First the definition from <a href="http://mathworld.wolfram.com/MarkovChain.html">Wolfram</a></p>

<blockquote>
A Markov chain is collection of random variables {X_t} (where the index t runs through 0, 1, &#8230;) having the property that, given the present, the future is conditionally independent of the past.
</blockquote>

<p><a href="http://en.wikipedia.org/wiki/Transition_probabilities">Wikipedia</a> is a little clearer</p>

<blockquote>
 &#8230;Markov chain is a stochastic process with markov property &#8230; [Which means] state changes are probabilistic, and future state depend on current state only.
</blockquote>

<p>Markov chains have various uses, but now let&#8217;s see how it can be used to generate
gibberish, which might look legit.</p>

<p>The algorithm is,</p>

<ol>
<li>Have a text which will serve as the corpus from which we choose the next
transitions.</li>
<li>Start with two consecutive words from the text. The last two words constitute
the present state.</li>
<li>Generating next word is the markov transition. To generate the next word, look
in the corpus, and find which words are present after the given two words. Choose
one of them randomly.</li>
<li>Repeat 2, until text of required size is generated.</li>
</ol>

<p>The code for this is</p>

<script src="http://gist.github.com/131679.js"></script>

<p>To see a sample output, we take the text of <em>My man jeeves</em> by Wodehouse from
<a href="http://www.gutenberg.org/etext/8164">Project Gutenberg</a>, and see a sample output.</p>

<pre><code>In [1]: file_ = open('/home/shabda/jeeves.txt')

In [2]: import markovgen

In [3]: markov = markovgen.Markov(file_)

In [4]: markov.generate_markov_text()
Out[4]: 'Can you put a few years of your twin-brother Alfred,
who was apt to rally round a bit. I should strongly advocate
the blue with milk'
</code></pre>

<p>[The files you need to run this are <a href='http://uswaretech.com/blog/wp-content/uploads/2009/06/jeeves.txt'>jeeves.txt</a> and <a href='http://uswaretech.com/blog/wp-content/uploads/2009/06/markovgenpy.txt'>markovgen.py</a>]</p>

<h3>How is this a markov algorithm?</h3>

<ul>
<li>The last two words are the current state.</li>
<li>Next word depends on last two words only, or on <em>present state</em> only.</li>
<li>The next word is <em>randomly chosen</em> from a statistical model of the corpus.</li>
</ul>

<p>Here is some sample text.</p>

<p>&#8220;The quick brown fox jumps over the brown fox who is slow jumps over the brown
fox who is dead.&#8221;</p>

<p>This gives us a corpus like,</p>

<pre><code>{('The', 'quick'): ['brown'],
 ('brown', 'fox'): ['jumps', 'who', 'who'],
 ('fox', 'jumps'): ['over'],
 ('fox', 'who'): ['is', 'is'],
 ('is', 'slow'): ['jumps'],
 ('jumps', 'over'): ['the', 'the'],
 ('over', 'the'): ['brown', 'brown'],
 ('quick', 'brown'): ['fox'],
 ('slow', 'jumps'): ['over'],
 ('the', 'brown'): ['fox', 'fox'],
 ('who', 'is'): ['slow', 'dead.']}
</code></pre>

<p>Now if we start with &#8220;brown fox&#8221;, the next word can be &#8220;jumps&#8221; or &#8220;who&#8221;. If we
 choose &#8220;jumps&#8221;, then the current state is &#8220;fox jumps&#8221; and next word is over,
 and so on.</p>

<h3>Hints</h3>

<ul>
<li>The larger text we choose, the more choices are there at each transition, and
a better looking text is generated.</li>
<li>The state can be set to depend on one word, two words, or any number of words.
As the number of words in each state increases, the generated text becomes less
random.</li>
<li>Don&#8217;t strip the punctuations etc. They lead to a more representative corpus,
and a better random text.</li>
</ul>

<h3>Resources</h3>

<ul>
<li><a href='http://uswaretech.com/blog/wp-content/uploads/2009/06/jeeves.txt'>jeeves.txt</a></li>
<li><a href='http://uswaretech.com/blog/wp-content/uploads/2009/06/markovgenpy.txt'>markovgen.py</a></li>
<li><a href="http://www.yisongyue.com/shaney/">Online markov text generator</a></li>
<li><a href="www.yaymukund.com/twittov/">Twitter markov script</a></li>
</ul>

<hr />

<p>Did you know that markov chains have many other uses in finance, statistics and mathematics? In fact Google&#8217;s page rank algorithm is essentially a markov chain of the web! We publish articles on Algorithms, Python, Django and related technologies every week. Why not <a href="http://feeds.feedburner.com/UswareBlog">Subscribe to us</a> or <a href="http://twitter.com/uswaretech">follow us on twitter</a>?</p>


<p>Related posts:<ol><li><a href='http://uswaretech.com/blog/2009/03/finding-keywords-using-python/' rel='bookmark' title='Permanent Link: Finding keywords using Python'>Finding keywords using Python</a></li>
<li><a href='http://uswaretech.com/blog/2008/10/generating-pdfs-with-django/' rel='bookmark' title='Permanent Link: Generating PDFs with Django'>Generating PDFs with Django</a></li>
<li><a href='http://uswaretech.com/blog/2009/03/constraint-programming-in-python/' rel='bookmark' title='Permanent Link: Constraint programming in Python'>Constraint programming in Python</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://uswaretech.com/blog/2009/06/pseudo-random-text-markov-chains-python/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>AJAX &amp; SEO</title>
		<link>http://uswaretech.com/blog/2009/03/ajax-seo/</link>
		<comments>http://uswaretech.com/blog/2009/03/ajax-seo/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 04:53:22 +0000</pubDate>
		<dc:creator>Rama Vadakattu</dc:creator>
				<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://uswaretech.com/blog/2009/03/ajax-seo/</guid>
		<description><![CDATA[In today&#8217;s web world&#160; we can’t underestimate the importance of search engine traffic to a website.As this traffic plays a key role we must take care that our web pages are also search engine friendly. WebPages in which the content is constructed and displayed&#160; by AJAX is not search engine friendly.Such content is not accessible [...]


Related posts:<ol><li><a href='http://uswaretech.com/blog/2008/10/building-seo-optimised-django-web-applications/' rel='bookmark' title='Permanent Link: Building SEO optimised Django web applications'>Building SEO optimised Django web applications</a></li>
<li><a href='http://uswaretech.com/blog/2008/04/parable-of-the-nofollow/' rel='bookmark' title='Permanent Link: Parable of the nofollow'>Parable of the nofollow</a></li>
<li><a href='http://uswaretech.com/blog/2008/04/parable-of-the-captcha-the-futility-of-fighting-automated-spam-with-automated-methods/' rel='bookmark' title='Permanent Link: Parable of the Captcha &#8211; The futility of fighting automated spam with automated methods.'>Parable of the Captcha &#8211; The futility of fighting automated spam with automated methods.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p><a href="http://uswaretech.com/blog/wp-content/uploads/2009/03/image.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="180" alt="image" src="http://uswaretech.com/blog/wp-content/uploads/2009/03/image-thumb.png" width="240" align="right" border="0" /></a> In today&#8217;s web world&#160; we can’t underestimate the importance of search engine traffic to a website.As this traffic plays a key role we must take care that our web pages are also search engine friendly.</p>

<p>WebPages in which the content is constructed and displayed&#160; by AJAX is not search engine friendly.Such content is not accessible to the crawler , as the result those pages are&#160; not indexed in the search engines&#160; by which we may miss a certain amount of traffic from a search engine.</p>

<p>So before using AJAX on a webpage for displaying content you must aware of the following:</p>

<p>1) The content displayed by AJAX is not search engine friendly and is not indexed by search engines.</p>

<p>if you feel such content to be search engine friendly use normal webpages instead of pages powered by AJAX.</p>

<p><strong>please note that you can still use AJAX for displaying&#160; items in a webpage other than content like forms,sliders etc</strong>… for improving&#160; user communication without losing&#160; search engine friendliness of a page.</p>


<p>Related posts:<ol><li><a href='http://uswaretech.com/blog/2008/10/building-seo-optimised-django-web-applications/' rel='bookmark' title='Permanent Link: Building SEO optimised Django web applications'>Building SEO optimised Django web applications</a></li>
<li><a href='http://uswaretech.com/blog/2008/04/parable-of-the-nofollow/' rel='bookmark' title='Permanent Link: Parable of the nofollow'>Parable of the nofollow</a></li>
<li><a href='http://uswaretech.com/blog/2008/04/parable-of-the-captcha-the-futility-of-fighting-automated-spam-with-automated-methods/' rel='bookmark' title='Permanent Link: Parable of the Captcha &#8211; The futility of fighting automated spam with automated methods.'>Parable of the Captcha &#8211; The futility of fighting automated spam with automated methods.</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://uswaretech.com/blog/2009/03/ajax-seo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building SEO optimised Django web applications</title>
		<link>http://uswaretech.com/blog/2008/10/building-seo-optimised-django-web-applications/</link>
		<comments>http://uswaretech.com/blog/2008/10/building-seo-optimised-django-web-applications/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 16:59:44 +0000</pubDate>
		<dc:creator>shabda</dc:creator>
				<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://uswaretech.com/blog/?p=31</guid>
		<description><![CDATA[This is an article about building SEO, optmised web applications with Django. I assume you already have an idea how Seo works. We will take the example of a hypothetical Blog app to explain the suggestions made. Without further ado, here are the tips. Basic Use beautiful URLs. Learn the difference between HTTP 301 and [...]


Related posts:<ol><li><a href='http://uswaretech.com/blog/2009/03/ajax-seo/' rel='bookmark' title='Permanent Link: AJAX &amp; SEO'>AJAX &amp; SEO</a></li>
<li><a href='http://uswaretech.com/blog/2008/04/new-tutorial-building-a-search-engine-with-appengine-and-yahoo/' rel='bookmark' title='Permanent Link: New tutorial &#8211; Building a search engine with Appengine and Yahoo'>New tutorial &#8211; Building a search engine with Appengine and Yahoo</a></li>
<li><a href='http://uswaretech.com/blog/2008/11/building-reusable-django-apps/' rel='bookmark' title='Permanent Link: Building reusable Django apps'>Building reusable Django apps</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p></p><p>This is an article about building <a href="http://www.seobook.com/glossary/#seo">SEO</a>, optmised web applications with Django. I assume you already have an idea how Seo works. We will take the example 
of a hypothetical Blog app to explain the suggestions made.</p>

<p>Without further ado, here are the tips.</p>

<p>Basic</p>

<ol>
<li>Use beautiful URLs.</li>
<li>Learn the difference between HTTP 301 and HTTP 302 redirects.</li>
<li>Layout content in a SEO friendly way.</li>
<li>Create a sitmaps.</li>
</ol>

<p>Not so obvious</p>

<ol>
<li>Use the Admin to allow end users to update fields.</li>
<li>Do not get your Url structures too deep.</li>
<li>Create a robots.txt file. </li>
<li>Link to your pages wisely.</li>
<li>Minimise duplicate content.</li>
<li>Ping Google when your site gets updated.</li>
</ol>

<h2>Basic tips.</h2>

<p>If you are building a production web app, you should really be using these techniques.</p>

<h3>Use beautiful URLs.</h3>

<p>Say our app has a model like,</p>

<pre><code>class Entry(models.Model):
      title = models.CharField(max_length = 100)
      body = models.TextField()
</code></pre>

<p>It would be very tempting to have Urls like /entry/15/, and map this url to the entry with PK 15. Resist this temptation. Search Engines need help to decide what a page is about, and the Urls plays a
major part in that. Instead we want the Url to depend on the title.</p>

<pre><code>class Entry(models.Model):
      title = models.CharField(max_length = 100)
      body = models.TextField()
      slug = models.SlugField()

      def save(self):
        self.slug = '-'.join(self.title.split())#And clean title, and make sure this is unique.
        super(Entry, self).save()
</code></pre>

<p>Then we can use slug, and have Urls like /entry/seo-tips-for-django/</p>

<p>Read more:<br />
[1]: <a href="http://www.seomoz.org/blog/dynamic-urls-vs-static-urls-the-best-practice-for-seo-is-still-clear">Dynamic URLs vs. Static URLs</a></p>

<h3>Learn the difference between HTTP 301 and HTTP 302 redirects.</h3>

<p>A HTTP 301 redirects says that the url currently being accessed has moved permanenetly, while a HTTP 302 is temporary redirect which asks search engines to try the same url next time. In Django a Http 301
maps to HttpResponsePermanenetRedirect, and a HTTP 302 maps to HttpResponseRedirect. A 301 redirect makes the search engines count the links pointing to a old Url for the new Url.</p>

<p>Suppose our old Url was /entry/seo-tips-for-django/, and we edited the title to &#8220;Best SEO tips for Django&#8221;, and want the new url to be /entry/best-seo-tips-for-django/. Now as <a href="http://www.w3.org/Provider/Style/URI">&#8220;Cool URIs Do not change&#8221;</a>, we want
to do an redirect from  /entry/seo-tips-for-django/ to /entry/best-seo-tips-for-django/. As some people may have already linked to /entry/seo-tips-for-django/, we want a HttpResponsePermananentRedirect here.</p>

<h3>Layout content in a SEO friendly way.</h3>

<p>Django gives you complete control over how your Html will appear. Use this to your advantage.</p>

<p>Search engines give more weight to the content which appears earlier in a page layout. So layout your page where the the content area appears before the footer, and then layout your pages using CSS.</p>

<p>For example the first base template is better than second,</p>

<pre><code>&lt;body&gt;
{% block content %}
{% endblock %}
{% block sidebar %}
{% endblock %}
{% block footer %}
{% endblock %}
&lt;/body&gt;


&lt;body&gt;
{% block footer %}
{% endblock %}
{% block sidebar %}
{% endblock %}
{% block content %}
{% endblock %}
&lt;/body&gt;
</code></pre>

<h3>Create a sitmaps.</h3>

<p>Django comes with a wonderful <a href="http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/">Sitemaps framework</a>. Use this to generate a Sitemap for all our dynamic pages.</p>

<p>Here is the all the code you need to generate the sitemap for our Entries, taken directly from <a href="(http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/)">Django Sitemaps page</a>, and it works perfectly.
Plus this is your urls.py and you have a shiny xml sitemap ready.</p>

<p>Read More<br />
[1]: <a href="http://en.wikipedia.org/wiki/Site_map">Site Map</a></p>

<h3>Use the Admin to allow end users to update fields.</h3>

<p>Use the wonderful Admin interface to your advantage. For example, for /entry/seo-tips-for-django/ we can use the Admin to allow users to update the slug without updating the title.</p>

<h3>Do not get your Url structures too deep.</h3>

<p>Search Engines give more weight to pages which are closer to the root of the site. Instead of /blog/entry/2008/oct/2008/seo-tips-for-django/, prefer /entry/seo-tips-for-django/. As Django makes including urlconfs inside
other urlconfs so easy, this can lead to deeper Url structure than needed.</p>

<p>For example your Django project has a main urls.py,</p>

<p>which does,</p>

<pre><code>url(r'^blog/', include('blog.urls')),
</code></pre>

<p>and blog/urls.py does</p>

<pre><code>url(r'^search/', include('blog.searchurls')),
</code></pre>

<p>and blog/urls.py does</p>

<pre><code>url(r'^search/$', 'search_view'),
</code></pre>

<p>then your serach page will be at /blog/search/search/, when it should probably be at /search/. Include with care.</p>

<p>which includes blog/urls.py</p>

<h3>Create a robots.txt file.</h3>

<p>Use <a href="http://code.google.com/p/django-robots">Django Robots</a> to create robots,txt file for your Django site.</p>

<h3>Link to your pages wisely.</h3>

<p>Eg. When you are linking to the the entry page from main page/other page on your site use, use descriptive anchor texts. SO the permalink for our entry pages shuld not be,</p>

<pre><code>&lt;a href="{{ entry.get_absolute_url }}"&gt;Read More&lt;/a&gt;
</code></pre>

<p>But rather,</p>

<pre><code>&lt;a href="{{ entry.get_absolute_url }}"&gt;{{ entry.title }}&lt;/a&gt;
</code></pre>

<h3>Minimise duplicate content.</h3>

<p>Search engines hate duplicate content. So try not to have the same content on multiple Urls.</p>

<p>For example see this innocous looking url pattern</p>

<pre><code>urlpatterns = patterns('',
    (r'^entry/(\w+)/', 'blog.view.entry'),

    ...
</code></pre>

<p>This url pattern will match for all of /entry/seo-tips-for-django/1, /entry/seo-tips-for-django/2, /entry/seo-tips-for-django/3 and similar.</p>

<p>To make sure only /entry/seo-tips-for-django/ matches, use</p>

<pre><code>urlpatterns = patterns('',
    (r'^entry/(\w+)/$', 'blog.view.entry'),
    ...
</code></pre>

<p>On a similar note, say you have commenst for your Blog, which you want permalinks for.</p>

<p>Do not do this.</p>

<pre><code>class Comment(models.Model):
     def get_absolute_url(self):
      #You would use permalink here.
      return '/comment/%s/' % self.id # or even '/comment/%s/'  % self.slug

Instead what you want here is,

class Comment(models.Model):
     def get_absolute_url(self):
      return '%s#%s' % (self.entry.get_absolute_url(), self.id)
</code></pre>

<p>And create named anchors in your entries template. This makes sure that each comment is visible at only one Url.</p>

<h3>Ping Google when your site gets updated.</h3>

<p>You would have created a Dynamic sitemap using the sitemaps framework. SO when your content gets updated, you sitemap would get updated too. Let Google know of this using django.contrib.sitemaps.ping_google</p>

<p>from django.contrib.sitemaps import ping_google</p>

<pre><code> class Entry(models.Model):
     # ...
     def save(self, force_insert=False, force_update=False):
     super(Entry, self).save(force_insert, force_update)
     try:
         ping_google()
     except Exception:
         # Bare 'except' because we could get a variety
         # of HTTP-related exceptions.
         pass
</code></pre>

<p>http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/#pinging-google</p>

<hr />

<p>Need a web application built? <a href="http://uswaretech.com/contact/">Talk to us</a>.</p>


<p>Related posts:<ol><li><a href='http://uswaretech.com/blog/2009/03/ajax-seo/' rel='bookmark' title='Permanent Link: AJAX &amp; SEO'>AJAX &amp; SEO</a></li>
<li><a href='http://uswaretech.com/blog/2008/04/new-tutorial-building-a-search-engine-with-appengine-and-yahoo/' rel='bookmark' title='Permanent Link: New tutorial &#8211; Building a search engine with Appengine and Yahoo'>New tutorial &#8211; Building a search engine with Appengine and Yahoo</a></li>
<li><a href='http://uswaretech.com/blog/2008/11/building-reusable-django-apps/' rel='bookmark' title='Permanent Link: Building reusable Django apps'>Building reusable Django apps</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://uswaretech.com/blog/2008/10/building-seo-optimised-django-web-applications/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
