Friendly URL Management


"Work in Progress"

Currently migrating the docs from FC3 to FC4 and rewriting to reflect how Friendly URLs work in Farcry 4.x.

See Friendly URL Management for existing docs.

FarCry manages content in a pseudo-object oriented way, through the so called "content object application programming interface" or COAPI. This approach provides tremendous advantages for content management but has the disadvantage of generating URLs that are parameterised by default. Parameterised URLs are intimidating to users and difficult to remember and share.

For example, a typical parameterised URL in FarCry would be:

In contrast, Friendly URLs are defined as internet addresses that are both easy for human users of the web site to read, and also meaningful for automated spiders. FarCry has a special engine for automatically creating and managing Friendly URLs for content generated through the system.

For example, a typical Friendly URL in FarCry would be:

More FU Information

Friendly URL Subsystem

All system level friendly URL management is handled through a specific component, /core/packages/farcry/fu.cfc

Database persistence is done in the "refFriendlyURL" table with the following fields:

  • objectid (pk)
  • refobjectid (objectid of referenced content item)
  • friendlyurl (everything after /go/*, not including query_string)
  • query_string (the query_string of the parameterised URL)
  • status (0: redirect 301, 1: active, 2: active permanent)

status includes an "active permanent" state to accommodate the option for FU's that have been manually created and should consequently not be automatically retired on content editing changes. As content is edited it is envisaged that old FU's will be flagged to 0 while the current active FU will have a state of 1. That is, refobjectid/status:1 should be unique.

Friendly URL Structure

Any content type (core or custom) can record any FU based on both properties and logic stored in the content type, activated during editing, approval or any other stage of the content item lifecycle.

This enables content types to accommodate strategies for developing SEO specific properties. How these SEO properties are populated would be wholly dependent on the edit handler for the content type in question. For example, such a property could be a freeform field, calculated or selectively populated from any form of metadata engine for specific keyword taxonomies.

An example format for the friendly URL might be as follows:

Note in this example we're using the /product/ prefix rather than /go/ seoURLKeyword - user defined property. Users select a word or phrase from a predefined list of options. Multi-word phrases should be separated by hyphens. (i.e. superfriendly-urls)


What happens when Friendly URLs change? FarCry holds onto old URLs, persisting them in the database and flagging them as defunct. That way we can do some better 404 handling in the go.cfm template. By default missed FU look ups perform a second look up for deprecated URLs from the database and then redirecting the user if possible. As a last resort we pass the user through to a 404.cfm handler.

Clients migrating content from old systems can write specific checks in go.cfm, post FU lookup, to map old content to new locations and firing relevant 301 redirects. With the case of historical URLs that don't match the FU pattern (probably most), we'd be proposing that the error handler or Application.cfm/.cfc look for the redirect before abandoning the user to a 404 or missing objectid error.

Redirect in ColdFusion

It is critical to consider the nature of the redirect being performed, namely a 301, in order to preserve search engine page rank and indexation during the move. Ideally this should be done using a specific HTTP header.

<cfheader statuscode="301" statustext="Moved permanently">
<cfheader name="Location" value="">

Extending refObjects

Its possible projects may wish to utilise a cross content-type document id that is different to a CF UUID. For example, the docid might carry through from a legacy system, or simply provide a simplified content key. At this time I can see no issue with extending the refObjects table to incoporate an additional column.


FU's can really be any parameterised URL, including variable-value pairs beyond objectid=UUID. So it is feasible to incoporate sub-navigational context into an FU. However, the real issue is management of the FU and ensuring that accessories such as buildLink.cfm custom tag properly understand the extended concepts.