Skip to content
thofrey edited this page Apr 1, 2014 · 6 revisions

Table of Contents

  1. Overview
  2. Configuration Syntax
  3. Using Patterns
  4. Additional Implementation Information
  5. Common Errors
  6. Frequently Asked Questions

Overview

One of the Mach-II XML configuration file sections that can become rather unruly is the <page-views> section. A smart developer will use some sort of convention when structuring views and page-view names. However, this becomes rather tedious over time as the size of the application grows because you have to manually add each <page-view> in XML. It can be prone to error because it's easy to forget to add a new <page-view>. View loaders are a CFC that would allow a developers to load views based on convention such as using an ANT-style path matching pattern.

Using the pattern view loader, each directory and file name would be translated into a page-view name using a configurable delimiter. For example if a view with the path of /aboutUs/index.cfm was found, it would be translated into a page-view name of aboutUs.index. The translation starts with directories and the file name that start after the ANT-style pattern end. Therefore, a deeply nested directory may require a prefix.

The addition of view loaders would allow developers to auto-register page-views by convention thus reducing a normally tedious task of registering views. Also, developers could define multiple view-loaders in the page-views section or create their own loader by extending a particular Mach-II CFC.

Configuration Syntax

As always with new features to Mach-II, bundled view loaders will use "smart" defaults with the option to use explicit configuration for custom situations. The Mach-II 1.8 release will ship with one view loader bundled that matches views by a ANT-style wildcard pattern matching like algorithm.

Smart Defaults Syntax

    <page-views>
        <!-- This would load all views with the pattern of "/views/**/*.cfm"
            which is the most basic and common pattern -->
        <view-loader type="MachII.framework.viewLoaders.PatternViewLoader" />

        <!-- Normal static page-view nodes are allowed -->
        <page-view name="someView" page="/views/someView.cfm"/>
    </page-views>

Customized Configuration Syntax

    <page-views>
        <view-loader type="MachII.framework.viewLoaders.PatternViewLoader">
            <parameters>
                <!-- An ANT-style patterns using wildcards to find views to load -->
                <parameter name="pattern" value="/views/**/*.cfm" />

                <!-- A string to prefix the <page-view> name with (matches only
                    starts after first pattern character is detected).
                    Optional, showing default value if attribute is omitted -->
                <parameter name="prefix" value="" />

                <!-- Character to use when building the <page-view> names.
                    Optional, showing default value if attribute is omitted -->
                <parameter name="nameDelimiter" value="." />

                <!-- A list or array of ANT-style patterns or static paths to
                    exclude from the pattern search routine.
                    Optional, takes a list or an array -->
                <parameter name="exclude" value="/views/includes/**,/views/otherDir/**" />
                - or -
                <parameter name="exclude">
                    <array>
                        <element value="/views/includes/**"/>
                        <element value="/views/otherDir/**"/>
                    </array>
                </parameter>

                <!-- Boolean indicator to throw an exception if no matches are found
                Optional, takes a boolean and defaults to "true" -->
                <parameter name="throwIfNoMatches" value="true"/>
            </parameters>
        </view-loader>

        <!-- Normal static page-view nodes are allowed or additional view-loaders -->
        <page-view name="someView" page="/views/someView.cfm"/>
    </page-views>

Definition Parameter Key Details

Attribute Required Datatype Default Description
pattern recommended string /views/**/*.cfm An ANT-style patterns using wildcards to find views to load. This can start with a relative path (which is relative from the applicationRoot). If you are using a relative, the pattern must start with ./.
prefix optional string [zero length string] A string to prefix the <page-view> name with (matches only starts after first pattern character is detected).
nameDelimiter optional string . [period] Character to use when building the <page-view> names. Example: . = aboutUs.people.peterFarrell, _ = aboutUs_people_peterFarrell, - = aboutUs-people-peterFarrell
exclude optional list (comma delimited) or array [zero length string] A list or array of ANT-style patterns or static paths to exclude from the pattern search routine.
throwIfNoMatches optional boolean true Throws an exception if no matches are found. Used to help debugging otherwise a page-view not found exception is usually generated which does not necessary point to the a problem with the view loader.

Using Patterns

Wilcard Description
* Matches zero or more characters.
? Matches exactly one character.
** Matches zero or more directories.

Example Patterns

Pattern / Prefix / Name Delimiter Pattern Results
/views/products/**/*.cfm
products
Matches (corresponding <page-view> name):
/views/products/index.cfm = products.index
/views/products/SE10/index.cfm = products.SE10.index
/views/products/SE10/details.cfm = products.SE10.details
/views/products/ST80/index.cfm = products.SE80.index
/views/products/ST80/details.cfm = products.SE80.details

Does Not Match:
/views/index.cfm
/views/aboutUs/index.cfm
/views/aboutUs/managementTeam.cfm
/views/**/*.cfm
[no prefix]
Matches (corresponding <page-view> name):
/views/index.cfm = index
/views/aboutUs/index.cfm = aboutUs.index
/views/aboutUs/managementTeam.cfm = aboutUs.managmentTeam
/views/products/index.cfm = products.index
/views/products/SE10/index.cfm = products.SE10.index
/views/products/SE10/details.cfm = products.SE10.details
/views/products/ST80/index.cfm = products.SE80.index
/views/products/ST80/details.cfm = products.SE80.details

Does Not Match:
/views/index.htm
/views/readme.txt
/views/index??.cfm
homePages
Matches (corresponding <page-view> name):
/views/index01.cfm = homePages_index01
/views/index02.cfm = homePages_index02
/views/indexAA.cfm = homePages_indexAA

Does Not Match:
/views/index01.htm
/views/index1.cfm
/views/indexA.cfm
/views/indexOther.cfm
/views/anotherDir/index01.cfm

(Remember that ? matches a single character, so the above example matches only files that start with "index", followed by two wildcard characters and then ".cfm".)

Additional Implementation Information

  • View loaders are configured and run in the order they are defined in the XML.
  • Static <page-view> cannot be overridden by views registered by a view loader.
  • The PatternViewLoader generates <page-view> names starting with directories and file names starting with the path that starts after the pattern. Use the prefix attribute to prepend a string in front of the generated page view name.

Common Errors

  • An error like No matches found for pattern '/views/customPattern/**/*.cfm' in module '' can occur when you include an exclude patterns that are the same or similar to the search pattern. Be sure that your exclude patterns do not duplicate your search pattern. Common debugging technique includes commenting out your exclude patterns and slowing adding them in to find the problematic exclude pattern.
  • The view loader performs an expandPath operation on the value of your applicationRoot property. Your applicationRoot should not be blank. It it needs to be the root directory, then use the value of /.
  • If you are using a relative path in the pattern, the pattern is relative from your applicationRoot property.

Frequently Asked Questions

How do deeply nested directories and prefixes work?

"If the translation starts with directories and the file name that start after the ANT-style pattern end a deeply nested directory may require a prefix."

This means it is possible to get a translation of prefixfoo.viewnameX from this.is.a.deeply.nested.viewnameX by setting a prefix of prefixfoo. For example if your pattern is /this/is/a/deeply/nested/**/*.cfm and you had a prefix of prefixfoo then you would get prefixfoo.viewnameX. The dot path starts of the view translation starts after at the first pattern character, so everything before the double asterisk is left off the dot path that is generated for the view page name.

Clone this wiki locally