Tutorials/Understanding OXID SEO

By Vikram Vaswani

In the world of bricks-and-mortar retail, placing products on store shelves so that customers can find them with minimal difficulty is almost a science in itself. This factor assumes even more importance when it comes to online retail, because most consumers begin their search for products through a search engine and so, ensuring that your virtual shelves are properly labeled and indexed for searching is a key component of success.

Fortunately, OXID eShop comes with a full-featured SEO implementation that automatically takes care of generating descriptive URLs for your products and categories, and optimizing these URLs for maximum search engine "stickiness". This SEO implementation is extremely sophisticated - it supports URLs in multiple languages, handles reserved words and special characters, and allows a high degree of user customization. The next few sections will examine it in more detail.

Understanding Product and Category URLs
OXID eShop allows merchants to define product categories and assign products to these categories. Categories can be nested, and a single product may exist in more than one category. This hierarchical arrangement makes it possible for OXID to generate a unique, descriptive URL for every product listed in the shop database, as in the examples below: http://oxid.localhost/Babies/Crocodile-Wind-Up-Bath-Toy.html

http://oxid.localhost/Older-Children/Noddy-on-Wheels-Push-and-Go-Car.html

http://oxid.localhost/Older-Children/Boys/Star-Wars-Action-Figure-Set.html If your shop is set up for multiple languages, OXID supports language-specific unique URLs as well. Here is an example of the same product with two URLs, one for German-language users and one for English-language users: http://oxid.localhost/Baby/Haba-Kringelring.html

http://oxid.localhost/Baby/Haba-Clutching-Ring.html OXID eShop also allows users to tag products with descriptive keywords. Tags can be specified per language. These tags feed into a "tag cloud", which appears on the shop index page. Here's an example:



Tag URLs are SEO-compliant, and generate a cross-section listing of products matching the specified tag. OXID eShop automatically takes care of generating a tag cloud and tag URLs that match the shop's currently-selected language. Here are some examples: http://oxid.localhost/tag/car

http://oxid.localhost/tag/bath

http://oxid.localhost/tag/boys

Generating SEO URLs
URL encoding in OXID is handled by the oxSeoEncoder object. The oxSeoEncoder::_prepareTitle method takes care of automatically preparing an SEO URL from the product or category title, while the oxSeoEncoder::_getUniqueSeoUrl method checks the database and makes minor modifications to the result to ensure that the final SEO URL is completely unique and has no duplicates that will cause conflicts.

In general, the OXID URL encoder uses the following rules when generating SEO-compliant URLs for product and category names:


 * Replace underscores (_) with hyphens (-)
 * Replace umlaute (ä, ö, ü) and additional characters with standard ASCII character combinations (ae, oe, ue)
 * Ignore semicolons, colons, question marks (?), ampersands (&amp;) and other punctuation characters in category and product names
 * Use hyphens to separate words
 * Remove reserved words such as 'admin' and 'core'
 * Leave the case of product and category names unchanged
 * Add the .html extension to product URLs to make them appear as static pages

Merchants can also customize the generated URLs for each category/language and product/language combination via the Administer Products -&gt; Product -&gt; SEO section of each product listing in the OXID eShop administration module.



Translating SEO URLs
When the OXID eShop front controller received a request for an SEO-compliant URLs, it internally invokes a URL decoder, which remaps the request to the appropriate shop controller and passes it the parameters necessary to generate the correct product or category view. This process begins with the OXID eShop .htaccess file, which contains the rewriting rules necessary to invoke the URL decoder. Here is the relevant snippet of code: &lt;IfModule mod_rewrite.c&gt; RewriteCond %{REQUEST_URI} !(\/admin\/|\/core\/|\/export\/|\/modules\/|\/out\/|\/setup\/|\/tmp\/|\/views\/) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (\.html|\/)$ oxseo.php &lt;/IfModule&gt; The $OXID/oxseo.php script executes the $OXID/index.php front controller, which internally initializes an instance of the oxSeoDecoder object and executes its processSeoCall method. The oxSeoDecoder::processSeoCall method reads the request URL and extracts necessary parameters, such as the product name or category name, from it. It then passes these parameters to the oxSeoDecoder::decodeUrl method, which generates an MD5 hash of the request and then queries the oxseo database table for a match and the corresponding internal URL. The front controller then transparently redirects the requesting client to the internal URL. If no match is found, a 404 response code (page not found) is generated.

Here's a diagram that explains the process in more detail, showing how the SEO URL is mapped into an internal controller URL:



And in case you're wondering, here's a cross-section of the oxseo database table:



As you can see, this table has a list of SEO URLs, together with each one's corresponding internal URL for different languages. The front controller is able to use this information to invoke the correct view for each SEO URL.

Each URL has a "type" field, which is used for identification, faster search, and as a filter when cleaning or resetting the table. In particular, note that some URLs are "static"; this type represents URLs that should not be generated dynamically from user input (like product and category URLs) and it is typically used for common shop-level URLs such as URLs for the contact form, guestbook and help pages.

Handling Legacy URLs
It's worth noting that OXID's current implementation of SEO-compliant URLs is different from that used in previous versions. Earlier versions of OXID used URLs like those in the examples below: http://oxid.localhost/oxid.php/sid/cf2d4d66e18a52014cb5702556693b86/cl/details/cnid/1ad463624ce85f4b0.34723936/anid/a0048d7cb63df4ed3.56851241/MHD-05.06.2009---Weight-Watchers-Apple-Crumble-Slices-a-144-g/

http://oxid.localhost/basteln/textilblumenbaender/satinbaender-25mm-breit-22355-25.html Since these older URLs would already be registered with search engines, users of older versions of OXID eShop would normally have a disincentive to upgrade to OXID eShop v4.x. To account for this, OXID eShop includes an oxseohistory table, whose purpose is to store the older URL structures and thereby provide a basis for mapping them to the newer SEO-optimized structures. When the oxSeoDecoder::processSeoCall method receives a request for one of these older URLs from a search engine, it looks up the oxseohistory table for a match, sends the requesting client a 301 response code (page permanently moved) and redirects it to the new URL as retrieved from the oxseo table.

When a product or category name changes, OXID also automatically changes the corresponding SEO URL so that it reflects the new name. Another use of the oxseohistory table is to store the older SEO URL, so that requests for these older URLs are automatically and transparently redirected to the new URLs. The oxSeoEncoder::_copyToHistory method takes care of transferring URLs from the oxseo table to the oxseohistory table.

Setting Page Meta Information
Search engines often look at the &lt;head&gt; of a page to obtain meta-information about its contents. The two key elements in this section are &lt;title&gt; and &lt;meta&gt;, and OXID eShop allows merchants to extensively customize these elements via the OXID eShop administration panel.

The Master Settings -&gt; Core Settings -&gt; SEO panel allows merchants to define the title prefix and suffix, which are automatically added to the title of each page. This same section also allows merchants to specify a descriptive title for the shop index page. Both these values can be specified on a per-language basis, to ensure that text is properly localized for different languages.



OXID eShop also allows merchants control over the &lt;meta&gt; tags that appear near the top of each page. Both description and keywords can be customized on a per-page basis, and per language.

The meta-information that appears on the shop index page is controlled by the CMS templates META Description Startseite and META Keywords Startseite. These can be edited using the Customer Info -&gt; CMS Pages section of the administration panel, as shown below:



The meta-information for product and category pages is automatically generated by OXID eShop based on the description entered in the corresponding product listing. You can override this on a per-product or per-category basis by explicitly setting values for these fields in the SEO tab of the corresponding product or category record, as shown below:



More information on customizing shop meta tags can be found in the OXID eShop manual

Controlling Automated Page Indexing
While search engine indexing is nice, it's also important to tell search engines which sections of your site should not be indexed - for example, guestbook pages, user account information or shopping baskets. OXID eShop accomplishes this in two ways:

1. It attaches the rel = "nofollow" attribute to links that point to these pages, as below: &lt;a href="http://oxid.localhost/my-password/" rel="nofollow"&gt;My Password&lt;/a&gt; 2. It includes an additional &lt;meta&gt; element in the headers of these pages indicating that they should not be indexed or ranked higher than usual, as below: &lt;meta name="ROBOTS" content="NOINDEX, NOFOLLOW"&gt; Adding these elements tells search engines like Google not to give those links additional weight in their ranking algorithms. More information on the "nofollow" directive can be found at the official Google blog and on Wikipedia.

For older search engines, OXID eShop also includes a $OXID/robots.txt file that is used to instruct automated Web spiders to skip these pages of the site. Here's a snippet of this file: User-agent: * Disallow: /admin/ Disallow: /core/ Disallow: /tmp/ Disallow: /views/ Disallow: /setup/ ... As the above discussion illustrates, the developers of OXID eShop have given a great deal of thought and attention to ensuring that shop URLs are convenient, consistent and optimized for search engine indexing. Auto-generated product and category URLs, manual URL customization, support legacy URLs from earlier versions, the use of &lt;meta&gt; tags to provide additional descriptive information for each page, and the use of a robots.txt file to control the activities of automated crawlers are just some of the features of this SEO implementation, which is without doubt the most sophisticated and flexible one yet.