How to post forms to clean, rewritten URLs without JavaScript: a

How to post forms to SEO-friendly URLs without JavaScript

Rewritten URLs are valuable because they increase website usability and improve search engine optimisation (SEO), but unfortunately, HTML forms and clean URLs were not designed to work together.

In this tutorial, I will reveal my secret way to make them work without Javascript.

Let’s start by analysing the root problem.

HTML forms only have two ways to pass variables to their target page; the GET, and POST methods. Neither of these allows for dynamic rewritten URLs.

The POST method: (empty URLs)

Posting a form gives empty URLs

When posting data from a form, the parameters and their values are not visible in the target page URL because they are hidden.

The problem with this is a user cannot simply copy the URL and go back to the same page later and see the same content; the exact page content is 'lost'.

The GET method: (ugly, unfriendly URLs)

The Submitting a form with the GET method gives ugly, unfriendly URLs

Forms using the GET method send data via the URL. This means that the URL can be copied and revisited at any time.

The problem with this method is the ugly format of the parameters. The values in the URL string are verbose and unfriendly to type by hand or remember; this is what we are trying to avoid.

The solution: Post-to-self then redirect to an SEO-friendly URL

Form POST to self then redirect to a clean URL

The trick is to use server-side logic to construct a clean URL from the posted form data and then automatically redirect to it. This whole process works without any negative effect on user experience.

Any number of form fields can be used with this method too, but for simplicity, in this tutorial, I have used a single field as an example. The other good thing about this solution is it's completely invisible to the user and the back button always takes you back to the first page.

Ok, let's see how this works in more detail.

Building the search page

There are two parts to the search page, the HTML form, and the server-side code (PHP in this example) that handles the posted values. Let’s start by looking at the form.

The search form

Simply set the form method to POST and set the action to the current page (this is important). The easiest way to post a form to itself is to include the action parameter but make it equal to nothing. Here is the HTML of the search form:

<form method="post" action="">
   <fieldset>
      <input type="text" name="q" />
      <input type="submit" value="Search" />
   </fieldset>
</form>

The PHP form handling code

Because the form posts to itself, the PHP code that deals with the posted values MUST be included on every page where the form is displayed.

It is important to note that if your search box is part of your website template then it will be visible on every page and so the code must be on every page too. This will also mean that every page must be a dynamic PHP page so server-side logic can be used to process the form data. In other words, you cannot use the search on a static HTML page.

Another very important point concerns the placement of the code within the PHP file. For the server-side redirect to work correctly the PHP code that does the actual redirect MUST be before any HTML is output to the browser. If you don’t do this correctly then two pages will load, one after the other and the back button won’t take you back to the first page.

Here's the PHP code that handles the posted form data:

<?
// Collect the posted search query
$q = strtolower(mysql_real_escape_string($_POST['q']));

// Clean up by removing unwanted characters
$qclean = ereg_replace("[^ 0-9a-zA-Z]", " ", $q);

// Remove multiple adjacent spaces
while (strstr($qclean, "  ")) {
   $qclean = str_replace("  ", " ", $qclean);
}

// Replace single spaces with a URL friendly plus sign
$qclean = str_replace(" ", "+", $qclean);

// If validation has passed, redirect to the URL rewritten search page
if ($q != '') {
   header( 'Location: http://matthewjamestaylor.com/search/'.$q );
}
// HTML is output after here – NOT BEFORE!
?>
<html>

Building the search results page

There are four parts to the search results page; the Apache mod_rewrite rule, the PHP keyword processing, the MySQL query and then displaying the results.

Rewriting the search results page URL with mod_rewrite

To change the URL from search.php?q=keyword to a more friendly /search/keyword add the following rule to your .htaccess file:

# Clean up search URL
RewriteRule ^search/([^/\.]+)$ search.php?q=$1

Processing the keywords with PHP

First we collect the search phrase from the URL, validate the entry and then prepare it for inclusion in an SQL statement.

<?
// Collect the search phrase from the URL
$qs = mysql_real_escape_string($_GET['q']);

// Clean up by removing unwanted characters
$qsclean = ereg_replace("[^ 0-9a-zA-Z]", " ", $qs);

// Remove multiple adjacent spaces
while (strstr($qsclean, "  ")) {
   $qsclean = str_replace("  ", " ", $qsclean);
}

// Prefix each keyword with a + (for the SQL statement)
$qsql = "+".str_replace(" ", " +", $qsclean);
?>

Perform a MySQL Boolean full-text search

Once we have our keywords we simply add them to the SQL for our database search.

<?
$articles = mysql_query("SELECT title, MATCH(title, descr, body) AGAINST ('".$qsql."') as score from blog where 

MATCH(title, descr, body) AGAINST ('".$qsql."') order by score desc");
?>

Displaying the results

All we need is a simple while loop to print out all results.

<ul>
<?
while ($article = mysql_fetch_array($articles)) {
   print "<li>".$post[0]."</li> ";
}
?>
</ul>

That's it!

Now we have the search results page working we can also build beautiful links direct to search results if we need to too.

Let's recap the main features:

Published: 14 Jan 2008