SlideShare a Scribd company logo
Super Fast Application

Development with Mura CMS
What’s Up?
• Build a fully functional application
using Mura ORM & Mura.js
Target Audience
• ColdFusion/CFML Developer
• Using Mura CMS
• Familiar with
• .CFCs
• Mura’s base objects
• Popular SQL DBMS
• May (or may not) have used ColdFusion’s ORM
What is Mura CMS?
• Open source Content Management System (CMS)
• Let users add/edit content, while you build applications
• Used by clients large & small
Mura Display Objects
• Self-contained display
• Portable
• Distributable (via plugins)
• Could be an entire application!
The Mura Scope
• A wrapper for interacting with Mura CMS
• Access data
• Create/modify data
• Helper methods
• “Mura” or “m” and still supports “$”
Mura Display Objects

Part 1
Mura Display Objects
• Managed via front-end only (in Mura v7+)
Mura Display Objects
Mura Display Objects
• Directory based format
{SiteID}/includes/themes/{ThemeName}/display_objects/
{SiteID}/includes/display_objects/
Mura Display Objects
• Directory based format (works in plugins too)
plugins/{YourPlugin}/display_objects/
Mura Display Objects
• Or, register any directory you want …
m.siteConfig().registerDisplayObjectDir(

‘/path/to/your/display_objects/‘

);
// Path is a logical path to a CFML directory

// Usually registered in onApplicationLoad();
Mura Display Objects
• Anatomy of a display object
/mydisplayobject/
config.xml.cfm
index.cfm
configurator.cfm (optional)
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*” />
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*” />
* = all content types
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*” />
* = all content types
contenttypes=“{Type|Type/Subtype},Folder/Blog,Folder/News”
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*” />
* = all content types
contenttypes=“{Type|Type/Subtype},Folder/Blog,Folder/News”
contenttypes=“” Blank = never display as draggable option
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*”

condition=“(m.content(‘title’) eq ‘News’)” />
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*”

iconclass=“mi-somefontawesomeiconclass” />
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*”>



<extensions>…</extensions>



</mura>
Mura Display Objects
• config.xml.cfm
<mura name=“My Display Object”

contenttypes=“*”>



<extensions>…</extensions>



<imagesizes>

<imagesize name=“yoursize” width=“100” height=“100”/>

</imagesizes>



</mura>
Mura Display Objects
• index.cfm (if rendering via CFML)
<cfparam name=“objectparams.mytext” default=“”>
<cfoutput>

<h3>#esapiEncode(‘html’, objectparams.mytext)#</h3>

</cfoutput>
Mura Display Objects
• index.cfm (if rendering via JS)
<cfset objectparams.render=“client”>
Mura Display Objects
• index.cfm (if rendering via JS)
<cfset objectparams.render=“client”>
• mydisplayobject/model/handlers/myhandler.cfc



component extends="mura.cfobject" {

function onRenderStart(m){

m.addToHTMLHeadQueue('<script src=“/path/to/js.js”></script>’);

}

}
Mura Display Objects
• configurator.cfm (optional)
<cfparam name=“objectparams.mytext” default=“”>





<cfoutput>

<div class=“mura-control-group”>

<label class=“mura-control-label”>My Text</label>

<input type=“text”

name=“mytext”

class=“objectParam”

value=“#esapiEncode(‘html_attr’, objectparams.mytext#”>

</cfoutput>
Mura Display Objects
• configurator.cfm (optional)
<cfparam name=“objectparams.mytext” default=“”>



<cf_objectconfigurator>

<cfoutput>

<div class=“mura-control-group”>

<label class=“mura-control-label”>My Text</label>

<input type=“text”

name=“mytext”

class=“objectParam”

value=“#esapiEncode(‘html_attr’, objectparams.mytext#”>

</cfoutput>

</cf_objectconfigurator>
https://github.com/stevewithington/

murahelloworld/tree/cfml
What is ORM?
What is ORM?
• Popular SQL DBMS
• Only store/manipulate scalar values such as integers and strings
organized within tables
What is ORM?
• Popular SQL DBMS
• Only store/manipulate scalar values such as integers and strings
organized within tables
• Object values must either be converted into groups of simpler
values, or only use simple scalar values
What is ORM?
• Object-Relationtional Mapping (ORM) addresses the main issue
with SQL DBMS
• Translates the logical representation of objects into an
atomized form capable of being stored in a database, while
preserving the properties of objects and their relationships so
they can be reloaded as objects when needed
What is ORM?
• Object-Relational Mapping (ORM) is essentially a
“virtual object database”
What is Mura ORM?
What is Mura ORM?
• Mura ORM is a “virtual object database” that
can be used within Mura
What is Mura ORM?
• Mura ORM is a “virtual object database” that can be used within
Mura
• Takes advantage of Di1 (dependency injection)
• https://github.com/framework-one/di1
What is Mura ORM?
• Mura ORM is a “virtual object database” that can be used within
Mura
• Takes advantage of Di1 (dependency injection)
• https://github.com/framework-one/di1
• Access & modify objects quickly & easily
What is Mura ORM?
• Mura ORM is a “virtual object database” that can be used within
Mura
• Takes advantage of Di1 (dependency injection)
• https://github.com/framework-one/di1
• Access & modify objects quickly & easily
• No need for custom DAOs, class extensions, or database-vendor-
specific CRUD statements
What is Mura ORM?
• Mura ORM is a “virtual object database” that can be used within
Mura
• Takes advantage of Di1 (dependency injection)
• https://github.com/framework-one/di1
• Access & modify objects quickly & easily
• No need for custom DAOs, class extensions, or database-vendor-
specific CRUD statements
• Similar to ColdFusion-based Hibernate ORM (but not the same!)
Mura ORM Configuration
Mura ORM Configuration
• Convention based vs. having to explicitly register entities
{SiteID}/includes/model/
{SiteID}/includes/themes/{ThemeName}/model/
Mura ORM Configuration
• Convention based vs. having to explicitly register entities
{SiteID}/includes/model/
{SiteID}/includes/themes/{ThemeName}/model/


Or any display object’s “model” directory!
../display_objects/mydisplayobject/model/
Mura ORM Configuration
• Or, register any directory you want …
m.globalConfig().registerModelDir(

‘/path/to/your/model/‘

);
// Path is a logical path to a CFML directory
Mura ORM Configuration
• Or, register any directory you want …
m.globalConfig().registerModelDir(

‘/path/to/your/model/‘

);
// Path is a logical path to a CFML directory
// Usually registered in onApplicationLoad();
Mura ORM Configuration
• Any .cfc under the “model” directory will automatically get
registered with Di1
Mura ORM Configuration
• Any .cfc under the “model” directory will automatically get
registered with Di1
• If it’s under a “beans” directory, it will be registered as a
transient, not as a singleton
Mura ORM Configuration
• Any .cfc under the “model” directory will automatically get
registered with Di1
• If it’s under a “beans” directory, it will be registered as a
transient, not as a singleton
• A transient exists only for a request and then is discarded
• You get a new copy every time
Mura ORM Configuration
• Any .cfc under the “model” directory will automatically get
registered with Di1
• If it’s under a “beans” directory, it will be registered as a
transient, not as a singleton
• A transient exists only for a request and then is discarded
• You get a new copy every time
• A singleton is shared among all threads and requests … there’s
only one of them
• You’re not getting a new copy every time
• Good for service type objects
Mura ORM Configuration
• Any .cfc under the “model” directory will automatically get
registered with Di1
• If it’s under a “beans” directory, it will be registered as a
transient, not as a singleton
../model/beans/person.cfc
../model/beans/personaddress.cfc
../model/beans/personphonenumber.cfc
Mura ORM Configuration
• If a directory found under “model” is named “handlers” then
any .cfc under this directory will be registered as eventHandlers
Mura ORM Configuration
• If a directory found under “model” is named “handlers” then
any .cfc under this directory will be registered as eventHandlers
• For example:
../model/handlers/myhandler.cfc
../model/services/handlers/myhandler.cfc
Mura ORM Configuration
• Reload Mura to get them registered
Mura ORM Configuration
• Reload Mura to get them registered
• The first time you reload, and anytime you add new properties, be
sure to append ‘&applydbupdates’ to the URL
Mura ORM Configuration
• Reload Mura to get them registered
• The first time you reload, and anytime you add new properties, be
sure to append ‘&applydbupdates’ to the URL
• For example: 

./?appreload&applydbupates
Mura Display Objects

Part 2
Mura Display Objects
• Display object’s can have their own “model” directory
../display_objects/mydisplayobject/model/
Mura Display Objects
• Display object’s can have their own “model” directory
../display_objects/mydisplayobject/model/
• And their own “beans” directory
../display_objects/mydisplayobject/model/beans/
Mura Display Objects
• Display object’s can have their own “model” directory
../display_objects/mydisplayobject/model/
• And their own “beans” directory
../display_objects/mydisplayobject/model/beans/
• And “handlers” too
../display_objects/mydisplayobject/model/handlers/
Address Book
Address Book
• Person
Address Book
• Person
• Zero or more phone numbers
Address Book
• Person
• Zero or more phone numbers
• Zero or more addresses
Address Book
• Person object with attributes/fields
Address Book
• Person object with attributes/fields
• Person’s name
Address Book
• Person object with attributes/fields
• Person’s name
• List of phone numbers
• PhoneNumber objects
Address Book
• Person object with attributes/fields
• Person’s name
• List of phone numbers
• PhoneNumber objects
• List of addresses
• Address objects
Address Book
• The address book entry (Person) is treated as a single object
Address Book
• The address book entry (Person) is treated as a single object
• It can be referenced by a single variable containing a pointer to
the object
Address Book
• The address book entry (Person) is treated as a single object
• It can be referenced by a single variable containing a pointer to
the object
• Various helper methods can be associated with the object, such as
a method to return the preferred phone number, the home
address, and so on
Mura ORM Entity
Mura ORM Entity
component

extends="mura.bean.beanORM"

entityname="person"

table="custom_persons"

bundleable="true"

displayname="PersonBean"

public=true

orderby="namelast,namefirst" {



// Properties & Methods



}
Mura ORM Entity
• Component (CFC) Attributes
entityname 

table

datasource

discriminatorcolumn 

discriminatorvalue

orderby

readonly
Mura ORM Entity
• Component (CFC) Attributes
entityname 

table

datasource

discriminatorcolumn 

discriminatorvalue

orderby

readonly
• Mura-specific attributes
public

bundleable 

cachename

dbtype

manageschema

usetrash

Mura ORM Entity
component

extends=“mura.bean.beanORM”

entityname=“person” … {



// primary key (are UUIDs)

property name=“personid” fieldtype=“id”;



}
Mura ORM Entity
component

extends=“mura.bean.beanORM”

entityname=“person” … {



// primary key

property name=“personid” fieldtype=“id”;



// person attributes

property name=“namefirst” datatype=“varchar”;

property name=“namelast” datatype=“varchar”;

}
Mura ORM Entity
component

extends=“mura.bean.beanORM”

entityname=“person” … {

…
// foreign key(s)

property name=“user” 

cfc=“user” 

fieldtype=“many-to-one” 

fkcolumn=“userid”;

}
Mura ORM Entity
component

extends=“mura.bean.beanORM”

entityname=“person” … {

…
// relationship(s)

property name=“phonenumbers” 

singularname=“phonenumber”

cfc=“personphonenumber” 

fieldtype=“one-to-many”

cascade=“delete”;

}
Mura ORM Entity
component

extends=“mura.bean.beanORM”

entityname=“personphonenumber” … {

…
// relationship(s)

property name=“person” 

cfc=“person” 

fieldtype=“many-to-one”

fkcolumn=“personid”;

}
Mura ORM Entity
component

extends=“mura.bean.beanORM”

entityname=“personphonenumber” … {

…
// attribute(s)

property name=“phonenumber” 

datatype=“varchar”

length=“255”

required=true

message=“Phone Number is required.”;

}
Mura ORM Entity
• Property Attributes
name

persistent

fieldtype

cfc

fkcolumn

type

cascade

singularname

orderby

length

default

ormtype
Mura ORM Entity
• Property Attributes
name

persistent

fieldtype

cfc

fkcolumn

type

cascade

singularname

orderby

length

default

ormtype
• Mura-specific attributes
loadkey

datatype

nullable

required

validate

message

regex

comparable

Mura ORM Entity
• Property validation attributes
minValue
maxValue
minLength
maxLength
minCollection
maxCollection
minList
maxList
inList
method
lte
lt
gte
gt
eq
neq

Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
entity.set(‘attribute’, ‘Some Value’);
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
entity.set(‘attribute’, ‘Some Value’).save();
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
entity.set(‘attribute’, ‘Some Value’).save();
entity.get{RelatedEntity}();
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
entity.set(‘attribute’, ‘Some Value’).save();
entity.get{RelatedEntity}();
entity.get{RelatedEntity}Iterator();
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
entity.set(‘attribute’, ‘Some Value’).save();
entity.get{RelatedEntity}();
entity.get{RelatedEntity}Iterator();
entity.get{RelatedEntity}Query();
Mura ORM Entity
entity = m.getBean(‘entityName’)

.loadBy(someAttribute=‘Something’);
entity.get(‘attribute’);
entity.set(‘attribute’, ‘Some Value’).save();
entity.get{RelatedEntity}();
entity.get{RelatedEntity}Iterator();
entity.get{RelatedEntity}Query();
m.getFeed(‘entityName’);
Mura ORM Entity
contactBean = m.getBean(‘person’)

.loadBy(personid=m.event(‘pid’));
Mura ORM Entity
contactBean = m.getBean(‘person’)

.loadBy(personid=m.event(‘pid’));
if ( contactBean.exists() ) { 

// This bean exists!
} else {

// Do something if it’s a new bean
}
Mura ORM Entity
contactBean = m.getBean(‘person’)

.loadBy(personid=m.event(‘pid’));
// Phone Numbers Iterator

itPhones = contactBean.getPhoneNumbersIterator();
Mura ORM Entity
contactBean = m.getBean(‘person’)

.loadBy(personid=m.event(‘pid’));
// Phone Numbers Iterator

itPhones = contactBean.getPhoneNumbersIterator();


while ( itPhones.hasNext() ) {

phone = itPhones.next();

WriteOutput( phone.get(‘phonenumber’) );

}
Mura ORM Feed
Mura ORM Feed (Content)
m
.getFeed(‘content’);
Mura ORM Feed (Content)
m
.getFeed(‘content’)
.where() // optional … but readable
.prop(‘title’)
.isEQ(‘News’)
.orProp(‘title’)
.isEQ(‘Blog’)
.sort(‘title’, ‘desc’)
.getIterator();
Mura ORM Feed (Entity)
m
.getFeed(‘person’)
.where()
.prop(‘namefirst’)
.containsValue(m.event(‘namefirst’))
.orProp(‘namelast’)
.isEQ(m.event(‘namelast’))
.getIterator();
Mura ORM Feed (Sorting)
m
.getFeed(‘person’)
.where()
.prop(‘userid’)
.isEQ(m.currentUser(‘userid’)
.sort(‘namelast’, ‘asc’)
.sort(‘namefirst’, ‘desc’)
.getIterator();
Mura ORM Feed (Methods)
m
.getFeed([entityname])
.where()
.prop([property])
.andProp([property])
.orProp([property])
.isEQ([criteria])
.isNEQ([criteria])
.isLT([criteria])
.isLTE([criteria])
.isGT([criteria])
.isGTE([criteria])
.containsValue([criteria])
.null()
.beginsWith([criteria])
.endsWith([criteria])
.openGrouping()
.andOpenGrouping()
.closeGrouping()
.sort([property],[asc||desc])
.itemsPerPage([itemsPerPage])
.maxItems([maxItems])
.isIn([list criteria])
.isNotIn([list criteria])
.innerJoin([relatedEntity])
.leftJoin([relatedEntity])
.getQuery()
.getIterator()
Mura ORM Events
Mura ORM Events
• ../model/handlers/myhandler.cfc
Mura ORM Events
• ../model/handlers/myhandler.cfc
onBefore{Entity}Save(m) {

var bean = m.event(‘bean’);

… 

}
Mura ORM Events
• ../model/handlers/myhandler.cfc
onBefore{Entity}Save(m) {

var bean = m.event(‘bean’);

… 

}
// Plus any other Mura event listeners you want!
Mura ORM Events
• Support for ColdFusion/CFML ORM Events

preLoad();
preUpdate();
preCreate();
preInsert();
preDelete();


postLoad();
postUpdate();
postCreate();
postInsert();
postDelete();

https://github.com/stevewithington/

muracontacts/tree/cfml
Mura.js
Mura.js
• A lightweight utility to decouple dependency on jQuery
Mura.js
• A lightweight utility to decouple dependency on jQuery
• A JS framework for interacting with the Mura JSON API
Mura.js
• Familiar jQuery syntax
Mura(function(m) {
m(‘.target’).each(function() {

m(this).html(‘Mura found you!’);

});

});
Mura.js
• Baked-in AJAX support


Mura

.ajax({

type: ‘post’,

url: ’https://domain.com/path/',

data: { key: value },

success: function(resp) { console.log(resp) },

error: function(resp) { console.log(resp) }

});
Mura.js
• Baked-in AJAX support & JS promises


Mura

.get(‘https://domain.com/path/')

.then(function(resp) {

// success

Mura(‘#target’).html(resp.data.html);

}, function(e) {

// fail

});
Mura.js
• Baked-in AJAX support & JS promises


Mura

.post(

‘https://domain.com/path/',

{ key: value }

)

.then(function(resp) {

// success

}, function(e) { 

// error 

});
Mura.js
• JS promises can be stacked like Russian dolls


Mura.get(‘https://domain.com/path/')

.then(function(resp) {

// success

Mura.get(‘https://domain.com?id=' + resp.id)

.then(function(newresp) {

Mura(‘#target’).html(newresp.html);

});

}, function(e) { 

// error 

});
Mura.js
• Register event handlers


Mura(‘#mybutton’)

.on(‘click’, function(e) {

e.preventDefault();

console.log(e);

});
Mura.js
• Mura.DOMSelection class
• Wraps selected target via the Mura() method
Mura.js
• Mura.DOMSelection class
• Wraps selected target via the Mura() method
• Allows you to handle selection as a single object or a collection
Mura.js
• Mura.DOMSelection class
• Wraps selected target via the Mura() method
• Allows you to handle selection as a single object or a collection
• Single object

Mura(‘.target’).html(‘Hello world!’);
Mura.js
• Mura.DOMSelection class
• Wraps selected target via the Mura() method
• Allows you to handle selection as a single object or a collection
• Single object

Mura(‘.target’).html(‘Hello world!’);

• Collection

Mura(‘.target’).each(function() {

Mura(this).html(‘Hello world!’);

});
Mura.js
• Supported methods can be found under:



{SiteID}/js/src/mura.domselection.js
Mura.js
• Load entities



Mura

.getEntity(‘person’)

.loadBy(‘personid’, pid)

.then(function(person) {

// success

console.log(person);

}, function(person) {

// fail

console.log(person.get(‘errors’));

});
Mura.js
• Create/Update entities



Mura

.getEntity(‘person’)

.loadBy(‘personid’, pid)

.then(function(person) {

// load success

person.set(‘namelast’, ‘Withington’)

.save()

.then(function(person) {

// save success

}, function(person) { 

// save fail 

});

});
Mura.js
• Delete entities



Mura

.getEntity(‘person’)

.loadBy(‘personid’, pid)

.then(function(person) {

// load success

person

.delete()

.then(function(person) {

// delete success

}, function(person) { 

// delete fail 

});

});
Mura.js
• Feed API



Mura

.getFeed(‘person’)

.where() // optional

.prop(‘namelast’).isEQ(‘Levine’)

.orProp(‘namelast’).beginsWith(‘Withing’)

.getQuery()

.then(function(people) {

// success

people.each(function(prsn, idx) {

console.log(prsn.get(‘namefirst’) + ‘ ‘ + prsn.get(‘namelast’));

});

});
Mura.js (Feed Methods)
Mura
.getFeed([entityname])
.where()
.prop([property])
.andProp([property])
.orProp([property])
.isEQ([criteria])
.isNEQ([criteria])
.isLT([criteria])
.isLTE([criteria])
.isGT([criteria])
.isGTE([criteria])
.containsValue([criteria])
.null()
.beginsWith([criteria])
.endsWith([criteria])
.openGrouping()
.andOpenGrouping()
.closeGrouping()
.sort([property],[asc||desc])
.itemsPerPage([itemsPerPage])
.maxItems([maxItems])
.isIn([list criteria])
.isNotIn([list criteria])
.innerJoin([relatedEntity])
.leftJoin([relatedEntity])
.getQuery()
Mura Display Objects

Part 3
Mura Display Objects
• Loading JS/CSS files



Mura(function(m) {

m.loader()

.loadcss(m.themepath + ‘/path/all.css’, {media:’all’})

.loadcss(m.themepath + ‘/path/print.css’, {media:’print’})

.loadjs(

m.themepath + ’/path/script1.js’,

m.themepath + ’/path/script2.js’,

function() {

// Now do something with the loaded JS 

}

);

});
Mura Display Objects
• Mura.loader()
• Only loads files once (no duplicates)
Mura Display Objects
• Mura.loader()
• Only loads files once (no duplicates)
• loadjs() can take string arguments or arrays of strings
Mura Display Objects
• Mura.loader()
• Only loads files once (no duplicates)
• loadjs() can take string arguments or arrays of strings
• if array, files are loaded asynchronously
Mura Display Objects
• Mura.loader()
• Only loads files once (no duplicates)
• loadjs() can take string arguments or arrays of strings
• if array, files are loaded asynchronously
• if string, files are loaded synchronously
Mura Display Objects
• loadjs() Synchronous Example
• When the 2nd file is loading, it can reference variables from 1st



Mura(function(m) {

m.loader()

.loadjs(

m.themepath + ’/path/script1.js’,

m.themepath + ’/path/script2.js’,

function() {

// Now do something with the loaded JS 

}

);

});
Mura Display Objects
• loadjs() Asynchronous Example
• When the 2nd file is loading, it cannot reference variables from 1st



Mura(function(m) {

m.loader()

.loadjs(

[

m.themepath + ’/path/script1.js’,

m.themepath + ’/path/script2.js’

],

function() {

// Now do something with the loaded JS 

}

);

});
Mura Display Objects
• index.cfm (Full example if rendering via Server/CFML)
<cfparam name=“objectparams.mytext” default=“”>

<cfoutput>

<h3>#esapiEncode(‘html’, objectparams.mytext)#</h3>

</cfoutput>



<script>

Mura(function(m) {

m.loader()

.loadcss(m.themepath + ‘/path/my.css’)

.loadjs(m.themepath + ’/path/my.js’);

});

</script>
Mura Display Objects
• index.cfm (Full example if rendering via Client/JS)
Mura.DisplayObject.myobject = Mura.UI.extend({

render: function() {

this.container = Mura(this.context.targetEl);



Mura.loader()

.loadcss(Mura.themepath + ‘/path/my.css’)

.loadjs(Mura.themepath + ’/path/my.js’,

function(){

//DO STUFF

}

);

}
});
https://github.com/stevewithington/

murahelloworld/tree/js
https://github.com/stevewithington/

muracontacts/tree/js
content_types
content_types
• Control body by Type/Subtype
content_types
• Control body by Type/Subtype
• Folder/Contacts
• Page/Contact
content_types
• Control body by Type/Subtype



{SiteID}/includes/content_types/
content_types
• Control body by Type/Subtype



{SiteID}/includes/content_types/

{SiteID}/includes/themes/{ThemeName}/content_types/
content_types
• Or, register any directory you want …
m.siteConfig().registerContentTypeDir(

‘/path/to/your/content_types/‘

);
// Path is a logical path to a CFML directory
content_types
• Or, register any directory you want …
m.siteConfig().registerContentTypeDir(

‘/path/to/your/content_types/‘

);
// Path is a logical path to a CFML directory
// Usually registered in onApplicationLoad();
content_types
• Control body by Type/Subtype



{SiteID}/includes/content_types/

{SiteID}/includes/themes/{ThemeName}/content_types/

• Target Type/Subtype by directory structure:



content_types/{type}
content_types
• Control body by Type/Subtype



{SiteID}/includes/content_types/

{SiteID}/includes/themes/{ThemeName}/content_types/

• Target Type/Subtype by directory structure:



content_types/{type}

content_types/page/index.cfm
content_types
• Control body by Type/Subtype



{SiteID}/includes/content_types/

{SiteID}/includes/themes/{ThemeName}/content_types/

• Target Type/Subtype by directory structure:



content_types/{type}

content_types/page/index.cfm



content_types/{type}_{subtype}
content_types
• Control body by Type/Subtype



{SiteID}/includes/content_types/

{SiteID}/includes/themes/{ThemeName}/content_types/

• Target Type/Subtype by directory structure:



content_types/{type}

content_types/page/index.cfm



content_types/{type}_{subtype}

content_types/page_contact/index.cfm
content_types
• Anatomy of a content_type



content_types/folder_contacts/index.cfm

content_types/folder_contacts/config.xml.cfm
content_types
• Anatomy of a content_type



content_types/folder_contacts/index.cfm

content_types/folder_contacts/config.xml.cfm

• index.cfm = the body/view
content_types
• Anatomy of a content_type



content_types/folder_contacts/index.cfm

content_types/folder_contacts/config.xml.cfm

• index.cfm = the body/view
• config.xml.cfm = the configuration
content_types
• Anatomy of a content_type



content_types/folder_contacts/index.cfm

content_types/folder_contacts/config.xml.cfm



content_types/folder_contacts/model/
content_types
• Anatomy of a content_type



content_types/folder_contacts/index.cfm

content_types/folder_contacts/config.xml.cfm



content_types/folder_contacts/model/

content_types/folder_contacts/model/beans/

content_types/folder_contacts/model/handlers/
Q+A
Resources
• http://www.getmura.com
• https://github.com/stevewithington/cfsummit-2016
• https://github.com/stevewithington/muracontacts
• https://github.com/stevewithington/murahelloworld
• https://groups.google.com/forum/#!forum/mura-cms-developers
Thank
you!

More Related Content

What's hot (20)

Restful API's with ColdFusion
Restful API's with ColdFusionRestful API's with ColdFusion
Restful API's with ColdFusion
ColdFusionConference
 
ColdFusion builder plugins
ColdFusion builder pluginsColdFusion builder plugins
ColdFusion builder plugins
ColdFusionConference
 
Hidden gems in cf2016
Hidden gems in cf2016Hidden gems in cf2016
Hidden gems in cf2016
ColdFusionConference
 
Securing applications
Securing applicationsSecuring applications
Securing applications
ColdFusionConference
 
10 Reasons ColdFusion PDFs should rule the world
10 Reasons ColdFusion PDFs should rule the world10 Reasons ColdFusion PDFs should rule the world
10 Reasons ColdFusion PDFs should rule the world
ColdFusionConference
 
Load Balancing, Failover and Scalability with ColdFusion
Load Balancing, Failover and Scalability with ColdFusionLoad Balancing, Failover and Scalability with ColdFusion
Load Balancing, Failover and Scalability with ColdFusion
ColdFusionConference
 
Locking Down CF Servers
Locking Down CF ServersLocking Down CF Servers
Locking Down CF Servers
ColdFusionConference
 
10 common cf server challenges
10 common cf server challenges10 common cf server challenges
10 common cf server challenges
ColdFusionConference
 
Instant ColdFusion with Vagrant
Instant ColdFusion with VagrantInstant ColdFusion with Vagrant
Instant ColdFusion with Vagrant
ColdFusionConference
 
Can you contain the future - Docker, Container Technologies, The Future, and You
Can you contain the future - Docker, Container Technologies, The Future, and YouCan you contain the future - Docker, Container Technologies, The Future, and You
Can you contain the future - Docker, Container Technologies, The Future, and You
ColdFusionConference
 
Workflows and Digital Signatures
Workflows and Digital SignaturesWorkflows and Digital Signatures
Workflows and Digital Signatures
ColdFusionConference
 
Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016
ColdFusionConference
 
Expand Your ColdFusion App Power with AWS
Expand Your ColdFusion App Power with AWSExpand Your ColdFusion App Power with AWS
Expand Your ColdFusion App Power with AWS
ColdFusionConference
 
Realtime with websockets
Realtime with websocketsRealtime with websockets
Realtime with websockets
ColdFusionConference
 
Command Box ColdFusion Package Manager, Automation
Command Box ColdFusion Package Manager, AutomationCommand Box ColdFusion Package Manager, Automation
Command Box ColdFusion Package Manager, Automation
ColdFusionConference
 
Hidden Gems in ColdFusion 2016
Hidden Gems in ColdFusion 2016Hidden Gems in ColdFusion 2016
Hidden Gems in ColdFusion 2016
ColdFusionConference
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
Migration to ColdFusion 11 – making it seamless and easy anit
Migration to ColdFusion 11 – making it seamless and easy   anitMigration to ColdFusion 11 – making it seamless and easy   anit
Migration to ColdFusion 11 – making it seamless and easy anit
ColdFusionConference
 
OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014
Jary Carter
 
Node.js to the rescue
Node.js to the rescueNode.js to the rescue
Node.js to the rescue
Marko Heijnen
 
10 Reasons ColdFusion PDFs should rule the world
10 Reasons ColdFusion PDFs should rule the world10 Reasons ColdFusion PDFs should rule the world
10 Reasons ColdFusion PDFs should rule the world
ColdFusionConference
 
Load Balancing, Failover and Scalability with ColdFusion
Load Balancing, Failover and Scalability with ColdFusionLoad Balancing, Failover and Scalability with ColdFusion
Load Balancing, Failover and Scalability with ColdFusion
ColdFusionConference
 
Can you contain the future - Docker, Container Technologies, The Future, and You
Can you contain the future - Docker, Container Technologies, The Future, and YouCan you contain the future - Docker, Container Technologies, The Future, and You
Can you contain the future - Docker, Container Technologies, The Future, and You
ColdFusionConference
 
Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016
ColdFusionConference
 
Expand Your ColdFusion App Power with AWS
Expand Your ColdFusion App Power with AWSExpand Your ColdFusion App Power with AWS
Expand Your ColdFusion App Power with AWS
ColdFusionConference
 
Command Box ColdFusion Package Manager, Automation
Command Box ColdFusion Package Manager, AutomationCommand Box ColdFusion Package Manager, Automation
Command Box ColdFusion Package Manager, Automation
ColdFusionConference
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
Migration to ColdFusion 11 – making it seamless and easy anit
Migration to ColdFusion 11 – making it seamless and easy   anitMigration to ColdFusion 11 – making it seamless and easy   anit
Migration to ColdFusion 11 – making it seamless and easy anit
ColdFusionConference
 
OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014
Jary Carter
 
Node.js to the rescue
Node.js to the rescueNode.js to the rescue
Node.js to the rescue
Marko Heijnen
 

Viewers also liked (17)

ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusionConference
 
Don't just pdf, Smart PDF
Don't just pdf, Smart PDFDon't just pdf, Smart PDF
Don't just pdf, Smart PDF
ColdFusionConference
 
Crafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an ArchitectCrafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an Architect
ColdFusionConference
 
ColdFusion in Transit action
ColdFusion in Transit actionColdFusion in Transit action
ColdFusion in Transit action
ColdFusionConference
 
Testing automaton
Testing automatonTesting automaton
Testing automaton
ColdFusionConference
 
Building better SQL Server Databases
Building better SQL Server DatabasesBuilding better SQL Server Databases
Building better SQL Server Databases
ColdFusionConference
 
Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016
ColdFusionConference
 
Cf ppt vsr
Cf ppt vsrCf ppt vsr
Cf ppt vsr
ColdFusionConference
 
Why Everyone else writes bad code
Why Everyone else writes bad codeWhy Everyone else writes bad code
Why Everyone else writes bad code
ColdFusionConference
 
Instant ColdFusion with Vagrant
Instant ColdFusion with VagrantInstant ColdFusion with Vagrant
Instant ColdFusion with Vagrant
ColdFusionConference
 
Restful services with ColdFusion
Restful services with ColdFusionRestful services with ColdFusion
Restful services with ColdFusion
ColdFusionConference
 
Monetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APISMonetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APIS
ColdFusionConference
 
Security And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API ManagerSecurity And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API Manager
ColdFusionConference
 
API Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIsAPI Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIs
ColdFusionConference
 
Api manager preconference
Api manager preconferenceApi manager preconference
Api manager preconference
ColdFusionConference
 
Where is cold fusion headed
Where is cold fusion headedWhere is cold fusion headed
Where is cold fusion headed
ColdFusionConference
 
Build your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and webBuild your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and web
ColdFusionConference
 
ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusionConference
 
Crafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an ArchitectCrafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an Architect
ColdFusionConference
 
Building better SQL Server Databases
Building better SQL Server DatabasesBuilding better SQL Server Databases
Building better SQL Server Databases
ColdFusionConference
 
Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016
ColdFusionConference
 
Monetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APISMonetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APIS
ColdFusionConference
 
Security And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API ManagerSecurity And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API Manager
ColdFusionConference
 
API Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIsAPI Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIs
ColdFusionConference
 
Build your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and webBuild your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and web
ColdFusionConference
 
Ad

Similar to Super Fast Application development with Mura CMS (20)

June 10th: The SugarCRM Platform
June 10th: The SugarCRM PlatformJune 10th: The SugarCRM Platform
June 10th: The SugarCRM Platform
Matthew Cooke
 
June 10th: The SugarCRM Platform
June 10th: The SugarCRM PlatformJune 10th: The SugarCRM Platform
June 10th: The SugarCRM Platform
ticomixcrm
 
Django introduction @ UGent
Django introduction @ UGentDjango introduction @ UGent
Django introduction @ UGent
kevinvw
 
Ember - introduction
Ember - introductionEmber - introduction
Ember - introduction
Harikrishnan C
 
Alfresco Content Modelling and Policy Behaviours
Alfresco Content Modelling and Policy BehavioursAlfresco Content Modelling and Policy Behaviours
Alfresco Content Modelling and Policy Behaviours
J V
 
Tech talk-live-alfresco-drupal
Tech talk-live-alfresco-drupalTech talk-live-alfresco-drupal
Tech talk-live-alfresco-drupal
Alfresco Software
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
WO Community
 
ColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introductionColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introduction
SaravanaMuthu Jayaraj
 
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Lucidworks
 
Orm loveandhate
Orm loveandhateOrm loveandhate
Orm loveandhate
Wil de Bruin
 
Creating Custom Templates for Joomla! 2.5
Creating Custom Templates for Joomla! 2.5Creating Custom Templates for Joomla! 2.5
Creating Custom Templates for Joomla! 2.5
Don Cranford
 
Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)
Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)
Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)
Mark Hamstra
 
Drupal: Reusing functionality
Drupal: Reusing functionalityDrupal: Reusing functionality
Drupal: Reusing functionality
Raymond Muilwijk
 
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
Ortus Solutions, Corp
 
Customising civicrm
Customising civicrmCustomising civicrm
Customising civicrm
Chris Ward
 
Leveraging the Chaos tool suite for module development
Leveraging the Chaos tool suite  for module developmentLeveraging the Chaos tool suite  for module development
Leveraging the Chaos tool suite for module development
zroger
 
Introduction to Monsoon PHP framework
Introduction to Monsoon PHP frameworkIntroduction to Monsoon PHP framework
Introduction to Monsoon PHP framework
Krishna Srikanth Manda
 
CDMI For Swift
CDMI For SwiftCDMI For Swift
CDMI For Swift
Mark Carlson
 
SilverStripe From a Developer's Perspective
SilverStripe From a Developer's PerspectiveSilverStripe From a Developer's Perspective
SilverStripe From a Developer's Perspective
ajshort
 
OpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve content
OpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve contentOpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve content
OpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve content
Alkacon Software GmbH & Co. KG
 
June 10th: The SugarCRM Platform
June 10th: The SugarCRM PlatformJune 10th: The SugarCRM Platform
June 10th: The SugarCRM Platform
Matthew Cooke
 
June 10th: The SugarCRM Platform
June 10th: The SugarCRM PlatformJune 10th: The SugarCRM Platform
June 10th: The SugarCRM Platform
ticomixcrm
 
Django introduction @ UGent
Django introduction @ UGentDjango introduction @ UGent
Django introduction @ UGent
kevinvw
 
Alfresco Content Modelling and Policy Behaviours
Alfresco Content Modelling and Policy BehavioursAlfresco Content Modelling and Policy Behaviours
Alfresco Content Modelling and Policy Behaviours
J V
 
Tech talk-live-alfresco-drupal
Tech talk-live-alfresco-drupalTech talk-live-alfresco-drupal
Tech talk-live-alfresco-drupal
Alfresco Software
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
WO Community
 
ColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introductionColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introduction
SaravanaMuthu Jayaraj
 
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Lucidworks
 
Creating Custom Templates for Joomla! 2.5
Creating Custom Templates for Joomla! 2.5Creating Custom Templates for Joomla! 2.5
Creating Custom Templates for Joomla! 2.5
Don Cranford
 
Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)
Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)
Unleashing Creative Freedom with MODX (2015-09-08 at PHPAmersfoort)
Mark Hamstra
 
Drupal: Reusing functionality
Drupal: Reusing functionalityDrupal: Reusing functionality
Drupal: Reusing functionality
Raymond Muilwijk
 
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
Ortus Solutions, Corp
 
Customising civicrm
Customising civicrmCustomising civicrm
Customising civicrm
Chris Ward
 
Leveraging the Chaos tool suite for module development
Leveraging the Chaos tool suite  for module developmentLeveraging the Chaos tool suite  for module development
Leveraging the Chaos tool suite for module development
zroger
 
SilverStripe From a Developer's Perspective
SilverStripe From a Developer's PerspectiveSilverStripe From a Developer's Perspective
SilverStripe From a Developer's Perspective
ajshort
 
OpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve content
OpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve contentOpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve content
OpenCms Days 2012 - OpenCms 8.5: Using Apache Solr to retrieve content
Alkacon Software GmbH & Co. KG
 
Ad

More from ColdFusionConference (7)

Rest ful tools for lazy experts
Rest ful tools for lazy expertsRest ful tools for lazy experts
Rest ful tools for lazy experts
ColdFusionConference
 
Herding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandboxHerding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandbox
ColdFusionConference
 
Everyones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusionEveryones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusion
ColdFusionConference
 
Getting started with mobile application development
Getting started with mobile application developmentGetting started with mobile application development
Getting started with mobile application development
ColdFusionConference
 
Bring api manager into your stack
Bring api manager into your stackBring api manager into your stack
Bring api manager into your stack
ColdFusionConference
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
ColdFusionConference
 
ColdFusion Craftsmanship
ColdFusion CraftsmanshipColdFusion Craftsmanship
ColdFusion Craftsmanship
ColdFusionConference
 
Herding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandboxHerding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandbox
ColdFusionConference
 
Everyones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusionEveryones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusion
ColdFusionConference
 
Getting started with mobile application development
Getting started with mobile application developmentGetting started with mobile application development
Getting started with mobile application development
ColdFusionConference
 

Recently uploaded (20)

Maxx nft market place new generation nft marketing place
Maxx nft market place new generation nft marketing placeMaxx nft market place new generation nft marketing place
Maxx nft market place new generation nft marketing place
usersalmanrazdelhi
 
Palo Alto Networks Cybersecurity Foundation
Palo Alto Networks Cybersecurity FoundationPalo Alto Networks Cybersecurity Foundation
Palo Alto Networks Cybersecurity Foundation
VICTOR MAESTRE RAMIREZ
 
Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025
Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025
Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025
Nikki Chapple
 
Measuring Microsoft 365 Copilot and Gen AI Success
Measuring Microsoft 365 Copilot and Gen AI SuccessMeasuring Microsoft 365 Copilot and Gen AI Success
Measuring Microsoft 365 Copilot and Gen AI Success
Nikki Chapple
 
Grannie’s Journey to Using Healthcare AI Experiences
Grannie’s Journey to Using Healthcare AI ExperiencesGrannie’s Journey to Using Healthcare AI Experiences
Grannie’s Journey to Using Healthcare AI Experiences
Lauren Parr
 
AI Trends - Mary Meeker
AI Trends - Mary MeekerAI Trends - Mary Meeker
AI Trends - Mary Meeker
Razin Mustafiz
 
6th Power Grid Model Meetup - 21 May 2025
6th Power Grid Model Meetup - 21 May 20256th Power Grid Model Meetup - 21 May 2025
6th Power Grid Model Meetup - 21 May 2025
DanBrown980551
 
Data Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any ApplicationData Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any Application
Safe Software
 
Jira Administration Training – Day 1 : Introduction
Jira Administration Training – Day 1 : IntroductionJira Administration Training – Day 1 : Introduction
Jira Administration Training – Day 1 : Introduction
Ravi Teja
 
GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...
GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...
GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...
James Anderson
 
Offshore IT Support: Balancing In-House and Offshore Help Desk Technicians
Offshore IT Support: Balancing In-House and Offshore Help Desk TechniciansOffshore IT Support: Balancing In-House and Offshore Help Desk Technicians
Offshore IT Support: Balancing In-House and Offshore Help Desk Technicians
john823664
 
SDG 9000 Series: Unleashing multigigabit everywhere
SDG 9000 Series: Unleashing multigigabit everywhereSDG 9000 Series: Unleashing multigigabit everywhere
SDG 9000 Series: Unleashing multigigabit everywhere
Adtran
 
Dev Dives: System-to-system integration with UiPath API Workflows
Dev Dives: System-to-system integration with UiPath API WorkflowsDev Dives: System-to-system integration with UiPath API Workflows
Dev Dives: System-to-system integration with UiPath API Workflows
UiPathCommunity
 
Kubernetes Cloud Native Indonesia Meetup - May 2025
Kubernetes Cloud Native Indonesia Meetup - May 2025Kubernetes Cloud Native Indonesia Meetup - May 2025
Kubernetes Cloud Native Indonesia Meetup - May 2025
Prasta Maha
 
Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)
Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)
Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)
Peter Bittner
 
Cyber security cyber security cyber security cyber security cyber security cy...
Cyber security cyber security cyber security cyber security cyber security cy...Cyber security cyber security cyber security cyber security cyber security cy...
Cyber security cyber security cyber security cyber security cyber security cy...
pranavbodhak
 
Cognitive Chasms - A Typology of GenAI Failure Failure Modes
Cognitive Chasms - A Typology of GenAI Failure Failure ModesCognitive Chasms - A Typology of GenAI Failure Failure Modes
Cognitive Chasms - A Typology of GenAI Failure Failure Modes
Dr. Tathagat Varma
 
Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...
Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...
Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...
Aaryan Kansari
 
Cyber Security Legal Framework in Nepal.pptx
Cyber Security Legal Framework in Nepal.pptxCyber Security Legal Framework in Nepal.pptx
Cyber Security Legal Framework in Nepal.pptx
Ghimire B.R.
 
European Accessibility Act & Integrated Accessibility Testing
European Accessibility Act & Integrated Accessibility TestingEuropean Accessibility Act & Integrated Accessibility Testing
European Accessibility Act & Integrated Accessibility Testing
Julia Undeutsch
 
Maxx nft market place new generation nft marketing place
Maxx nft market place new generation nft marketing placeMaxx nft market place new generation nft marketing place
Maxx nft market place new generation nft marketing place
usersalmanrazdelhi
 
Palo Alto Networks Cybersecurity Foundation
Palo Alto Networks Cybersecurity FoundationPalo Alto Networks Cybersecurity Foundation
Palo Alto Networks Cybersecurity Foundation
VICTOR MAESTRE RAMIREZ
 
Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025
Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025
Protecting Your Sensitive Data with Microsoft Purview - IRMS 2025
Nikki Chapple
 
Measuring Microsoft 365 Copilot and Gen AI Success
Measuring Microsoft 365 Copilot and Gen AI SuccessMeasuring Microsoft 365 Copilot and Gen AI Success
Measuring Microsoft 365 Copilot and Gen AI Success
Nikki Chapple
 
Grannie’s Journey to Using Healthcare AI Experiences
Grannie’s Journey to Using Healthcare AI ExperiencesGrannie’s Journey to Using Healthcare AI Experiences
Grannie’s Journey to Using Healthcare AI Experiences
Lauren Parr
 
AI Trends - Mary Meeker
AI Trends - Mary MeekerAI Trends - Mary Meeker
AI Trends - Mary Meeker
Razin Mustafiz
 
6th Power Grid Model Meetup - 21 May 2025
6th Power Grid Model Meetup - 21 May 20256th Power Grid Model Meetup - 21 May 2025
6th Power Grid Model Meetup - 21 May 2025
DanBrown980551
 
Data Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any ApplicationData Virtualization: Bringing the Power of FME to Any Application
Data Virtualization: Bringing the Power of FME to Any Application
Safe Software
 
Jira Administration Training – Day 1 : Introduction
Jira Administration Training – Day 1 : IntroductionJira Administration Training – Day 1 : Introduction
Jira Administration Training – Day 1 : Introduction
Ravi Teja
 
GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...
GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...
GDG Cloud Southlake #43: Tommy Todd: The Quantum Apocalypse: A Looming Threat...
James Anderson
 
Offshore IT Support: Balancing In-House and Offshore Help Desk Technicians
Offshore IT Support: Balancing In-House and Offshore Help Desk TechniciansOffshore IT Support: Balancing In-House and Offshore Help Desk Technicians
Offshore IT Support: Balancing In-House and Offshore Help Desk Technicians
john823664
 
SDG 9000 Series: Unleashing multigigabit everywhere
SDG 9000 Series: Unleashing multigigabit everywhereSDG 9000 Series: Unleashing multigigabit everywhere
SDG 9000 Series: Unleashing multigigabit everywhere
Adtran
 
Dev Dives: System-to-system integration with UiPath API Workflows
Dev Dives: System-to-system integration with UiPath API WorkflowsDev Dives: System-to-system integration with UiPath API Workflows
Dev Dives: System-to-system integration with UiPath API Workflows
UiPathCommunity
 
Kubernetes Cloud Native Indonesia Meetup - May 2025
Kubernetes Cloud Native Indonesia Meetup - May 2025Kubernetes Cloud Native Indonesia Meetup - May 2025
Kubernetes Cloud Native Indonesia Meetup - May 2025
Prasta Maha
 
Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)
Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)
Nix(OS) for Python Developers - PyCon 25 (Bologna, Italia)
Peter Bittner
 
Cyber security cyber security cyber security cyber security cyber security cy...
Cyber security cyber security cyber security cyber security cyber security cy...Cyber security cyber security cyber security cyber security cyber security cy...
Cyber security cyber security cyber security cyber security cyber security cy...
pranavbodhak
 
Cognitive Chasms - A Typology of GenAI Failure Failure Modes
Cognitive Chasms - A Typology of GenAI Failure Failure ModesCognitive Chasms - A Typology of GenAI Failure Failure Modes
Cognitive Chasms - A Typology of GenAI Failure Failure Modes
Dr. Tathagat Varma
 
Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...
Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...
Agentic AI Explained: The Next Frontier of Autonomous Intelligence & Generati...
Aaryan Kansari
 
Cyber Security Legal Framework in Nepal.pptx
Cyber Security Legal Framework in Nepal.pptxCyber Security Legal Framework in Nepal.pptx
Cyber Security Legal Framework in Nepal.pptx
Ghimire B.R.
 
European Accessibility Act & Integrated Accessibility Testing
European Accessibility Act & Integrated Accessibility TestingEuropean Accessibility Act & Integrated Accessibility Testing
European Accessibility Act & Integrated Accessibility Testing
Julia Undeutsch
 

Super Fast Application development with Mura CMS

  • 2. What’s Up? • Build a fully functional application using Mura ORM & Mura.js
  • 3. Target Audience • ColdFusion/CFML Developer • Using Mura CMS • Familiar with • .CFCs • Mura’s base objects • Popular SQL DBMS • May (or may not) have used ColdFusion’s ORM
  • 4. What is Mura CMS? • Open source Content Management System (CMS) • Let users add/edit content, while you build applications • Used by clients large & small
  • 5. Mura Display Objects • Self-contained display • Portable • Distributable (via plugins) • Could be an entire application!
  • 6. The Mura Scope • A wrapper for interacting with Mura CMS • Access data • Create/modify data • Helper methods • “Mura” or “m” and still supports “$”
  • 8. Mura Display Objects • Managed via front-end only (in Mura v7+)
  • 10. Mura Display Objects • Directory based format {SiteID}/includes/themes/{ThemeName}/display_objects/ {SiteID}/includes/display_objects/
  • 11. Mura Display Objects • Directory based format (works in plugins too) plugins/{YourPlugin}/display_objects/
  • 12. Mura Display Objects • Or, register any directory you want … m.siteConfig().registerDisplayObjectDir(
 ‘/path/to/your/display_objects/‘
 ); // Path is a logical path to a CFML directory
 // Usually registered in onApplicationLoad();
  • 13. Mura Display Objects • Anatomy of a display object /mydisplayobject/ config.xml.cfm index.cfm configurator.cfm (optional)
  • 14. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*” />
  • 15. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*” /> * = all content types
  • 16. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*” /> * = all content types contenttypes=“{Type|Type/Subtype},Folder/Blog,Folder/News”
  • 17. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*” /> * = all content types contenttypes=“{Type|Type/Subtype},Folder/Blog,Folder/News” contenttypes=“” Blank = never display as draggable option
  • 18. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*”
 condition=“(m.content(‘title’) eq ‘News’)” />
  • 19. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*”
 iconclass=“mi-somefontawesomeiconclass” />
  • 20. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*”>
 
 <extensions>…</extensions>
 
 </mura>
  • 21. Mura Display Objects • config.xml.cfm <mura name=“My Display Object”
 contenttypes=“*”>
 
 <extensions>…</extensions>
 
 <imagesizes>
 <imagesize name=“yoursize” width=“100” height=“100”/>
 </imagesizes>
 
 </mura>
  • 22. Mura Display Objects • index.cfm (if rendering via CFML) <cfparam name=“objectparams.mytext” default=“”> <cfoutput>
 <h3>#esapiEncode(‘html’, objectparams.mytext)#</h3>
 </cfoutput>
  • 23. Mura Display Objects • index.cfm (if rendering via JS) <cfset objectparams.render=“client”>
  • 24. Mura Display Objects • index.cfm (if rendering via JS) <cfset objectparams.render=“client”> • mydisplayobject/model/handlers/myhandler.cfc
 
 component extends="mura.cfobject" {
 function onRenderStart(m){
 m.addToHTMLHeadQueue('<script src=“/path/to/js.js”></script>’);
 }
 }
  • 25. Mura Display Objects • configurator.cfm (optional) <cfparam name=“objectparams.mytext” default=“”>
 
 
 <cfoutput>
 <div class=“mura-control-group”>
 <label class=“mura-control-label”>My Text</label>
 <input type=“text”
 name=“mytext”
 class=“objectParam”
 value=“#esapiEncode(‘html_attr’, objectparams.mytext#”>
 </cfoutput>
  • 26. Mura Display Objects • configurator.cfm (optional) <cfparam name=“objectparams.mytext” default=“”>
 
 <cf_objectconfigurator>
 <cfoutput>
 <div class=“mura-control-group”>
 <label class=“mura-control-label”>My Text</label>
 <input type=“text”
 name=“mytext”
 class=“objectParam”
 value=“#esapiEncode(‘html_attr’, objectparams.mytext#”>
 </cfoutput>
 </cf_objectconfigurator>
  • 29. What is ORM? • Popular SQL DBMS • Only store/manipulate scalar values such as integers and strings organized within tables
  • 30. What is ORM? • Popular SQL DBMS • Only store/manipulate scalar values such as integers and strings organized within tables • Object values must either be converted into groups of simpler values, or only use simple scalar values
  • 31. What is ORM? • Object-Relationtional Mapping (ORM) addresses the main issue with SQL DBMS • Translates the logical representation of objects into an atomized form capable of being stored in a database, while preserving the properties of objects and their relationships so they can be reloaded as objects when needed
  • 32. What is ORM? • Object-Relational Mapping (ORM) is essentially a “virtual object database”
  • 33. What is Mura ORM?
  • 34. What is Mura ORM? • Mura ORM is a “virtual object database” that can be used within Mura
  • 35. What is Mura ORM? • Mura ORM is a “virtual object database” that can be used within Mura • Takes advantage of Di1 (dependency injection) • https://github.com/framework-one/di1
  • 36. What is Mura ORM? • Mura ORM is a “virtual object database” that can be used within Mura • Takes advantage of Di1 (dependency injection) • https://github.com/framework-one/di1 • Access & modify objects quickly & easily
  • 37. What is Mura ORM? • Mura ORM is a “virtual object database” that can be used within Mura • Takes advantage of Di1 (dependency injection) • https://github.com/framework-one/di1 • Access & modify objects quickly & easily • No need for custom DAOs, class extensions, or database-vendor- specific CRUD statements
  • 38. What is Mura ORM? • Mura ORM is a “virtual object database” that can be used within Mura • Takes advantage of Di1 (dependency injection) • https://github.com/framework-one/di1 • Access & modify objects quickly & easily • No need for custom DAOs, class extensions, or database-vendor- specific CRUD statements • Similar to ColdFusion-based Hibernate ORM (but not the same!)
  • 40. Mura ORM Configuration • Convention based vs. having to explicitly register entities {SiteID}/includes/model/ {SiteID}/includes/themes/{ThemeName}/model/
  • 41. Mura ORM Configuration • Convention based vs. having to explicitly register entities {SiteID}/includes/model/ {SiteID}/includes/themes/{ThemeName}/model/ 
 Or any display object’s “model” directory! ../display_objects/mydisplayobject/model/
  • 42. Mura ORM Configuration • Or, register any directory you want … m.globalConfig().registerModelDir(
 ‘/path/to/your/model/‘
 ); // Path is a logical path to a CFML directory
  • 43. Mura ORM Configuration • Or, register any directory you want … m.globalConfig().registerModelDir(
 ‘/path/to/your/model/‘
 ); // Path is a logical path to a CFML directory // Usually registered in onApplicationLoad();
  • 44. Mura ORM Configuration • Any .cfc under the “model” directory will automatically get registered with Di1
  • 45. Mura ORM Configuration • Any .cfc under the “model” directory will automatically get registered with Di1 • If it’s under a “beans” directory, it will be registered as a transient, not as a singleton
  • 46. Mura ORM Configuration • Any .cfc under the “model” directory will automatically get registered with Di1 • If it’s under a “beans” directory, it will be registered as a transient, not as a singleton • A transient exists only for a request and then is discarded • You get a new copy every time
  • 47. Mura ORM Configuration • Any .cfc under the “model” directory will automatically get registered with Di1 • If it’s under a “beans” directory, it will be registered as a transient, not as a singleton • A transient exists only for a request and then is discarded • You get a new copy every time • A singleton is shared among all threads and requests … there’s only one of them • You’re not getting a new copy every time • Good for service type objects
  • 48. Mura ORM Configuration • Any .cfc under the “model” directory will automatically get registered with Di1 • If it’s under a “beans” directory, it will be registered as a transient, not as a singleton ../model/beans/person.cfc ../model/beans/personaddress.cfc ../model/beans/personphonenumber.cfc
  • 49. Mura ORM Configuration • If a directory found under “model” is named “handlers” then any .cfc under this directory will be registered as eventHandlers
  • 50. Mura ORM Configuration • If a directory found under “model” is named “handlers” then any .cfc under this directory will be registered as eventHandlers • For example: ../model/handlers/myhandler.cfc ../model/services/handlers/myhandler.cfc
  • 51. Mura ORM Configuration • Reload Mura to get them registered
  • 52. Mura ORM Configuration • Reload Mura to get them registered • The first time you reload, and anytime you add new properties, be sure to append ‘&applydbupdates’ to the URL
  • 53. Mura ORM Configuration • Reload Mura to get them registered • The first time you reload, and anytime you add new properties, be sure to append ‘&applydbupdates’ to the URL • For example: 
 ./?appreload&applydbupates
  • 55. Mura Display Objects • Display object’s can have their own “model” directory ../display_objects/mydisplayobject/model/
  • 56. Mura Display Objects • Display object’s can have their own “model” directory ../display_objects/mydisplayobject/model/ • And their own “beans” directory ../display_objects/mydisplayobject/model/beans/
  • 57. Mura Display Objects • Display object’s can have their own “model” directory ../display_objects/mydisplayobject/model/ • And their own “beans” directory ../display_objects/mydisplayobject/model/beans/ • And “handlers” too ../display_objects/mydisplayobject/model/handlers/
  • 60. Address Book • Person • Zero or more phone numbers
  • 61. Address Book • Person • Zero or more phone numbers • Zero or more addresses
  • 62. Address Book • Person object with attributes/fields
  • 63. Address Book • Person object with attributes/fields • Person’s name
  • 64. Address Book • Person object with attributes/fields • Person’s name • List of phone numbers • PhoneNumber objects
  • 65. Address Book • Person object with attributes/fields • Person’s name • List of phone numbers • PhoneNumber objects • List of addresses • Address objects
  • 66. Address Book • The address book entry (Person) is treated as a single object
  • 67. Address Book • The address book entry (Person) is treated as a single object • It can be referenced by a single variable containing a pointer to the object
  • 68. Address Book • The address book entry (Person) is treated as a single object • It can be referenced by a single variable containing a pointer to the object • Various helper methods can be associated with the object, such as a method to return the preferred phone number, the home address, and so on
  • 71. Mura ORM Entity • Component (CFC) Attributes entityname 
 table
 datasource
 discriminatorcolumn 
 discriminatorvalue
 orderby
 readonly
  • 72. Mura ORM Entity • Component (CFC) Attributes entityname 
 table
 datasource
 discriminatorcolumn 
 discriminatorvalue
 orderby
 readonly • Mura-specific attributes public
 bundleable 
 cachename
 dbtype
 manageschema
 usetrash

  • 73. Mura ORM Entity component
 extends=“mura.bean.beanORM”
 entityname=“person” … {
 
 // primary key (are UUIDs)
 property name=“personid” fieldtype=“id”;
 
 }
  • 74. Mura ORM Entity component
 extends=“mura.bean.beanORM”
 entityname=“person” … {
 
 // primary key
 property name=“personid” fieldtype=“id”;
 
 // person attributes
 property name=“namefirst” datatype=“varchar”;
 property name=“namelast” datatype=“varchar”;
 }
  • 75. Mura ORM Entity component
 extends=“mura.bean.beanORM”
 entityname=“person” … {
 … // foreign key(s)
 property name=“user” 
 cfc=“user” 
 fieldtype=“many-to-one” 
 fkcolumn=“userid”;
 }
  • 76. Mura ORM Entity component
 extends=“mura.bean.beanORM”
 entityname=“person” … {
 … // relationship(s)
 property name=“phonenumbers” 
 singularname=“phonenumber”
 cfc=“personphonenumber” 
 fieldtype=“one-to-many”
 cascade=“delete”;
 }
  • 77. Mura ORM Entity component
 extends=“mura.bean.beanORM”
 entityname=“personphonenumber” … {
 … // relationship(s)
 property name=“person” 
 cfc=“person” 
 fieldtype=“many-to-one”
 fkcolumn=“personid”;
 }
  • 78. Mura ORM Entity component
 extends=“mura.bean.beanORM”
 entityname=“personphonenumber” … {
 … // attribute(s)
 property name=“phonenumber” 
 datatype=“varchar”
 length=“255”
 required=true
 message=“Phone Number is required.”;
 }
  • 79. Mura ORM Entity • Property Attributes name
 persistent
 fieldtype
 cfc
 fkcolumn
 type
 cascade
 singularname
 orderby
 length
 default
 ormtype
  • 80. Mura ORM Entity • Property Attributes name
 persistent
 fieldtype
 cfc
 fkcolumn
 type
 cascade
 singularname
 orderby
 length
 default
 ormtype • Mura-specific attributes loadkey
 datatype
 nullable
 required
 validate
 message
 regex
 comparable

  • 81. Mura ORM Entity • Property validation attributes minValue maxValue minLength maxLength minCollection maxCollection minList maxList inList method lte lt gte gt eq neq

  • 82. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’);
  • 83. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’);
  • 84. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’); entity.set(‘attribute’, ‘Some Value’);
  • 85. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’); entity.set(‘attribute’, ‘Some Value’).save();
  • 86. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’); entity.set(‘attribute’, ‘Some Value’).save(); entity.get{RelatedEntity}();
  • 87. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’); entity.set(‘attribute’, ‘Some Value’).save(); entity.get{RelatedEntity}(); entity.get{RelatedEntity}Iterator();
  • 88. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’); entity.set(‘attribute’, ‘Some Value’).save(); entity.get{RelatedEntity}(); entity.get{RelatedEntity}Iterator(); entity.get{RelatedEntity}Query();
  • 89. Mura ORM Entity entity = m.getBean(‘entityName’)
 .loadBy(someAttribute=‘Something’); entity.get(‘attribute’); entity.set(‘attribute’, ‘Some Value’).save(); entity.get{RelatedEntity}(); entity.get{RelatedEntity}Iterator(); entity.get{RelatedEntity}Query(); m.getFeed(‘entityName’);
  • 90. Mura ORM Entity contactBean = m.getBean(‘person’)
 .loadBy(personid=m.event(‘pid’));
  • 91. Mura ORM Entity contactBean = m.getBean(‘person’)
 .loadBy(personid=m.event(‘pid’)); if ( contactBean.exists() ) { 
 // This bean exists! } else {
 // Do something if it’s a new bean }
  • 92. Mura ORM Entity contactBean = m.getBean(‘person’)
 .loadBy(personid=m.event(‘pid’)); // Phone Numbers Iterator
 itPhones = contactBean.getPhoneNumbersIterator();
  • 93. Mura ORM Entity contactBean = m.getBean(‘person’)
 .loadBy(personid=m.event(‘pid’)); // Phone Numbers Iterator
 itPhones = contactBean.getPhoneNumbersIterator(); 
 while ( itPhones.hasNext() ) {
 phone = itPhones.next();
 WriteOutput( phone.get(‘phonenumber’) );
 }
  • 95. Mura ORM Feed (Content) m .getFeed(‘content’);
  • 96. Mura ORM Feed (Content) m .getFeed(‘content’) .where() // optional … but readable .prop(‘title’) .isEQ(‘News’) .orProp(‘title’) .isEQ(‘Blog’) .sort(‘title’, ‘desc’) .getIterator();
  • 97. Mura ORM Feed (Entity) m .getFeed(‘person’) .where() .prop(‘namefirst’) .containsValue(m.event(‘namefirst’)) .orProp(‘namelast’) .isEQ(m.event(‘namelast’)) .getIterator();
  • 98. Mura ORM Feed (Sorting) m .getFeed(‘person’) .where() .prop(‘userid’) .isEQ(m.currentUser(‘userid’) .sort(‘namelast’, ‘asc’) .sort(‘namefirst’, ‘desc’) .getIterator();
  • 99. Mura ORM Feed (Methods) m .getFeed([entityname]) .where() .prop([property]) .andProp([property]) .orProp([property]) .isEQ([criteria]) .isNEQ([criteria]) .isLT([criteria]) .isLTE([criteria]) .isGT([criteria]) .isGTE([criteria]) .containsValue([criteria]) .null() .beginsWith([criteria]) .endsWith([criteria]) .openGrouping() .andOpenGrouping() .closeGrouping() .sort([property],[asc||desc]) .itemsPerPage([itemsPerPage]) .maxItems([maxItems]) .isIn([list criteria]) .isNotIn([list criteria]) .innerJoin([relatedEntity]) .leftJoin([relatedEntity]) .getQuery() .getIterator()
  • 101. Mura ORM Events • ../model/handlers/myhandler.cfc
  • 102. Mura ORM Events • ../model/handlers/myhandler.cfc onBefore{Entity}Save(m) {
 var bean = m.event(‘bean’);
 … 
 }
  • 103. Mura ORM Events • ../model/handlers/myhandler.cfc onBefore{Entity}Save(m) {
 var bean = m.event(‘bean’);
 … 
 } // Plus any other Mura event listeners you want!
  • 104. Mura ORM Events • Support for ColdFusion/CFML ORM Events
 preLoad(); preUpdate(); preCreate(); preInsert(); preDelete(); 
 postLoad(); postUpdate(); postCreate(); postInsert(); postDelete();

  • 107. Mura.js • A lightweight utility to decouple dependency on jQuery
  • 108. Mura.js • A lightweight utility to decouple dependency on jQuery • A JS framework for interacting with the Mura JSON API
  • 109. Mura.js • Familiar jQuery syntax Mura(function(m) { m(‘.target’).each(function() {
 m(this).html(‘Mura found you!’);
 });
 });
  • 110. Mura.js • Baked-in AJAX support 
 Mura
 .ajax({
 type: ‘post’,
 url: ’https://domain.com/path/',
 data: { key: value },
 success: function(resp) { console.log(resp) },
 error: function(resp) { console.log(resp) }
 });
  • 111. Mura.js • Baked-in AJAX support & JS promises 
 Mura
 .get(‘https://domain.com/path/')
 .then(function(resp) {
 // success
 Mura(‘#target’).html(resp.data.html);
 }, function(e) {
 // fail
 });
  • 112. Mura.js • Baked-in AJAX support & JS promises 
 Mura
 .post(
 ‘https://domain.com/path/',
 { key: value }
 )
 .then(function(resp) {
 // success
 }, function(e) { 
 // error 
 });
  • 113. Mura.js • JS promises can be stacked like Russian dolls 
 Mura.get(‘https://domain.com/path/')
 .then(function(resp) {
 // success
 Mura.get(‘https://domain.com?id=' + resp.id)
 .then(function(newresp) {
 Mura(‘#target’).html(newresp.html);
 });
 }, function(e) { 
 // error 
 });
  • 114. Mura.js • Register event handlers 
 Mura(‘#mybutton’)
 .on(‘click’, function(e) {
 e.preventDefault();
 console.log(e);
 });
  • 115. Mura.js • Mura.DOMSelection class • Wraps selected target via the Mura() method
  • 116. Mura.js • Mura.DOMSelection class • Wraps selected target via the Mura() method • Allows you to handle selection as a single object or a collection
  • 117. Mura.js • Mura.DOMSelection class • Wraps selected target via the Mura() method • Allows you to handle selection as a single object or a collection • Single object
 Mura(‘.target’).html(‘Hello world!’);
  • 118. Mura.js • Mura.DOMSelection class • Wraps selected target via the Mura() method • Allows you to handle selection as a single object or a collection • Single object
 Mura(‘.target’).html(‘Hello world!’);
 • Collection
 Mura(‘.target’).each(function() {
 Mura(this).html(‘Hello world!’);
 });
  • 119. Mura.js • Supported methods can be found under:
 
 {SiteID}/js/src/mura.domselection.js
  • 120. Mura.js • Load entities
 
 Mura
 .getEntity(‘person’)
 .loadBy(‘personid’, pid)
 .then(function(person) {
 // success
 console.log(person);
 }, function(person) {
 // fail
 console.log(person.get(‘errors’));
 });
  • 121. Mura.js • Create/Update entities
 
 Mura
 .getEntity(‘person’)
 .loadBy(‘personid’, pid)
 .then(function(person) {
 // load success
 person.set(‘namelast’, ‘Withington’)
 .save()
 .then(function(person) {
 // save success
 }, function(person) { 
 // save fail 
 });
 });
  • 122. Mura.js • Delete entities
 
 Mura
 .getEntity(‘person’)
 .loadBy(‘personid’, pid)
 .then(function(person) {
 // load success
 person
 .delete()
 .then(function(person) {
 // delete success
 }, function(person) { 
 // delete fail 
 });
 });
  • 123. Mura.js • Feed API
 
 Mura
 .getFeed(‘person’)
 .where() // optional
 .prop(‘namelast’).isEQ(‘Levine’)
 .orProp(‘namelast’).beginsWith(‘Withing’)
 .getQuery()
 .then(function(people) {
 // success
 people.each(function(prsn, idx) {
 console.log(prsn.get(‘namefirst’) + ‘ ‘ + prsn.get(‘namelast’));
 });
 });
  • 126. Mura Display Objects • Loading JS/CSS files
 
 Mura(function(m) {
 m.loader()
 .loadcss(m.themepath + ‘/path/all.css’, {media:’all’})
 .loadcss(m.themepath + ‘/path/print.css’, {media:’print’})
 .loadjs(
 m.themepath + ’/path/script1.js’,
 m.themepath + ’/path/script2.js’,
 function() {
 // Now do something with the loaded JS 
 }
 );
 });
  • 127. Mura Display Objects • Mura.loader() • Only loads files once (no duplicates)
  • 128. Mura Display Objects • Mura.loader() • Only loads files once (no duplicates) • loadjs() can take string arguments or arrays of strings
  • 129. Mura Display Objects • Mura.loader() • Only loads files once (no duplicates) • loadjs() can take string arguments or arrays of strings • if array, files are loaded asynchronously
  • 130. Mura Display Objects • Mura.loader() • Only loads files once (no duplicates) • loadjs() can take string arguments or arrays of strings • if array, files are loaded asynchronously • if string, files are loaded synchronously
  • 131. Mura Display Objects • loadjs() Synchronous Example • When the 2nd file is loading, it can reference variables from 1st
 
 Mura(function(m) {
 m.loader()
 .loadjs(
 m.themepath + ’/path/script1.js’,
 m.themepath + ’/path/script2.js’,
 function() {
 // Now do something with the loaded JS 
 }
 );
 });
  • 132. Mura Display Objects • loadjs() Asynchronous Example • When the 2nd file is loading, it cannot reference variables from 1st
 
 Mura(function(m) {
 m.loader()
 .loadjs(
 [
 m.themepath + ’/path/script1.js’,
 m.themepath + ’/path/script2.js’
 ],
 function() {
 // Now do something with the loaded JS 
 }
 );
 });
  • 133. Mura Display Objects • index.cfm (Full example if rendering via Server/CFML) <cfparam name=“objectparams.mytext” default=“”>
 <cfoutput>
 <h3>#esapiEncode(‘html’, objectparams.mytext)#</h3>
 </cfoutput>
 
 <script>
 Mura(function(m) {
 m.loader()
 .loadcss(m.themepath + ‘/path/my.css’)
 .loadjs(m.themepath + ’/path/my.js’);
 });
 </script>
  • 134. Mura Display Objects • index.cfm (Full example if rendering via Client/JS) Mura.DisplayObject.myobject = Mura.UI.extend({
 render: function() {
 this.container = Mura(this.context.targetEl);
 
 Mura.loader()
 .loadcss(Mura.themepath + ‘/path/my.css’)
 .loadjs(Mura.themepath + ’/path/my.js’,
 function(){
 //DO STUFF
 }
 );
 } });
  • 138. content_types • Control body by Type/Subtype
  • 139. content_types • Control body by Type/Subtype • Folder/Contacts • Page/Contact
  • 140. content_types • Control body by Type/Subtype
 
 {SiteID}/includes/content_types/
  • 141. content_types • Control body by Type/Subtype
 
 {SiteID}/includes/content_types/
 {SiteID}/includes/themes/{ThemeName}/content_types/
  • 142. content_types • Or, register any directory you want … m.siteConfig().registerContentTypeDir(
 ‘/path/to/your/content_types/‘
 ); // Path is a logical path to a CFML directory
  • 143. content_types • Or, register any directory you want … m.siteConfig().registerContentTypeDir(
 ‘/path/to/your/content_types/‘
 ); // Path is a logical path to a CFML directory // Usually registered in onApplicationLoad();
  • 144. content_types • Control body by Type/Subtype
 
 {SiteID}/includes/content_types/
 {SiteID}/includes/themes/{ThemeName}/content_types/
 • Target Type/Subtype by directory structure:
 
 content_types/{type}
  • 145. content_types • Control body by Type/Subtype
 
 {SiteID}/includes/content_types/
 {SiteID}/includes/themes/{ThemeName}/content_types/
 • Target Type/Subtype by directory structure:
 
 content_types/{type}
 content_types/page/index.cfm
  • 146. content_types • Control body by Type/Subtype
 
 {SiteID}/includes/content_types/
 {SiteID}/includes/themes/{ThemeName}/content_types/
 • Target Type/Subtype by directory structure:
 
 content_types/{type}
 content_types/page/index.cfm
 
 content_types/{type}_{subtype}
  • 147. content_types • Control body by Type/Subtype
 
 {SiteID}/includes/content_types/
 {SiteID}/includes/themes/{ThemeName}/content_types/
 • Target Type/Subtype by directory structure:
 
 content_types/{type}
 content_types/page/index.cfm
 
 content_types/{type}_{subtype}
 content_types/page_contact/index.cfm
  • 148. content_types • Anatomy of a content_type
 
 content_types/folder_contacts/index.cfm
 content_types/folder_contacts/config.xml.cfm
  • 149. content_types • Anatomy of a content_type
 
 content_types/folder_contacts/index.cfm
 content_types/folder_contacts/config.xml.cfm
 • index.cfm = the body/view
  • 150. content_types • Anatomy of a content_type
 
 content_types/folder_contacts/index.cfm
 content_types/folder_contacts/config.xml.cfm
 • index.cfm = the body/view • config.xml.cfm = the configuration
  • 151. content_types • Anatomy of a content_type
 
 content_types/folder_contacts/index.cfm
 content_types/folder_contacts/config.xml.cfm
 
 content_types/folder_contacts/model/
  • 152. content_types • Anatomy of a content_type
 
 content_types/folder_contacts/index.cfm
 content_types/folder_contacts/config.xml.cfm
 
 content_types/folder_contacts/model/
 content_types/folder_contacts/model/beans/
 content_types/folder_contacts/model/handlers/
  • 153. Q+A
  • 154. Resources • http://www.getmura.com • https://github.com/stevewithington/cfsummit-2016 • https://github.com/stevewithington/muracontacts • https://github.com/stevewithington/murahelloworld • https://groups.google.com/forum/#!forum/mura-cms-developers