<?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>Zo&#039;C &#187; Server Side</title>
	<atom:link href="http://www.z-oc.com/blog/category/server-side/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.z-oc.com/blog</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Wed, 03 Feb 2010 15:06:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Domain redirect wizardry with .htaccess rules</title>
		<link>http://www.z-oc.com/blog/2009/01/htaccess-redirect-wizardry/</link>
		<comments>http://www.z-oc.com/blog/2009/01/htaccess-redirect-wizardry/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 17:10:47 +0000</pubDate>
		<dc:creator>guioconnor</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[domain]]></category>
		<category><![CDATA[redirect]]></category>
		<category><![CDATA[wizardry]]></category>

		<guid isPermaLink="false">http://www.z-oc.com/blog/2009/01/untitled/</guid>
		<description><![CDATA[So you decided your domain doesn&#8217;t fit you as well as you&#8217;d like. And you are also afraid you&#8217;ll be losing all the old links and search engine ranking if you move to a new one. Maybe you also want to use the current domain for a different project that suits it best. Or maybe [...]]]></description>
			<content:encoded><![CDATA[<p>So you decided your domain doesn&#8217;t fit you as well as you&#8217;d like. And you are also afraid you&#8217;ll be losing all the old links and search<br />
engine ranking if you move to a new one. Maybe you also want to use the current domain for a different project that suits it best.</p>
<p>Or maybe you just want to change the structure of your URLs or you want a different URI structure in the new domain.</p>
<p>Let&#8217;s see how to write some htaccess rules so Apache can do the magic for you.</p>
<p><span id="more-342"></span></p>
<h3>Redirect the whole domain</h3>
<p>Redirecting a whole domain with .htaccess rules is easy. All you have to do is to put the rules below in an file named .htaccess<br />
in the root directory for your old domain.</p>
<pre><code>
RewriteEngine on
RewriteRule ^(.&lowast;)$ http://www.newdomain.com/$1 [R=301,L]
</code>
</pre>
<p>Let&#8217;s see how the magic happens.</p>
<p>The first line is merely to turn on the Rewrite engine on apache and enable the rewrite rules to be interpreted.</p>
<p>The second line is composed of 4 parts.</p>
<ol>
<li>The RewriteRule keyword</li>
<li>A regular expression (regex) to match the original URI</li>
<li>The URI to be redirected to and </li>
<li>Parameters</li>
</ol>
<p>The regular expression in this case is <code>^(.*)$</code>. The dot, in a regular expression matches a character, any character except the newline.<br />
That means that any letter, number or symbol container in a URL will be matched. The asterisk <code>(&lowast;)</code> means that you want to repeat the regex it affects<br />
zero or more times.</p>
<p>Simply put, <code>(.&lowast;)</code> matches any amount of non-newline characters, including zero.</p>
<p>Additionally, the carat <code>(^)</code> represents the start of a line and the dollar sign <code>($)</code> represents the end, so the whole expression<br />
matches a line of zero or more non-newline characters, i.e., the whole path of your URI inside your domain.</p>
<p>The third part is the URI to redirect to. As you see, is pretty straightforward, the only tricky bit is the <code>$1</code>.</p>
<p>The reason for it is that you don&#8217;t want to redirect any URI in the old domain to the root of your new domain. What you want is to redirect<br />
each page for the equivalent in the new one. For instance this URI</p>
<pre><code>http://www.oldomain.com/path/to/page</code></pre>
<p>Should redirect to</p>
<pre><code>http://www.newomain.com/path/to/page</code></pre>
<p>Now, for every regular expression inside parenthesis the text it matches is stored for use in the third part as a variable. The variables are called<br />
<code>$1</code>, <code>$2</code>, <code>$3</code> and so on. We have only one Regex matching the whole path (remember the domain name is not included)<br />
so we have the whole path stored in <code>$1</code>.</p>
<h3>Altering the URI structure</h3>
<p>It may be the case that you don&#8217;t like the current structure of your URI&#8217;s. If your blog has URIs like this</p>
<pre><code>www.olddomain.com/blog/category/2009-12-20-post-title</code></pre>
<p>Say we decide dates are not that important, we only want to keep the year, and we want it separated by a slash, rather than a dash. Additionally,<br />
we want to get rid of the &#8216;blog&#8217; keyword, since the whole domain is for the blog. The following rule will do the trick.</p>
<pre><code>
RewriteEngine on
RewriteRule ^blog/(.&lowast;)/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])-(.&lowast;)$ http://www.newdomain.com/$1/$2/$5 [R=301,L]
</code></pre>
<p>Here we have 5 matches being put into variables, one for each pair of parenthesis.</p>
<dl>
<dt>The category ($1)</dt>
<dd>Matches the first set of non-newline characteres after &#8216;blog/&#8217; and the before the following slash.</dd>
<dt>The Year ($2)</dt>
<dd>Matches 4 consecutive digits after the second slash and before the first dash after that</dd>
<dt>The Month ($3)</dt>
<dd>Matches 2 consecutive digits between the first and second dashes after the second slash</dd>
<dt>The day ($4)</dt>
<dd>Matches 2 consecutive digits between the second and third dashes after the second slash</dd>
<dt>The Post Slug ($5)</dt>
<dd>Matches all the rest of the line</dd>
</dl>
<p class="warning">Before we proceed, notice a peculiarity here. Because the rule starts with the carat (^) and ends with the dollar sign ($) you are<br />
matching the whole line in this format. If the URI doesn&#8217;t start exactly with &#8220;blog/&#8221; and has the exact amount of slashes and dashes<br />
we specified it won&#8217;t be a match and will be ignored. Also, the category may be empty, as long as the two slashes are there, but the digits<br />
must be present in exact amounts. That, of course, is to be expected of any previously valid URL on the domain.
</p>
<p>Now that we have the five variables with the orginal information parsed, we can use them as we want. We decided to get rid of the blog part (which we<br />
are matching literally, instead of via regex, because it&#8217;s too simple), month and day and reorganize category, year and post slug. We will use the<br />
first, second and fifth variables and simply ignore the rest.</p>
<pre><code>http://www.newdomain.com/$1/$2/$5/</code></pre>
<p>If you don&#8217;t want to redirect to a new domain but just rearrange the URIs within it, you may simply omit the domain on the redirection and use these rules</p>
<pre><code>RewriteEngine on
RewriteRule ^blog/(.&lowast;)/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])-(.&lowast;)$ /$1/$2/$5 [R=301,L]
</code></pre>
<h3>Reusing the domain for a different project</h3>
<p>More often than not, after a domain redirect, the old domain will remain merely as an entry point for redirection. People do that for several reasons,<br />
one of them is that readers can be confused to find the old URLs being redirected to a new site and the domain being used for a new site.</p>
<p>But deciding whether or not to reuse your domain is outside the scope of this post. You may be splitting your site in two and you&#8217;ll leave part of it in<br />
the old domain or after a few years, links to your old domain may be minimal or, simply, you may have a better strategy that I can thing while writing this.</p>
<p>In any case, if you want to reuse your domain at some point, you must be aware of a few things.</p>
<p>All the URI&#8217;s redirected are taken and can&#8217;t be reused without disabling the redirection. You guessed that, of course, but you have to keep in mind that<br />
when you are using regexes for your redirects you are matching a whole class of URIs, even some that have not being used but match the pattern.</p>
<p>If you hurried up and used the first rule (repeated below) you are matching every single URI within the old domain and it means that any content there<br />
will be unreachable because the redirection rules will take precedence.</p>
<pre><code>
RewriteEngine on
RewriteRule ^(.&lowast;)$ http://www.newdomain.com/$1 [R=301,L]
</code></pre>
<p>If you used the second rule (repeated below) you are targetting a much more specific set of URIs. Anything that doesn&#8217;t have the exact format described<br />
(/blog/[characters]/[4digits]-[2digits]-[2digits]-[characters]) will be reachable.</p>
<pre><code>
RewriteEngine on
RewriteRule ^blog/(.&lowast;)/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])-(.&lowast;)$ http://www.newdomain.com/$1/$2/$5 [R=301,L]
</code></pre>
<p>You&#8217;ll be able to even run a blog under <code>http://www.olddomain.com/blog/</code> as long as you don&#8217;t use the exact same URI structure. Again<br />
whether or not this is a good idea is up to you to decide.</p>
<h3>301 or 302 redirects</h3>
<p>Finally, you may have noticed that one of the parameters on the last part of the rules is the number 301. This is the type of redirection you are<br />
performing. You can use either 301 or 302 as redirection codes, 301 stands for a permanent redirection, whereas 302 stands for a temporary redirection.</p>
<p>Redirection codes are informed to user agents (browsers), search bots and anyone else who may want to know. While both redirection codes will take you<br />
to the new URI, there are important consequences of choosing either.</p>
<p>Because user agents and bots are informed of the redirection code, they can take actions based on them.</p>
<p>A temporary redirection is equivalent to an &#8220;Out For Lunch&#8221; sign. For some reason, the page is being redirected, but you are confirming the user is on<br />
the permanent URI for the resource. Bear in mind that &#8220;temporary&#8221; doesn&#8217;t imply in any length of time, you are only saying &#8220;Yes, this is the URI. We<br />
are operating there right now, but come back here the next time&#8221;.</p>
<p>Reasons for that could be:</p>
<dt>Maintenance page</dt>
<dd>You may want to redirect the whole traffic of your page for a few minutes or hours while you are performing an upgrade</dd>
<dt>Feedburner redirect</dt>
<dd>If you use feedbuner, you may want people to subscribe to an URI within your domain, but redirect to feedburner. If<br />
    one day you want to use a different service, all your subscribers use your URI, so they will be automatically redirected.</dd>
<p>A permanent redirection is stronger, it is equivalent to say &#8220;We moved, we are now operating there and we are not coming back. Next time<br />
you may prefer to go there straight away&#8221;. The consequence of that<br />
is that search bots, intelligent user agents, social bookmarking sites and whoever else may care, can update their links to the new location.</p>
<p>This is what is going to make possible for Search Engines to transfer the status of your site to the new structure.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.z-oc.com/blog/2009/01/htaccess-redirect-wizardry/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Tutorial: A category based archive on WordPress</title>
		<link>http://www.z-oc.com/blog/2008/03/category-based-archive/</link>
		<comments>http://www.z-oc.com/blog/2008/03/category-based-archive/#comments</comments>
		<pubDate>Sat, 29 Mar 2008 02:21:20 +0000</pubDate>
		<dc:creator>guioconnor</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[page]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.z-oc.com/blog/2008/03/category-based-archive/</guid>
		<description><![CDATA[I followed Lorelle&#8217;s advice advice and added a category based archive on Zo&#8217;C's archive page, and now I&#8217;m going to tell you how to create yours. At the end of this post, you&#8217;ll find the complete code in a single piece. Step 1: Create the template file and find the content area The first thing [...]]]></description>
			<content:encoded><![CDATA[<p>I followed <a href="http://www.z-oc.com/blog/2008/02/a-powerful-archive-page-for-your-wordpress-blog/#comment-1111">Lorelle&#8217;s advice</a> advice and added a category based archive on <a href="http://www.z-oc.com/blog/archive/">Zo&#8217;C's archive page</a>, and now I&#8217;m going to tell you how to create yours.</p>
<p>At the end of this post, you&#8217;ll find the complete code in a single piece.</p>
<h3>Step 1: Create the template file and find the content area</h3>
<p>The first thing to do is create a new template page for your theme. The easiest way to do it is by duplicating your default page template which is the file &#8220;page.php&#8221;. Login via FTP, SSH or your favorite method an copy that file to &#8220;category_archive.php&#8221; and start editing.</p>
<p>Edit your file so at the very beginning it has the following lines, they are responsible for telling WordPress this is a template page and its name.</p>
<p><code>
<pre>&lt;?php
/*
Template Name: CategoryArchive
*/
?&gt;</pre>
<p></code></p>
<p>The reason why we copied the default page instead of starting from the scratch is that any theme has is peculiarities (footer, sidebar, header, this and that) and we want to preserve them all, we just want to change the content. So, now, you must find the content.</p>
<p><span id="more-268"></span></p>
<p>It is probably different on your theme, but in mine, I find content starts after this</p>
<p><code>
<pre>&lt;div id="main"&gt;
&lt;div id="container"&gt;
&lt;?php include("menu-sec.php"); ?&gt;
	&lt;div id="content"&gt;</pre>
<p></code></p>
<p>And ends just before this</p>
<p><code>
<pre>	&lt;/div&gt;&lt;!-- content --&gt;
&lt;/div&gt;&lt;!-- container --&gt;

&lt;?php get_sidebar(); ?&gt;
&lt;div class="clearer"&gt;&lt;/div&gt;
&lt;/div&gt;&lt;!-- main --&gt;

&lt;?php get_footer(); ?&gt;</pre>
<p></code></p>
<h3>Step 2: Find the categories and loop through them</h3>
<p>Once you have located the content area let&#8217;s get to the PHP code to make the magic happen.</p>
<p>First you have to inquiry WordPress for the categories</p>
<p><code>
<pre>&lt;?php $cats = get_categories("hierarchical=0"); ?&gt;</pre>
<p></code></p>
<p>Then loop through them and display them. Don&#8217;t forget to check for NULL entries: a sanity check. In case something goes wrong and no categories are returned the script will do nothing instead of crashing.</p>
<p><code>
<pre>
&lt;?php if($cats != NULL) { ?&gt;
		&lt;ul&gt;
		&lt;?php foreach ($cats as $cat) { ?&gt;
			&lt;li&gt;
			&lt;?php if($cat != NULL) {
				$base_url = get_bloginfo('home') . "/category/" . $cat-&gt;slug; ?&gt;
				&lt;h3&gt;&lt;a href="&lt;?php echo $base_url?&gt;"&gt;&lt;?php echo $cat-&gt;cat_name?&gt;&lt;/a&gt;&lt;/h3&gt;
			&lt;?php } ?&gt;

			&lt;?php // Show category description
				if ($cat-&gt;category_description != NULL) ?&gt;
					&lt;p&gt;&lt;?php echo $cat-&gt;category_description ?&gt;&lt;/p&gt;</pre>
<p></code></p>
<p>For each category, we are presenting the title and the description. Additionally, the category name is a link to the regular category listing page, so people can dig further on a category, if they want to.</p>
<h3>Step 3: Find the posts filed under each category and display them</h3>
<p>On each iteration of the loop above, besides presenting the category info, we need to query the posts filed under that particular category and display them. Start by querying WordPress about the posts of the category you are in.</p>
<p><code>
<pre>&lt;?php $myposts = get_posts("numberposts=-1&#038;category=$cat->cat_ID"); ?&gt;</pre>
<p></code></p>
<p>(UPDATE: get_posts parameters updated to avoid the default limit of 5 posts, thanks Chuck for <a href="http://www.z-oc.com/blog/2008/03/category-based-archive/#comment-1224">pointing out the problem</a>.)</p>
<p>And then, loop through them displaying its name and permalink. And, once we have our hands on it, lets add it a touch of class and display the date in which it was published.</p>
<p><code>
<pre>&lt;ul&gt;
&lt;?php foreach($myposts as $post) : ?&gt;
	&lt;li&gt;&lt;?php the_time('M d') ?&gt;. &lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;&lt;/li&gt;
&lt;?php endforeach; ?&gt;
&lt;/ul&gt;</pre>
<p></code></p>
<p>Don&#8217;t forget to close the outer loop:</p>
<p><code>
<pre>&lt;?php } ?&gt;</pre>
<p></code></p>
<h3>Step 4: Create a page using the layout you just made</h3>
<p><img src='http://www.z-oc.com/blog/wp-content/uploads/2008/03/selecting_template.png' alt='Selecting The Template' class="right" />Now that you have created a page template for your category based archive, you must create a page using it.</p>
<p>Go to the admin panel on your blog, to the write page interface and create your page normally, except that on the right panel, under &#8220;Page Template&#8221; you&#8217;ll chose &#8220;CategoryArchive&#8221;. Chose a nice Post Slug for it if you want and a descriptive title but you don&#8217;t need to put any content because it won&#8217;t show anyway.</p>
<h3>The complete code to copy and paste</h3>
<p>If you find it difficult to copy and paste all the pieces of this tutorial, here is the complete code that you can just copy and paste inside the  content of your page template. </p>
<p>Just remember that this is NOT the complete template, as it changes from theme to theme, this is only the juicy part of it, enjoy.</p>
<p><code>
<pre>&lt;?php $cats = get_categories("hierarchical=0"); ?&gt;

&lt;?php if($cats != NULL) { ?&gt;
		&lt;ul&gt;
		&lt;?php foreach ($cats as $cat) { ?&gt;
			&lt;li&gt;

			&lt;?php if($cat != NULL) {
				$base_url = get_bloginfo('home') . "/category/" . $cat-&gt;slug; ?&gt;
				&lt;h3&gt;&lt;a href="&lt;?php echo $base_url?&gt;"&gt;&lt;?php echo $cat-&gt;cat_name?&gt;&lt;/a&gt;&lt;/h3&gt;
			&lt;?php } ?&gt;

			&lt;?php // Show category description
				if ($cat-&gt;category_description != NULL) ?&gt;
					&lt;p&gt;&lt;?php echo $cat-&gt;category_description ?&gt;&lt;/p&gt;

				&lt;?php $myposts = get_posts("category=$cat-&gt;cat_ID"); ?&gt;
				&lt;ul&gt;
				&lt;?php foreach($myposts as $post) : ?&gt;
					&lt;li&gt;&lt;?php the_time('M d') ?&gt;. &lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;&lt;/li&gt;
				&lt;?php endforeach; ?&gt;
				&lt;/ul&gt;
			&lt;/li&gt;
	&lt;?php } ?&gt;
		&lt;/ul&gt;
&lt;?php } ?&gt;</pre>
<p></code></p>
<h3>Who is using it</h3>
<ul>
<li><a href="http://pshero.com/gallery/">PS Hero</a></li>
<li><a href="http://www.morphodesigns.com/article-time-machine/">Morpho Designs</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.z-oc.com/blog/2008/03/category-based-archive/feed/</wfw:commentRss>
		<slash:comments>70</slash:comments>
		</item>
		<item>
		<title>Django &#8211; A framework to easily build complex sites</title>
		<link>http://www.z-oc.com/blog/2007/12/django-a-framework-to-easily-build-complex-sites/</link>
		<comments>http://www.z-oc.com/blog/2007/12/django-a-framework-to-easily-build-complex-sites/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 19:37:19 +0000</pubDate>
		<dc:creator>guioconnor</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[complex]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://www.z-oc.com/blog/2007/12/django-a-framework-to-easily-build-complex-sites/</guid>
		<description><![CDATA[If you haven&#8217;t heard about Django, it is a Python Based framework to build complex and resource savvy sites easily and quickly. I have been studying and playing with Django in the last days and I&#8217;m simply amazed about it. If you are a designer rather than a developer, the word python might scare you [...]]]></description>
			<content:encoded><![CDATA[<p>If you haven&#8217;t heard about <a href="http://www.djangoproject.com">Django</a>, it is a Python Based framework to build complex and resource savvy sites easily and quickly. I have been studying and playing with Django in the last days and I&#8217;m simply amazed about it.</p>
<p>If you are a designer rather than a developer, the word python might scare you a little, since you don&#8217;t want to learn any python at all. Instead, if you are a developer, you might be skeptic to read that complex sites can be built easily.</p>
<p><span id="more-212"></span></p>
<h3>Why is Django so scalable?</h3>
<p>So, here is how it works. Django is not a CMS like Joomla, WordPress, or Drupal. Django is a framework, meaning that is not a ready made tool to put a site online out of the box. Instead is a development platform where you can develop your CMS, Blog platform or a custom made site.</p>
<p>Now, what I&#8217;ve seen as major advantages in Django are</p>
<dl>
<dt>A high degree of reusability through pluggable components.</dt>
<dd>As a developer, this is a way to easy reuse resources developed once in other projects, but  ultimately means you can reuse components made by other people, being people on your team, software you can download on the web or developed for you by a hired developer.</dd>
<dt>O high degree of separation between the functional and the presentation layer</dt>
<dd>Technically Django itself is a library to be added to Python, but a project in Python is composed of two things, application and views and they are strongly de-coupled, meaning that different people can work on these layers and interaction can be kept to a minimum. Means also that, as a designer, you can build great sites without having to learn a lot of python</dd>
</dl>
<h3>Installing and maintaining Django</h3>
<p>As <a href="http://www2.jeffcroft.com/blog/2006/may/02/django-non-programmers/">Jeff Croft says</a>, Django Documentation is aimed to non-programmers and the installation process of Python libraries might not be trivial for everyone, but if you already have Python running on your computer, building a development environment on your computer following the <a href="http://www.djangoproject.com/documentation/install/">installation instructions</a> is pretty much straightforward.</p>
<p>What might not be that easy, is to set up your host to have a prodution environment. For instance, if you use <a href="http://www.dreamhost.com/r.cgi?252836">Dreamhost</a>, you can follow <a href="http://wiki.dreamhost.com/index.php/Django">instructions on their wiki</a> to set it up, but they don&#8217;t actively support Django, so if you don&#8217;t manage to install it or if something breaks you are pretty much on your own.</p>
<p>The good news is that there are servers that support it, so in theory, you only have to install the applications you want or develop your own and build sites of arbitrary complexity.</p>
<p>By now, I&#8217;m still playing on my development environment on my iMac, but I&#8217;m inclined to sign up with <a href="http://www.webfaction.com/signup?affiliate=guioconnor">Web Faction</a> for real-life Django projects, their price is compatible with the most used web hosts and I heard many good things about them.</p>
<h3>How different applications relate on a project?</h3>
<p>In dajngo, a web project basically consists on configuring the applications you want to use, related with the templates for the site and the URLs to access them. Applications may reside wherever you want just as templates, meaning that if you have a Poll application (you can actually build one following four simple tutorials included in <a href="http://www.djangoproject.com/documentation/">the documentation</a>), for instance, you can only import the functionality, and attach it to your site templates without much further customization.</p>
<p>If you are used to plugin enabled systems like WordPress, you are certainly having a familiar feeling about this. The advantage is that being Django a framework, not an application, different applications are much more independent of each other than plugins from wordpress, or any platform you might have in mind and allow you to create completely different and complex applications that can be coupled on a per-project basis.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.z-oc.com/blog/2007/12/django-a-framework-to-easily-build-complex-sites/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>&#8220;Order By&#8221; in SQL queries and random selection of database items</title>
		<link>http://www.z-oc.com/blog/2007/06/order-by-in-sql-queries-and-random-selection-of-database-items/</link>
		<comments>http://www.z-oc.com/blog/2007/06/order-by-in-sql-queries-and-random-selection-of-database-items/#comments</comments>
		<pubDate>Thu, 14 Jun 2007 17:20:10 +0000</pubDate>
		<dc:creator>guioconnor</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[mySQL]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.z-oc.com/blog/2007/06/order-by-in-sql-queries-and-random-selection-of-database-items/</guid>
		<description><![CDATA[Simple hint, how to select a number random items from a MySQL database: SELECT * FROM your_table ORDER BY rand() LIMIT 2; The code above, selects all the fields from a database table named &#8220;your_table&#8221; orders the results randomically and gets the first two. Change two for your favourite number. Want to see an example [...]]]></description>
			<content:encoded><![CDATA[<p>Simple hint, how to select a number random items from a MySQL database:</p>
<pre>
<code>SELECT *
FROM your_table
ORDER BY rand()
LIMIT 2;</code>
</pre>
<p>The code above, selects all the fields from a database table named &#8220;your_table&#8221; orders the results randomically and gets the first two. Change two for your favourite number.</p>
<p><img src='http://www.z-oc.com/blog/wp-content/uploads/2007/06/recommended.png' class="instant" alt='Recommended Reading' style="float:left;margin: 0px 10px 10px 0" /></p>
<p>Want to see an example of this working? Just look to your right! On the sidebar, there is a section named &#8220;Recommended Reading&#8221;. This is a section with books I like and recommend. I keep a list of books on a database and I pick <del datetime="2007-07-02T02:40:41+00:00">two</del> six at random with a query like this, each time a page is loaded.</p>
<p>Maybe you did knew this command already, or at least you heard about the ORDER BY command, but do you exactly know how it works and how further you can go with it?</p>
<p>I&#8217;ll show you some nice things in this article.</p>
<p><span id="more-96"></span></p>
<p>[All the code on this page works in MySQL, <a href="http://www.petefreitag.com/item/466.cfm">SQL syntax may vary</a> in other Database Management Systems, but the same ideas apply to all]</p>
<h3>How does ORDER BY works</h3>
<p>The ORDER BY statement on a SQL query atributes an indexing number on each entry of the table.</p>
<p>When you do a </p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY price;</code>
</pre>
<p>An indexing value will be calculated for each entry, based on the expression after the ORDER BY statement. The <em>price</em> will work as variable. The value of the registry will be used as indexing value for it, then the whole list will be sorted based on it. This is how it works.</p>
<p>So, if you use a custom method to set the indexing value you can have your own sorting system. For instance, see this query</p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY price - discount;</code>
</pre>
<p>For each entry, the discount will be subtracted from the price, this number will be set as indexing value for the entry, then, the results will be sorted based on it.</p>
<p>In practice the indexing value will be the final value to be paid, lowest prices first. You can reverse this using descending order.</p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY price - discount DESC;</code>
</pre>
<h3>Order By using functions</h3>
<p>MySQL comes with a lot of <a href="http://dev.mysql.com/doc/refman/5.0/en/functions.html">predefined funcions</a> (and you can create funcions of your own, but this will not be covered on this post).</p>
<p>One of theese funcions is rand(). The rand() function returns a random number every time it is called.</p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY rand();</code>
</pre>
<p>When used in a query like the one above, the rand() funcion will be called for each entry and a random number will be set as indexing value for them. The table will, then, be sorted based on theese numbers. The result would by, obviously, that entries will appear in random places.</p>
<p>If you only want to select, say, 2 random entries from the table, you can limit your search using</p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY rand()
LIMIT 2;</code>
</pre>
<h3>Boolean searching criteria, one step beyond</h3>
<p>[Now, before anything else, I must give credit to Benjamin Wilger for <a href="http://www.ilovejackdaniels.com/blog/useful-sql-snippet/comments/#comment1">his comment</a> on <a href="http://www.ilovejackdaniels.com/blog/useful-sql-snippet/">Dave's blog</a>.]</p>
<p>What if you want to just sort through boolean criteria. For instance, what if you <em>don&#8217;t</em> want to sort by item final price, but you do want those who don&#8217;t have a discount to come before who have?</p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY (discount > 0);</code>
</pre>
<p>Now, this is tricky, so let&#8217;s see it carefully.</p>
<p>The expression <code>(discount > 0)</code> is a logical statement, not an arithmetic one. This means that the answer to that is either true or false instead of a number.</p>
<p>But in databases, everything are numbers on the lowest level. False is actually a zero and true is actually a one.</p>
<p>When you set the result of (discount > 0) as the indexing value, you are actually setting zeroes and ones as sorting criteria and, because zero comes first, the entries in which the expression evaluated as false come first.</p>
<p>If you want the items with discount to come first, you can sort in descending order</p>
<pre>
<code>SELECT *
FROM recommendations
ORDER BY (discount > 0) DESC;</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.z-oc.com/blog/2007/06/order-by-in-sql-queries-and-random-selection-of-database-items/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Managing obsolete pages with one line of code</title>
		<link>http://www.z-oc.com/blog/2007/05/managing-obsolete-pages-with-one-line-of-code/</link>
		<comments>http://www.z-oc.com/blog/2007/05/managing-obsolete-pages-with-one-line-of-code/#comments</comments>
		<pubDate>Mon, 07 May 2007 20:36:58 +0000</pubDate>
		<dc:creator>guioconnor</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Apache]]></category>

		<guid isPermaLink="false">http://www.z-oc.com/blog/2007/05/managing-obsolete-pages-with-one-line-of-code/</guid>
		<description><![CDATA[When I switched from Blogger to WordPress I had to deal with the problem of how to deal with the old pages. Blogger style of archiving was static. That means that for every post you created, the Blogger system created a static HTML page. WordPress on the other side creates pages dynamically, meaning that there [...]]]></description>
			<content:encoded><![CDATA[<p>When I switched from <a href="http://www.blogger.com">Blogger</a> to <a href="http://www.wordpress.org">WordPress</a> I had to deal with the problem of how to deal with the old pages.</p>
<p>Blogger style of archiving was static. That means that for every post you created, the Blogger system created a static HTML page.</p>
<p>WordPress on the other side creates pages dynamically, meaning that there is no .html file whatsoever, the page is created on the fly whenever you request it. A change in the database automatically reflects on the page.</p>
<p>Now, the problem is, the address of the new pages doesn&#8217;t match the address of the old ones.</p>
<p><span id="more-64"></span></p>
<p>While old posts where in <acronym>URL</acronym>s like this</p>
<pre><code>http://www.z-oc.com/blog/2006/09/food-links.html</code></pre>
<p>the new posts where called through PHP queries like this</p>
<pre><code>http://www.z-oc.com/blog/2006/09/food-links</code></pre>
<p>But, as long as the <a href="http://codex.wordpress.org/Writing_Posts#Advanced_Post_Editing_Screen">post slug</a> is the exact name of the blogger page (without the .html extension) putting the following rule on your <a href="http://httpd.apache.org/docs/1.3/howto/htaccess.html">.htaccess</a> file should do the trick.</p>
<pre><code>RewriteRule ^(.*).html$ http://www.site.com/$1 [R=301,L]</code></pre>
<p>This rule will simple redirect the html page to the new address that is exactly the same, but without the .html extension.</p>
<p>Keep in mind though, that this will redirect <em>all</em> pages in your site that end with and .html extension, so take care if you have some .html files around.</p>
<p>You can apply this rule on a per-directory basis or you can put aditiona rules to take care of those in particular.</p>
<p>This way of redirecting is particularly good for <acronym>SEO</acronym>, because search engines will be notified that the page was permanently moved, helping them to properly index you site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.z-oc.com/blog/2007/05/managing-obsolete-pages-with-one-line-of-code/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>How to build an events agenda with SQL</title>
		<link>http://www.z-oc.com/blog/2007/03/how-to-build-an-events-agenda-with-sql/</link>
		<comments>http://www.z-oc.com/blog/2007/03/how-to-build-an-events-agenda-with-sql/#comments</comments>
		<pubDate>Fri, 30 Mar 2007 16:55:00 +0000</pubDate>
		<dc:creator>guioconnor</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[agenda]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[mySQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.z-oc.com/blog/2007/03/how-to-build-an-events-agenda-with-sql/</guid>
		<description><![CDATA[In my opinion, one of the coolest things of the site I&#8217;ve built to Paulo gazela is the event agenda on the navigation bar. Of course there are many calendar programs around to add to your site and it&#8217;s also possible to integrate google calendar or a similar tool, but all Paulo needed was a [...]]]></description>
			<content:encoded><![CDATA[<p>In my opinion, one of the coolest things of the site <a href="http://www.z-oc.com/blog/2007/03/paulo-gazela-site-design-by-guilherme/">I&#8217;ve built</a> to <a href="http://www.paulogazela.com.br">Paulo gazela</a> is the event agenda on the navigation bar.</p>
<p>Of course there are many calendar programs around to add to your site and it&#8217;s also possible to integrate google calendar or a similar tool, but all Paulo needed was a way to show the events he was going to be in for the folowing, say, 15 days, and an easy interface to add them.</p>
<p>The solution is very simple. We&#8217;ve built a database with the date, time and details of the events and we created a SQL query to get all the events 15 days from the current date.</p>
<p>A single SQL query like the one below can handle everything</p>
<pre><code>
SELECT *
FROM event, place
WHERE event.place=place.id
  AND CURDATE() < = event.thedate
  AND DATE_ADD(CURDATE(),INTERVAL 15 DAY) >= event.thedate
ORDER BY
  event.thedate ASC,
  event.thetime ASC;
</code></pre>
<p>If you want to understand better what this is, to build the database tables and get some more detail, read on. </p>
<p><span id="more-55"></span></p>
<p>I will assume you have the basic knowledge about connecting to the database system in your server, but I&#8217;ll try go through all steps that are common for every system.</p>
<p>This is an ad hoc tutorial and I won&#8217;t explain a lot o SQL syntax, but if you want to really learn SQL in a generic sense, I encourage you to start learning <a href="http://www.w3schools.com/sql">here</a></p>
<p>First of all, you need to create the database and the tables. The SQL command to create the event table is similar to this</p>
<pre><code>
CREATE TABLE event (
  id INT UNIQUE NOT NULL AUTO_INCREMENT,
  thedate DATE,
  thetime TIME,
  place INT,
  name VARCHAR(40)
);
</code></pre>
<p>The reason why eventplace is an INT field is because the place in itself has a lot of information and good practice on databases (normal forms) require that places have to be stored on its own table.</p>
<pre><code>
CREATE TABLE place (
  id INT UNIQUE NOT NULL AUTO_INCREMENT,www.
  name VARCHAR(40),
  address VARCHAR(100),
  website VARCHAR(50),
  phone VARCHAR(20)
);
</code></pre>
<p>Now we have the database tables set up!</p>
<p>First thing to do is to create a place where one or more events will happen. The SQL to do that is something like:</p>
<pre><code>
INSERT INTO place (name, address, website, phone)
VALUES ('A cool place', 'Cool St. 42','www.coolplace.im','555-1234');
</code></pre>
<p>The id field is going to fill automatically with a unique number and the value will be set up to the next free number. As this is our first insertion, &#8220;Cool Place&#8221; register will have id 1, but we are not suppose to know this by heart, stick with me and I&#8217;ll show you how to do it. For now, let&#8217;s just assume we know that.</p>
<p>So, let&#8217;s insert an event to happen on a couple of days on Cool Place, which has id=1.</p>
<pre><code>
INSERT INTO event (thedate, thetime, place, name)
VALUES ('2007-04-05', '14:30:00', 1 ,'A Cool Event');
</code></pre>
<p>And this event will happen again next month.</p>
<pre><code>
INSERT INTO event (thedate, thetime, place, name)
VALUES ('2007-05-27', '14:30:00', 1 ,'A Cool Event');
</code></pre>
<p>Note that the third parameter, place, does not come into quotes, because is a numerical value rather than a string.</p>
<p>Ok, we&#8217;re set and done with the database, by repeating this procedures, we can insert as many places as we want, and events associated with these places. What we want to do now, is to list the events that will happen in the next 15 days.</p>
<p>Before we do that, let&#8217;s just see how to retrieve the information. We should issue a command to select the entries we want in the database.</p>
<p>The simplest query is something similar to</p>
<pre><code>
SELECT *
FROM event;
</code></pre>
<p>This means, select all fields on the table &#8216;events&#8217;, the asterisk stands for &#8216;all fields&#8217;. A somehow more complex query would be like this</p>
<p>But now, we want to know the name and address of the place where the event will occur, instead of the event id. So we want something like this:</p>
<pre><code>
SELECT
  thedate as date,
  thetime as time,
  event.name as e_name,
  place.name as p_name,
  address as addr
FROM event, place
WHERE event.place=place.id;
</code></pre>
<p>To show the events that will happen within 15 days from now, we must select all entries where the date is greater than today and lesser than today + 15 days.</p>
<pre><code>
SELECT
  event.thedate as d,
  event.thetime as t,
  event.name as e_name,
  place.name as p_name,
  place.address as addr
FROM event, place
WHERE event.place=place.id
  AND CURDATE() < = event.thedate
  AND DATE_ADD(CURDATE(),INTERVAL 15 DAY) >= event.thedate;
</code></pre>
<p>And how about to order entries by date and time? First order the entries by the date, adn then, events that have the same date will be ordered by the time.</p>
<pre><code>
SELECT
  event.thedate as d,
  event.thetime as t,
  event.name as e_name,
  place.name as p_name,
  place.address as addr
FROM event, place
WHERE event.place=place.id
  AND CURDATE() < = event.thedate
  AND DATE_ADD(CURDATE(),INTERVAL 15 DAY) >= event.thedate
ORDER BY
  event.thedate ASC,
  event.thetime ASC;
</code></pre>
<p>Ok, that&#8217;s it! This is the SQL we need.</p>
<p>A PHP implementation of the query would be something like this</p>
<pre><code>
&lt;?php
$con = mysql_connect("mysql.myserver.com","user","password");
if (!$con)
{
  die('Could not connect: ' . mysql_error());
}

$query = &quot;
    SELECT
      event.thedate as d,
      event.thetime as t,
      event.name as e_name,
      place.name as p_name,
      place.address as addr
    FROM event, place
    WHERE event.place=place.id
      AND CURDATE() < = event.thedate
      AND DATE_ADD(CURDATE(),INTERVAL 15 DAY) >= event.thedate
    ORDER BY
      event.thedate ASC,
      event.thetime ASC&quot;;

echo &quot;&lt;table&lt;&quot;;
$result = mysql_query($query);
while($row = mysql_fetch_array($result))
{
    echo &quot;&lt;tr&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['date'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['time'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['name'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['place'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['addr'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['website'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['phone'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;td&gt;&quot; . $row['descr'] . &quot;&lt;/td&gt;&quot;;
    echo &quot;&lt;/tr&gt;&quot;;
}
echo &quot;&lt;/table&lt;&quot;;
?&gt;
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.z-oc.com/blog/2007/03/how-to-build-an-events-agenda-with-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

