Since the "Core" contentRenderer is a "core" file, it shouldn't be modified directly. Instead, if you wish you to override any of the default settings or methods found in the "core" contentRenderer, Mura will first check the theme, and then the site for a contentRenderer.cfc. If the matching setting or method is found, it will use the custom setting or method in lieu of Mura's default "core" setting or method. You only need to define the setting(s) or method(s) you wish to override in your "Site" or "Theme" contentRenderer.

Custom Rendering Methods

In addition to overriding any of the default settings and methods found in the "Core" contentRenderer, any custom rendering methods defined in the "Site" or "Theme" contentRenderer are available via the Mura Scope. For example, if you have the following method defined in your "Site" or "Theme" contentRenderer:

Lookup Hierarchy

Mura uses the following lookup hierarchy for settings or methods found in a contentRenderer.cfc. If the setting or method is defined in the first file, Mura will use it and ignore any other identically named methods found in the remaining files.

"Theme" contentRenderer

../themes/{ThemeName}/contentRenderer.cfc

"Site" contentRenderer

{context}/sites/{SiteID}/includes/contentRenderer.cfc

"Core" contentRenderer

{context}/core/mura/content/contentRenderer.cfc

contentRenderer Settings

The vast majority of the contentRenderer settings allow developers to apply custom classes to Mura's modules. This allows developers to use CSS to control the style and display of Mura's modules, without having to override the rendering methods or modules themselves to achieve the desired result.

Mura allows you to override its default contentRenderer settings on a site-by-site basis. To override a setting, simply place a reference to the setting and your desired value in your "Site" or "Theme" contentRenderer.cfc.

Example

Reference

A reference for Mura's "Core" contentRenderer.cfc settings is outlined below. Keep in mind the vast majority of the contentRenderer settings are specific to Mura's modules, and as such, most of these settings are merely the CSS classes that will be applied to them.

Note: The settings listed below are the "default" settings, and many of them may be overwritten in Mura's default theme. Please refer to the theme's contentRenderer.cfc file to review the theme's settings.

This allows you to start standard navigation behavior at lower navigation levels. For example, this would be useful if you have a section of your site that should have its own primary navigation, such as a Member's only area with a custom layout template.

navDepthLimit

int

1000

This sets the maximum depth that standard navigation will follow.

navParentIdx

int

2

navGrandParentIdx

int

3

navDepthAdjust

int

0

navSelfIdx

int

1

deferMuraJS

boolean

false

If true, Mura will add a "defer" attribute to the script reference for mura.min.js so that the script will be executed when the page has finished parsing.

jsLib

string

jquery

This determines what JavaScript library Mura should use with its built-in display objects. Valid options are:

jquery

prototype

jsLibLoaded

boolean

false

This allows developers to not rely on Mura to load the default JavaScript framework and simply add it to their theme's HTML head area.

This allow developers to choose whether site personalizations such as ratings and favorites are attached to simple cookies or an actual Mura user. Users do not need to login in order to save cookie-based personalizations. Valid options:

user

cookie

hasEditableObjects

boolean

false

If true, enables editable objects (Version 6.x only)

asyncObjects

boolean

true

If true, Mura will load display objects asynchronously.

asyncRender

boolean

false

queueObjects

boolean

true

layoutManager

boolean

false

If true, will allow administrators to edit display objects via the front-end of the site. (Version 7.x)

legacyObjects

boolean

true

If false, Mura will enable the inline edit features of Mura (Version 7.x)

If true, the front end toolbar will be rendered for administrative users.

showMemberToolbar

boolean

If true, the front end toolbar will be rendered for site members

showEditableObjects

boolean

If true, editable display objects like components and content collections will be rendered. (Version 6.x)

showInlineEditor

boolean

If true, will display the Inline Edit button on the front end toolbar for administrative users. (Version 7.x)

renderHTMLQueues

boolean

true

If true, Mura will render the request's HTMLHeadQueue and HTMLFootQueue.

preloaderMarkup

string

empty string

Allows developers to include a custom preloader.

bodyMetaImageSizeArgs

struct

{size="medium"}

bodyMetaImageClass

string

thumbnail

A CSS class applied to the primary associated image.

navsize

int

50

An integer value to control the maximum number of navigational items to output for Mura generated navigation.

imageClass

string

img-thumbnail

A CSS class applied to the primary associated image when displayed in a list such as a collection.

categoriesNestCheckboxClass

string

checkbox

A CSS class applied to category checkboxes.

generalWrapperClass

string

well

A CSS class applied to general wrapper HTML elements.

Heading Markup Settings

When Mura outputs headings, the following settings may be used. The following settings are also used to control the heading tags used for the HTML Editor's "Format" select menu options. The defaults listed below are based on the concept that <h1> tags are reserved for the "Site Name" or logo area of the layout templates, and page titles begin with <h2> tags.

Setting

Type

Default

headline

string

h2

subHead1

string

h3

subHead2

string

h4

subHead3

string

h5

subHead4

string

h6

subHead5

string

h6

Alert Markup Settings

When Mura outputs an alert, the following settings may be used.

Setting

Type

Default

alertSuccessClass

string

alert alert-success

alertInfoClass

string

alert alert-info

alertWarningClass

string

alert

alertDangerClass

string

alert alert-error

Table Markup Settings

When Mura outputs a table, the following settings may be used.

Setting

Type

Default

tableClass

string

table table-bordered table-striped

tableHeadClass

string

empty string

tableHeaderClass

string

empty string

tableBodyClass

string

empty string

tableRowClass

string

empty string

tableCellClass

string

empty string

tableFooterClass

string

empty string

Module (Display Object) Settings

The vast majority of contentRenderer settings are used to control the CSS classes for HTML markup of Mura's baked-in modules. Mura's modules and their associated settings are described below.

Navigation

The markup for the various types of navigational modules can be found in the files located under:

{context}/core/modules/v1/nav/

Setting

Type

Default

navWrapperClass

string

sidebar-nav well

navLIClass

string

empty string

liHasKidsClass

string

empty string

liHasKidsAttributes

string

empty string

liCurrentClass

string

current

liCurrentAttributes

string

empty string

liHasKidsNestedClass

string

empty string

aHasKidsClass

string

empty string

aHasKidsAttributes

string

empty string

aCurrentClass

string

current

aCurrentAttributes

string

empty string

ulNestedClass

string

empty string

ulNestedAttributes

string

empty string

ulTopClass

string

navSecondary

ulPaginationClass

string

navSequential

ulPaginationWrapperClass

string

pagination

aNotCurrentClass

string

empty string

navCalendarWrapperClass

string

svCalendar

navCalendarTableClass

string

table table-bordered

navSequentialWrapperClass

string

pagination

navSequentialULClass

string

empty string

tagCloudWrapperClass

string

svTagCloud

navArchiveWrapperClass

string

empty string

navArchiveListClass

string

empty string

navBreadcrumbULClass

string

breadcrumb

Form

The Form module markup can be found in the files located under:

{context}/core/modules/v1/form/

Setting

Type

Default

formWrapperClass

string

well

formFieldWrapperClass

string

control-group

formFieldLabelClass

string

control-label

formInputWrapperClass

string

input-addon

formInputClass

string

form-control

formCheckboxClass

string

empty string

formButtonWrapperClass

string

btn-group

formButtonInnerClass

string

empty string

formButtonClass

string

btn btn-default

formRequiredWrapperClass

string

empty string

Form Builder

The Form Builder module markup can be found in the files located under:

The Mura [m] Tag

Developers need to use Mura Tags because hash tags (#) are ignored when entered as text in the HTML Editor. Hence, you can only render a CFML variable, or function call.

Globally Enable/Disable the Mura Tag

To globally enable or disable the Mura Tag, open the file located under {context}/config/settings.ini.cfm. Locate the enablemuratag key, and set the value to true to enable the Mura Tag, or false to disable the Mura Tag.

If enablemuratag is set to false, the Mura tag button will not appear on any HTML Editors. In addition, the Mura Tags will not be parsed as CFML, and will only display as a string of text, as it was entered into the HTML Editor.

Enable/Disable the Mura Tag on a Site-by-Site Basis

If you wish to enable or disable the Mura Tag on a site-by-site basis, you may edit the Site or Theme contentRenderer.cfc file located under:

Site contentRenderer.cfc

{context}/sites/{SiteID}/contentRenderer.cfc

Theme contentRenderer.cfc

../themes/{ThemeName}/contentRenderer.cfc

Then, add this.enablemuratag=true to enable, or this.enablemuratag=false to disable. This setting overrides the global setting described above.

Rendering Mura Tags

Mura Modules & Display Objects

Mura's baked-in modules are managed via the front-end user interface. Modules are sometimes referred to as "display objects" because often times, that's how the module itself is used. However, a Mura module does not have to contain a "display" of any kind. Modules can be complete applications, or simply contain some custom logic that is triggered based on a desired event.

Each of Mura's modules contain some server-side logic, basic markup, styling, and sometimes include JavaScript. In this section, you'll learn how to safely modify this logic, markup, styling, and/or JavaScript, and do so without worrying about your changes getting overwritten whenever Mura's files are updated. In addition, you'll learn how to create your own, custom modules too.

Modifying Mura's Modules

Mura's base modules (display objects) are located under the following directory:

{context}/core/modules/v1/

As illustrated in the image below, there are more modules than the ones listed.

You shouldn't modify any of the files in these directories directly. If you choose to do so, you run the risk of your changes being overwritten whenever Mura is updated to the latest version.

Instead, copy the desired directory and all of its files, then paste it under one of the locations listed in the "Lookup Hierarchy" section below. Then, you can safely make your modifications without fear of losing any of your changes the next time Mura is updated.

Registering a Custom "modules" Directory

While Mura automatically scans for modules in the directories specified in the "Lookup Hierarchy" section below, you may register a custom "modules" directory using the code example below.

m.siteConfig().registerModuleDir(
dir='/path/to/your/modules/'
);

The directory path should be a logical path to a CFML directory, and is usually registered in the onApplicationLoad() event.

Lookup Hierarchy

As mentioned under "The 'Modules' Directory" section, Mura uses the following lookup hierarchy when searching for modules, and aborts the lookup process once the target module has been located:

Theme modules are only used when the specified theme is actively assigned to a site. Keep in mind themes may be located under either the global themes directory ({context}/themes/{ThemeName}), or under a site ({context}/sites/{SiteName}/themes/{ThemeName}).

Site

{context}/sites/{SiteName}/modules/

Site modules are shared across all themes within the specific site.

Global

{context}/modules/

Global modules are shared across all sites under a single Mura instance.

Core

{context}/core/modules/v1/core_assets/modules/

These are the "core" modules or display objects which may be copied and placed into any of the directories above to be safely modified.

Anatomy of a Module

In addition to understanding how Mura's modules are constructed, Mura developers may use the information below to create their own, custom modules.

Directory Structure

First, create a directory under a known or registered "modules" directory. For example, ../modules/mymodule/. Within the {module} directory, you may have the following files and/or directories:

File or Directory

Req/Opt

Description

index.cfm

Optional

If your module will be used as a "display object", this file will contain the body or view used by Mura for display file itself. See example "index.cfm" file section below.

config.xml.cfm

Optional

This is the configuration file for the module itself. This file also allows you to include custom image sizes, class extensions, and more. See example "config.xml.cfm" file section below. Also visit the Elements Of The "config.xml.cfm" File section for information about available elements and attributes.

configurator.cfm

Optional

This file allows developers to include a form with configuration options which appear on the module configuration panel when using the Inline Edit feature. See example "configurator.cfm" file section below.

/model/

Optional

If you wish to leverage Mura ORM, the module could have its own "model" directory, which in turn could also include a "beans" and/or "handlers" directory too. See Mura ORM Configuration section for more information about the "model" directory.

/content_types/

Optional

You may also include custom content types. This is useful for keeping content types directly related to specific module(s) together, in a unified directory structure. See Content Types section for more information.

/modules/

Optional

You may also nest custom modules. This is useful for keeping related modules together, under one, unified module itself. One caveat is that if you choose to display the nested object on the parent object, content managers will not be able to access the nested object's configurator, if it has one. Because of this, you may wish to either omit the "contenttypes" attribute from your config.xml.cfm's <mura ...> node, or explicitly add contenttypes="" so that the nested object will not appear in the module panel's UI. If you need configurable options for the nested object, you should include the options on the parent object's configurator. To include the nested object in the view of the parent object, use the following syntax: #m.dspObject(object='{objectName}', objectparams=objectparams)#.

Example "index.cfm" File

The example below illustrates what an "index.cfm" file could contain. However, you may include your own custom markup, code, and more.

If you wish to add any CSS or JavaScript to the browser for your module, you'll need to use MuraJS to help you. The example below leverages the loader() method to load both CSS and JavaScript. Simply add this code to your "index.cfm" file. You may have to change the path(s) to match your specific directory structure, and needs.

Visit the MuraJS section to learn more about Mura.loader() capabilities.

Rendering Via JavaScript

If your module will be rendered using only JavaScript, your index.cfm file should only contain the following code:

<cfset objectparams.render="client">

Choosing this option means you'll have to load your JavaScript by using a custom event handler method, as shown below.

// ../yourmodule/model/handlers/yourhandler.cfc
component extends='mura.cfobject' {
function onRenderStart(m) {
// if script should be included in the <head>
arguments.m.addToHTMLHeadQueue('<script src="/path/to/script.js"></script>');
// OR
// if script should be included before closing </body> tag
arguments.m.addToHTMLFootQueue('<script src="/path/to/script.js"></script>');
}
}

Mura Content Types

In addition to using some of Mura's content-related event hooks, developers can control the rendering of the body area by targeting a content's Type and Subtype. This feature also applies to any custom Class Extensions. For example, "Folder/Contacts", "Page/Contact", etc.

Mura automatically scans the following directories for custom content types:

{context}/themes/{ThemeName}/content_types/

{context}/sites/{SiteID}/themes/{ThemeName}/content_types/

{context}/sites/{SiteID}/content_types/

../content_types/{type}/content_types/

../content_types/{type}_{subtype}/content_types/

Or, you can register any directory you want by using the following syntax:

m.siteConfig().registerContentTypeDir(
'/path/to/your/content_types/'
);
// Path is a logical path to a CFML directory
// Usually registered in onApplicationLoad();

Note: This feature only works if the layout template is using m.dspBody() to render the body area.

Control Body By Type/Subtype

You target the body's Type/Subtype by a conventional directory structure.

For example, you could target content by only its Type:

../content_types/{type}/
// If you wish to target 'Page'
../content_types/page/index.cfm

Or, you can target by both the Type, and its Subtype:

../content_types/{type}_{subtype}/
// If you wish to target 'Page/Contact'
../content_types/page_contact/index.cfm

Anatomy of a {type}_{subtype} Directory

As previously mentioned, you create a directory under a known or registered "content_types" directory by using {type}_{subtype} (e.g., ../content_types/page_contact/ or ../.content_types/component_default/, etc.). Within the {type}_{subtype} directory, you may have the following files and/or directories:

File or Directory

Req/Opt

Description

index.cfm

Required

This is the body or view used by Mura for display file itself. At a minimum, this file should contain <cfoutput>#m.renderEditableAttribute(attribute="body",type="htmlEditor")#</cfoutput>, if you wish to see any text entered into the "Content" area. See example "index.cfm" file below.

If you wish to leverage Mura ORM, the content type could have its own "model" directory, which in turn could also include a "beans" and/or "handlers" directory too. See Mura ORM Configuration section for more information about the "model" directory.

/modules/

Optional

You may also include custom modules. This is useful for keeping modules and/or display objects directly related to specific content types together, in a unified directory structure. See Modules section for more information. See below for information on how to output modules in your layout template.

/content_types/

Optional

You may include a nested "content_types" directory. This is a great way to keep related code items together.

Example "index.cfm" File

The example below illustrates what an "index.cfm" file could contain. However, you may include your own custom markup, code, and more.

How To Output Modules

To output a module (display object) in your custom body layout, use the following syntax:

<cfoutput>
#m.dspObject(object='{objectName}')#
</cfoutput>

When hardcoding a module in your layout, the "Delete" button will not appear for content managers when using the "Inline Edit" mode.

Including Configurable Modules

The first thing to understand about including configurable modules in your custom body layout is there can only be one (1) module that is configurable. Whichever module you wish to be configurable should include a "objectparams" parameter, and include the "objectparams" as the value, as shown below:

If you attempt to include multiple configurable modules using the code example above, the first module will be configurable, and all others will not. This means, when you select "Inline Edit" mode, only the first configurable module will include the pencil icon and actually be configurable.

To include additional modules, you may pass in any "objectparams" parameters as an object, as show in the example below:

Response Format

On success, the HTTP status code in the response header is 200 OK and the response body contains a data object in JSON format. On error, the header status code is an error code and the response body contains an error object.

Example Response

{
"data": {
"key": "value"
}
}

Response Status Codes

The JSON API uses the following response status codes:

Status Code

Description

200

OK - The request has succeeded. The client can read the result of the request in the body and the headers of the response.

400

Bad Request - The request could not be understood by the server due to malformed syntax. The message body will contain more information; see Error Handling, below.

401

Unauthorized - The request requires user authentication or, if the request included authoriation credentials, authorization has been refused for those credentials. Also, the JSON API feature may not be enabled for the site; see How To Enable, above.

403

Forbidden - The server understood the request, but is refusing to fulfill it. For example, requestor does not have permission to a requested method.

404

Not Found - The requested resource could not be found. This error can be due to a temporary or permanent condition.

Error Handling

When an error occurs, the response data attribute will not exist. The response will instead contan an error attribute.

History

FindQuery

Endpoint

GET https://yourdomain.com/{context}/index.cfm/_api/json/v1/{siteid}/{entityname}/?

OR

GET https://yourdomain.com/{context}/index.cfm/_api/json/v1/?method=findquery&siteid={siteid}&entityname={entityname}/?

Request & Query Parameters

Parameter

Value

context

The path to where Mura CMS resides within the webroot (typically, an empty string).

siteid

The SiteID of where the entity will be stored.

entityname

The entity's name. For example: ?entityname=content

fields

Optional. A comma-separated listed of fields to return. For example: ?fields=title,summary,contentid

maxitems

Optional. Limit the number of records to return. For example: ?maxitems=10

itemsperpage

Optional. Sets the desired number of items to return for each page. For example: ?itemsperpage=3

pageindex

Optional. Sets the desired page for pagination. For example: ?pageindex=2

sort

Optional. Control the sort order and direction of entities by specific attributes/fields. To sort decending, prefix the attribute/field with a minus sign (-). You may explicitly use the plus sign (+) to indicate the default setting of ascending. For example, to sort by "credits" ascending, and "title" decending: ?sort=credits,-title

Request & Query Parameters

The path to where Mura CMS resides within the webroot (typically, an empty string).

siteid

The SiteID of the site attempting to login to.

username

The User's username.

password

The User's password.

Example Response

{
"data": {
"status": "success"
}
}

data object

Key

Value Type

Value Description

status

string

success or failed, depending on the result of the attempt to login.

History

Added in version 6.2

Mura.js

Mura.js originally began as a lightweight utility to decouple Mura's dependency on jQuery, a popular JavaScript library. Since its inception, Mura.js has also grown into a JavaScript framework for interacting with Mura's JSON API, which allows Mura CMS to be the main content creation hub within an organization, and allows developers to build their applications as pure JavaScript clients.

Chaining Promises

The following example illustrates how you could handle multiple Ajax requests with Mura.js using JavaScript Promises chaining, and avoid the "pyramid of doom". In other words, avoid nesting your Ajax requests.

Mura ORM With Mura.js

Mura.js CRUD Functionality

Outlined below are code examples for performing basic CRUD operations on Mura ORM objects/entities via Mura.js. For developers who are primarily used to working with server-side languages, it may take a little time to adjust to working on the client side, because we need to "wait" until the object/entity is loaded in order to work with it. For this reason, it may be helpful to review how to work with JavaScript Promises.

Loading/Reading Mura ORM Objects/Entities

This example simply illustrates how to load a Mura ORM entity, using Mura.js.

Mura.loader()

The Mura.loader() method is for JavaScript and CSS parallel loading with dependencies management. Using this method also prevents duplicate JavaScript and/or CSS files from being loaded.

There are two primary methods associated with Mura.loader(), loadjs() and loadcss() described below.

loadjs(url, cb)

Parameter

Description

url

If the first parameter is an array, files will be loaded asynchronously. If it's a string, the files will be loaded synchronously. If the file is located under your theme, you may use m.themepath to dynamically generate the path to the theme location. For example: loadjs(m.themepath + '/script.js')

cb

A callback function to execute when all scripts have been loaded.

loadcss(url, attrs, cb)

Parameter

Description

url

The URL for the CSS file. If the file is located under your theme, you may use m.themepath to dynamically generate the path to the theme location. For example: loadcss(m.themepath + '/file.css')

attrs

You may optionally pass in an object to specify the media type attribute for the CSS file. For example: loadcss(m.themepath + '/file/css', {media: "print"})

Valid options include:

all

aural

braille

embossed

handheld

print

projection

screen

tty

tv

cb

A callback function which executes immediately.

Examples

This example illustrates the basic syntax for loading a JavaScript file, with a desired callback function.

The example below illustrates loading some scripts in parallel with another batch of scripts being loaded in order. In the example below, the first loadjs() will be executed in parallel of the second loadjs(). However, in the second loadjs(), the myDependentLib.js file won't be loaded until myRequiredLib.js has finished loading. Then, when they've finished loading, the callback function will execute.

Modules With Mura.js

As introduced in the Anatomy of a Module section, developers may choose to render their modules using purely JavaScript. When doing so, the module's index.cfm file should only contain the following line of code, which informs Mura it has nothing to render via server-side processing, and all rendering will occur via the "client" or browser.

<cfset objectparams.render="client">

Then, in order to load your script(s), you'll need to use a custom event handler, and register the onRenderStart event to dynamically load your script file(s), as illustrated below.

// ../yourmodule/model/handlers/yourhandler.cfc
component extends='mura.cfobject' {
function onRenderStart(m) {
// if script should be included in the <head>
arguments.m.addToHTMLHeadQueue('<script src="/path/to/script.js"></script>');
// OR
// if script should be included before closing </body> tag
arguments.m.addToHTMLFootQueue('<script src="/path/to/script.js"></script>');
}
}

By using addToHTMLHeadQueue and/or addToHTMLFootQueue, your scripts will only be loaded once, regardless of how many times your module has been applied to the layout.

The Custom JavaScript File

Assuming you've followed the instructions above to get your custom script file included into either the "head" portion of your theme, or before the closing "body" tag, you will most likely want to control when your script(s) are executed. However, you may also simply allow your scripts to run at all times.

Running Scripts on Every Request

If you merely wish for your script(s) to execute, regardless of whether or not your module has been applied to the layout, then you may simply include any JavaScript you wish. In other words, since your script files are being added on every request via your custom event handler's onRenderStart method, your scripts will automatically execute. This is useful for merely adding a utility script, such as a tracking script, etc.

The content of your script file may look as simple as the following example.

// your-script.js
console.log('Hello from your module!');

Running Scripts Only If Your Module Has Been Applied

Unless your scripts are utilities, such as tracking scripts, developers will most often wish their scripts to execute only when the module has been applied to the layout. In addition, when the module includes a configurator, each instance of the module will have access to its own configuration information.

First, it's important to understand that modules rendered via the client, are automatically registered to Mura's namespace under Mura.Module.YourModuleDirectoryName. Also, Mura will automatically invoke a "render" method via Mura.UI, on each request. By defining your own "render" method, you're able to pretty much do whatever you want.

The example below illustrates a skeleton script. You should substitute "yourModuleDirectoryName" with the actual directory name of your display object.

Forms & Mura.js

Mura forms are loaded asynchronously. So, if you wish to run some scripts, you need to use a special method to "reopen" the form, and then add your scripts. This can be done by leveraging a special Mura.js method: Mura.DisplayObject.Form.reopen({});.

Once the form has been "reopened," simply leverage one or more of the predefined events from the code example below to inject any custom logic.

NOTE: If not using deferred Mura.js then you do not need to reopen the display object classes within a Mura.preInit() method. The option to defer the loading of Mura.js was introduced in Mura 7.1 and is controlled by the this.deferMuraJS theme contentRenderer.cfc value.

Internationalization & Localization

Mura utilizes resource bundles to internationalize various areas of the user interface, making the code locale-independent.

Resource bundles are .properties files, located under specified directories in Mura. These .properties files, or resource bundles, are named to indicate the language code, and country code. For example, the language code for English (en) and the country code for United States (US) would be represented as en_US.properties. If Mura cannot find a direct language and region match, it will search for a language match. If a locale's language cannot be found, Mura will fall back to its default of English, or en_US.properties.

The file itself is comprised of key-value pairs. The keys remain the same throughout each of the .properties files, and the value is translated into the file's designated language. If Mura is searching for a specific key-value pair within a translation, and cannot locate it, Mura will fall back to the English translation.

The image below illustrates the en_US.properties file side-by-side with the es_ES.properties file:

Lookup Hierarchy

Mura automatically searches for resource bundles under specific directories, and uses the key-value pair(s) found in the order outlined below. If a resource_bundles directory does not exist in the following locations, you may safely create one, and place your resource bundle files there.

Module

../{module}/resource_bundles/

Module (aka "Display Object") resource bundles are used for the specific module itself.

Content Types

../content_types/{type}_{subtype}/resource_bundles/

Content Types resource bundles are used for the specified content type.

Theme

../{ThemeName}/resource_bundles/

Theme resource bundles are only used when the specified theme is actively assigned to a site.

Site

{context}/sites/{SiteID}/resource_bundles/

Site resource bundles are shared across all themes within the specified site.

Global

{context}/resource_bundles/

Global resource bundles are shared across all sites under a single Mura instance.

Core

{context}/core/modules/v1/core_assets/resource_bundles/

If the requested key-value pair is not defined in any of the locations above, Mura will use the "core" resource bundles located here for Mura's modules.

Note: Admin-area resource bundles are located under {context}/core/mura/resourceBundle/resources/. However, as of v7.1, many key-value pairs are not able to be overwritten using the technique described above at this time. Allowing for this option is under consideration for a future version.

Contribute

Custom Keys

As previously documented, Mura searches for custom ".properties" files, under the directories listed in the "Lookup Hierarchy" section.

You don't have to include all of the key-value pairs from the original files. You only have to include the key-value pairs you wish to override. In addition, if you have any custom keys you would like to use in your site, you can simply include them in your custom ".properties" files.

Displaying Custom Keys

To output a custom key-value from your ".properties" file, simply use m.rbKey({keyName}).

So, for example, to output a key of "myCustomString", use the following syntax.

<cfoutput>
#m.rbKey('myCustomString')#
</cfoutput>

Custom Factories

Mura allows you to create your own resource bundle factories, and fall back to Mura's original lookup hierarchy when a requested key-value is not found. This is especially useful when creating plugins, or integrating a custom application.

The code example below demonstrates how you could go about creating a custom resource bundle factory.

So, for example, to output a key of "myCustomString", with a custom factory variable named "customFactory", use the following syntax.

<cfoutput>
#customFactory.getKey('myCustomString')#
</cfoutput>

Caching

Mura has a built-in caching mechanism that, when enabled, will store data in memory for reuse. The purpose for this is to improve overall site performance, by decreasing the amount of reads to the database. Mura's caching uses a "lazy load" approach, which means data won't be cached until it's called upon the first time.

How to Enable/Disable Site Caching

Follow the steps below to enable and/or disable site caching.

From the back-end administrator, on the main navigation, click Site Settings, then select Edit Settings.

From the Site Settings screen, select the Basic tab.

Scroll down to Site Caching.

Select On to enable site caching.

Select Off to disable site caching.

After making your selection, click Save Settings.

Cache Free Memory Threshold

By default, when Site Caching is enabled, Mura will only store data into memory when the Java virtual machine (JVM) has at least sixty percent (60%) available memory. You may choose to set an alternate minimum desired percentage by following the steps outlined below.

From the back-end administrator, on the main navigation, click Site Settings, then select Edit Settings.

From the Site Settings screen, select the Basic tab.

Scroll down to Cache Free Memory Threshold (Defaults to 60%), and enter in your desired percentage amount. If you enter zero (0), Mura will revert to using its default setting of sixty percent (60%).

After entering your desired amount, click Save Settings.

cf_CacheOMatic Tags

One of the easiest ways to improve the performance of your site, is to use proven caching techniques. In addition to the native caching strategies for CFML, Mura also offers a special, custom tag, <cf_CacheOMatic>, to use for expensive database transaction code, or other time-consuming CFML code that doesn't need to be executed during each request.

Using Mura's <cf_CacheOMatic> tag allows you to add data to Mura's cache. The tag only works when Site Caching is enabled, which is a great reason to use it since you can easily disable it, if necessary.

The custom tag is located under {context}/core/mura/customtags/CacheOMatic.cfm if you would like to inspect the file to see how it works under the hood.

Tag Syntax

<cf_CacheOMatic>
Code or data to cache.
</cf_CacheOMatic>

Attributes

Attribute

Type

Default

Description

key

string

CGI.scriptname & CGI.query_string

A unique string to associate with the specified data. Used to retrieve the cached data, when Site Caching is enabled.

Programmatic Caching

As covered in the cf_CacheOMatic Tags section, Mura allows developers to add data to Mura's cache. One thing to keep in mind is your data or code may be either intentionally or even inadvertently wrapped by cf_CacheOMatic tags, subjecting your output to the settings of the tag.

However, as a developer, you may have data or code you wish to either explicitly exclude from being added to Mura's cache. Or, you may wish to set a specific duration of time the data or code may be cached for. Mura also allows developers to achieve this using the code snippets described below.

request.cacheItem

This code snippet controls whether the code or data will be cached if wrapped by cf_CacheOMatic tags. If true, the code or data will be cached according to the settings of the containing cf_CacheOMatic tags. If false, the code or data will not be cached.

Note: A side-effect of setting request.cacheItem to false is none of the code or data within the containing cf_CacheOMatic tags will be cached at all.

Syntax

request.cacheItem = {true || false}

Example

<cfset request.cacheItem = false />
<!--- The following timestamp will NOT be cached --->
<cfoutput>
<p>The date/time is #Now()#</p>
</cfoutput>

request.cacheItemTimeSpan

This code snippet controls the duration of time the code or data will be cached for.

Summary

Throughout this section, you built upon the knowledge obtained in the Theme Developer's area, and learned how to override Mura's default rendering methods, as well as how to create some sophisticated display objects, and how to target specific content types to provide custom body rendering. In addition, you learned about Mura.js, and how to use it in your development efforts, as well as other important information such as internationalization/localization, and how to leverage caching to improve your site's performance.