SEO-friendly URLs

Search Engine Optimization (SEO) is a discipline that helps web sites stand out to internet search engines. Making a web site friendly to search engines involves favoring text over images, identifying important keywords of interest in searches, and using heading tags to emphasize key features of individual pages. One aspect that can implemented in the Istarel Workshop Application Framework (IWAF) is SEO-friendly URLs.

That implementation involves the Redirect model object class, its associated RedirectFactory class, and the ApplicationDelegate.

Redirect Model Object

Each redirect is represented by a tuple in the underlying application database, and each tuple has two key columns: public_path and application_module. The public_path is the SEO-friendly URL and the application_module is the module invoked by the framework to do actual work. There are also two secondary columns (key and value) that are used to define a specific tuple to be used by the application application_module (but are often null when no such data is needed).

Listing: /rsrc/model/application/Redirect.php

class Redirect extends DefaultRedirect
{
    function url()
    {
        $url = new IWURL($this->application_module);
        if ($this->key) $url->setParameter($this->key, $this->value);
        return $url;
    }
}

Redirect Factory

The RedirectFactory class implements methods to support the creation and deletion of Redirect objects. These methods are invoked in two places. The ApplicationDelegate uses findApplicationModule() to determine the correct application module to invoke given a page request. Model object classes use their didSave() and didDelete() delegate methods to call createRedirect() and deleteRedirect().

Listing: /rsrc/model/application/RedirectFactory.php

class RedirectFactory extends DefaultRedirectFactory
{
    public static function findApplicationModule($url)
    {
        return RedirectFactory::retrieveRedirect($url, 'public_path');
    }

    static function createRedirect($path, $module, $key = null, $value = null)
    {
        // Does a redirect already exist for the public path?
        $counter = new ORMCounter('redirect');
        $counter->addCriteria(new ORMCriterion('public_path', $path));

        // If an entry already exists, nothing needs to be done
        if (1 == $counter->one()) return;

        // Create a new redirect entry
        $redirect = new Redirect;
        $redirect->setPublicPath($path)
                 ->setApplicationModule($module)
                 ->setKey($key)
                 ->setValue($value);
        $redirect->save();
    }

    public static function removeRedirect($public_path)
    {
        $delete = new ORMDelete('redirect');
        $delete->addCriteria(new ORMCriterion('public_path', $public_path));
        $delete->execute();
    }
}

Application Delegate

Finally, the ApplicationDelegate object has a modifyPageRequest($url) method. This allows the application to translate the SEO-friendly URL into a proper application module invocation.

Partial Listing: /rsrc/ApplicationDelegate.php

function modifyPageRequest($url)
{
    if (! $url) $url = $this->startingPoint();

    // If the request is a proper view, no need to modify the page request
    if ($this->requestExists($url)) return $url;

    if (in_array($url, $this->forbiddenViews())) return $this->startingPoint();

    // Remap an SEO-friendly page request, if applicable
    if (! $module = RedirectFactory::findApplicationModule($url)) return $url;

    // Build and return url
    $url = $module->application_module;
    if ($module->key) $_GET[$module->key] = $module->value;

    return $url;
}