URL Management Features
Table of Contents
Introduction
Mach-II is the 'C' in the MVC. As the controller, it is only natural that the controller itself should know how to build a url in a format that the framework can understand. Previous versions of Mach-II required the developer to manually build urls for use as hyperlinks in Views ) with the exception of the redirect command when it was introduced in Mach-II 1.0.10 in November 2005. The redirect command built redirect urls based on the information defined its' attributes.). In Mach-II 1.5.0, we are introducing a few new features to make developers lives easier.
BuildUrl()
This new method builds complete urls in application specified format. It will be available to all Mach-II extended CFCs (listeners, filters, plugins and properties) as well as CFM view files. BuildUrl() takes one required argument and two optional arguments. Using this method defaults the module name to the current module or if you are in the base application -- no module name. This utility method automatically incorporates your eventParameter, moduleDelimiter and any SES settings. Also, it will URLEncode any URL argument data.
For example, if you were in your base application:
Syntax
<!--- Passing a pipe (|) delimited list for the urlParameter argument --->
#BuildUrl("displayMusician", "firstName=#event.getArg("firstName")#|lastName=#event.getArg("lastName")#")#
<!--- Passing a struct for the urlParameter argument --->
#BuildUrl("displayMusician", variables.someStructOfNameValuePairs)#
Output
<!--- Default Query String URL ---> index.cfm?event=displayMusician&firstName=Bob&lastName=Dylan <!--- Example SES (Friendly) URL ---> index.cfm/event/displayMusician/firstName/Bob/lastName/Dylan/
Method Arguments
| Argument | Data Type | Required | Default Value | Description |
| eventName | string | yes | n/a | Name of the event you want to build to. Used for building urls to events in the current module |
| urlParameters | string or struct | no | none | String method "urlArg1=urlValue1|urlArg2=urlValue2" A string following the name/value pair format shown above or a struct of parameters where the struct keys will become the names of the urlArgs. |
| urlBase | string | optional | value of urlBase property | Use this attribute to change the base of the url. Defaults to the urlBase property value or default value defined by Mach-II if not explicitly defined in your application. |
Additional Information and Considerations
- That BuildUrl() will not encode complex data types that you pass as urlParameters since complex datatypes cannot be serialized and passed in a url query string.
- When using BuildUrl() in a view inside a module, Mach-II assumes the name of the module in which the current request is being processed. If the view is inherited from a base application in a module, all built URLs will assume this same module (i.e. not the base application module of ""). Thus it recommended to use BuildUrlToModule() for all built URL that are used for global views (i.e. navigation, headers, foots) that could be inherited and used by modules.
- Users of Mach-II 1.8+ can use the a custom CFML tag in the view tag library that is bundled with the framework to build URLs and HTML a tags. For more information on using this easier to use tag, check out the View Tag Library.
- Starting with Mach-II 1.8+, BuildUrl() orders all args alphanumerically so all generated URL remain consistent.
BuildUrlToModule()
This method is similar to BuildUrl() however it allows you to set the module name and following a similar syntax to BuildUrl(). You would use this method if you wanted to build a url to another module or base application.
Syntax
<!--- Passing a pipe (|) delimited list for the urlParameter argument --->
#BuildUrlToModule("bands", "displayMusician", "firstName=#event.getArg("firstName")#|lastName=#event.getArg("lastName")#")#
<!--- Passing a struct for the urlParameter argument --->
#BuildUrlToModule("bands", "displayMusician", variables.someStructOfNameValuePairs)
Output
<!--- Default Query String URL ---> index.cfm?event=bands:displayMusician&firstName=Bob&lastName=Dylan <!--- Example SES (Friendly) URL ---> index.cfm/event/bands:displayMusician/firstName/Bob/lastName/Dylan/
Method Arguments
| Argument | Data Type | Required | Default Value | Description |
| moduleName | string | yes | n/a | Name of the module you want to build the url. Using a value of "" defaults to the base module. |
| eventName | string | yes | n/a | Name of the event you want to build the url. |
| urlParameters | string/struct | optional | none | String method "urlArg1=urlValue1|urlArg2=urlValue2" A string following the name/value pair format shown above or a struct of parameters where the struct keys will become the names of the urlArgs. |
| urlBase | string | optional | value of urlBase property | Use this attribute to change the base of the url. Defaults to the urlBase property value or default value defined by Mach-II if not explicitly defined in your application. |
Additional Information and Considerations
- That BuildUrlToModule() will not encode complex data types that you pass as urlParameters since complex datatypes cannot be serialized and passed in a url query string.
Properties That Affect How URLs Are Constructed
With the introduction of modules, the syntax of an url has become more complex. We added BuildUrl() and BuildUrlToModule() to aid in the construction of urls. We added four new optional properties that control how BuildUrl? constructs URLs.
Property Information
| Property Name | Data Type | Required | Default Value | Description |
| urlBase | string | optional | index.cfm | Use this attribute to change the base of the url. |
| urlParseSES | boolean | optional | false | Changes whether Mach-II will parse the cgi.path_info for SES data. If set to false, Mach-II assumes that your webserver platform is rewriting urls (such as Apache Mod Rewrite or IIS ISAPI Rewrite). By setting urlBase to a zero length string and using your webserver platform rewriting engine, you can have urls without 'index.cfm' in them. |
| urlDelimiters | list - pipe (|) delimited | optional | ?|&|= | Defines the delimiters used to create the query string part of a URL. This property is used to create SES (Friendly) URLs. See below for more information. * first position is the query string delimiter (typically a "?") * second position is the series delimiter (typically a "&") * third position is the pair delimiter (typically a "=") |
| moduleDelimiter | string | optional | : | The delimiter to use between the module name and event name for events in modules. Defaults to ":". |
| eventParameter | string | optional | event | The name of the request parameter that will define the event for the framework to handle. |
How To Do Search Engine Safe (Friendly) URLs
We've added the ability to build urls in whatever format you wish including SES/Friendly urls.
Simply change (or add the property entirely) of the following properties:
<property name="urlParseSES" value="true" /> <property name="urlDelimiters" value="/|/|/" /> <property name="urlBase" value="/index.cfm" />
Setting the properties to above example values will give you SES (Friendly) URLs like:
/index.cfm/event/displayMusician/firstName/Bob/lastName/Dylan/ /index.cfm/event/bands:displayMusician/firstName/Bob/lastName/Dylan/
Additional Information and Considerations
- The value of urlBase must be an absolute path (no domain required). For example, if your application lives at http://www.example.com/myapp/index.cfm then change the value to "/myapp/index.cfm" or all generated urls will be relative thus causing strange urls parsed by the browser such as appending a clicked link on top of another link.
- It is impossible to encode all data into a SES url. This is because it uses the path_info variable from the cgi. This was originally design in the HTTP spec to take path information to invoke cgi scripts in different contexts. It has subsequently been used to leverage SES URLs. Problems start occurring when you start trying to encode a variable that takes a path and uses / or \. On IIS, it continues to pass this data along to Mach-II while on Apache it usually throws an error saying it cannot find a cgi script is a particular context. A possible workaround is to encode your paths with a different character denoting / and transform it back to a real path when using that event arg.
- If you change property value of urlBase to "" (empty string) when using SES URLs, you will have to use an URL rewriting tool such as mod_rewrite for Apache or one of many ISAPI filters for IIS. A tool is required because without a path and file name your web server will not know to forward the request to your CFML engine. Without using a tool to rewrite the URL, you will get an error from your web server similar to The requested URL /event/somepage was not found on this server. This is not a Mach-II defect, but the method in which web servers process requests.
TODO: Add information on reserved characters in path info.
Redirect Command
We've vastly improved the redirect command in Mach-II 1.5 and it now allows you redirect (via a cflocation) and persist complex data types across the redirect. Another enhancement allows you to optionally set the HTTP status code sent to the browser when Mach-II performs a redirect.
New Redirect Command Attributes
| Attribute Name | Data Type | Required | Default Value | Description |
| persist | boolean | optional | false | Indicates that you "persist" event arguments across a redirect (i.e. cflocation). This allows you to persist complex data types (i.e. structs, cfcs, arrays, etc.) in a temporary scope which is automatically picked up on the other side of the redirect and populated into the event. |
| persistArgs | list - comma (,) delimited | optional | all desired event-args | List of event arguments to persist across the redirect. If this attribute is omitted or left blank, all event args currently in the event will be persisted across the redirect. |
| statuscode | Allowed values: permanent, temporary, prg | optional | temporary | Type of HTTP status code to send to the browser for the redirect. Defaults to "temporary" if not defined (emulates the same behavior as previous versions of Mach-II or the behavior of a <cflocation>). * "permanent" sends a "301 Moved Permanently" HTTP status code * "temporary" sends a "302 Found" HTTP status code * "prg" sends a "303 See Other" HTTP status code which is "correct" status code to send if you post a form and redirect the user agent to a "complete" page in order to stop multiple refresh posts |
| module | string | optional | n/a | This lets you redirect to an event in another module. |
All persisted events are multi-threaded and is handled by the framework. Mach-II automatically appends an URL parameter with a modified UUID which corresponds to persisted event data when the redirectPersistParameterLocation is url (default) or sets a cookie named persistId when the redirectPersistParameterLocation is cookie without modifying the URL.
Example URLs when redirectPersistParameterLocation is set to url:
http://www.example.com/index.cfm?event=somePage&persistId=B7BAE959CEE07278344E91671DA376F4
http://www.example.com/index.cfm/event/somePage/persistId/B7BAE959CEE07278344E91671DA376F4/
Properties That Affect The Redirect Command
| Property Name | Data Type | Required | Default Value | Description |
| redirectPersistParameter | string | optional | persistId | The name of the URL parameter used to identify persisted data. |
| redirectPersistScope | Allowed values: server, application, session | optional | session | The scope to use to save persisted data in. |
| redirectPersistParameterLocation | Allowed values: url, cookie | optional | url | The location to place the persist id. Usually is placed in the URL, but setting to cookie will set a temporary cookie with the persist id value leaving the URL without a persist id. This feature was introduced in Mach-II 1.8 |
Mach-II also cleans up any lost persisted event data (if for example a browser does not complete request the new page after the redirect) after a short period of time (3 minutes).
Additional Information and Considerations
- Relative paths to things like stylesheets and javascript pages may break when implementing URL management. These can be easily fixed by making them absolute calls instead of relative ones.
- If you are using SES URLs and your index.cfm does not sit at the root of your domain or subdomain, you may need to use the <base href="http://www.example.com/myApp/" /> HTML tag which specifies a base URL for all links on the page. This must be placed in the <head> element of your page. For additional information, read more on the base tag.
- If the MACHII_CONFIG_MODE of your application is set to 1 (always reload), redirect persist will not function correctly because it looses the reference to the persistence cache when the application is reloaded. Set your MACHII_CONFIG_MODE to 0 or -1.
