By the end of this unit you will have learnt how to relate content types to one another, using one-to-many and many-to-many relationships. You will be able to create user interfaces to allow editors to select and relate objects from libraries. |
An array property can contain a series of object references to other objects in the COAPI; a many-to-many relationship. When it's presented to the system view or webskin it's represented as an actual array property, where each index contains the objectid (or primary key) of the related object. This objectid can then be used to reference the related object as needed. In addition, the order (or sequence) of the relationship is preserved so that programmers can rely on the order to be exactly as the user nominated.
Array properties in terms of how they are defined in a content type really don't differ all that much to normal properties. You add a <cfproperty> and simply define type="array" and a list of content types that you would like to allow to be associated using ftJoin, for example ftJoin="superPower". However, what happens behind the scenes is much more involved.
<cfcomponent ..> ... <cfproperty name="aPowers" type="array" hint="Array of superhuman powers." ftSeq="12" ftFieldset="Related Content" ftWizardStep="Relationships" ftLabel="Powers" ftType="array" ftJoin="superPower" /> ... </cfcomponent> |
Array properties must be prefixed with the letter "a". If you don't do that then the deployment window will not be able to correctly detect that you have deployed the array property. |
If you open up the database model after you deploy an array property, you'll notice that the property (for example, aPowers) is not represented by a column in the table. Array data is essentially an index of references to other objects and is defined by its own linked table (for example, superHero_aPowers). The array table includes the parent object, the referenced objectid, the sequence multiple entries should be represented in, and the typename of the referenced object. Importantly, the data model in the database itself does not need to be understood to work with arrays - the framework handles recording and retrieving this information.
Array properties can themselves be extended to include additional attributes - but lets keep it simple for now. |
ftJoin is a critical piece of metadata as it designates exactly what content types are allowed to be related to this specific property. Interestingly, FarCry Framework is quite happy to have multiple content types referenced, even though the content types themselves may have very different sets of properties. The default UI controls for libraries are designed to allow users to switch between nominated content types if multiple types have been referenced.
<cfproperty name="aMedia" type="array" hint="Local media library." required="no" default="" ftSeq="13" ftFieldset="Relationships" ftLabel="Associated Media" ftType="array" ftJoin="dmImage,dmFile,dmFlash" /> |
By default the library UI control for an array property will list all content objects of the nominated type, ordered by datetimelastupdated.
It won't surprise you that the options for the library are extensive and include the ability to restrict what content objects are available, the order they are displayed, how they are displayed and so on. Review the formtool metadata dictionary entry on Libraries for more details. |
We're going to add an array property [aPowers] to join our hero to the powers they possess.
<cfproperty ftSeq="12" ftFieldset="Related Content" ftWizardStep="Relationships" name="aPowers" type="array" ftLabel="Powers" ftJoin="superPower" hint="Array of superhuman powers." /> |
By default the library will only show a content object's label, and if that's blank the objectid. However, like many aspects of the framework, this behaviour can be modified to suit your specific application. FarCry Framework has a special webskin (or view) for rendering the objects selected for the library: ./webskin/typename/librarySelected.cfm (where typename is represented by the actual typename you are trying to modify).
Your super powers only shows the label for your content object. Lets make that look prettier.
<cfsetting enablecfoutputonly="true" /> <!--- @@displayname: Power (Library) ---> <cfoutput> <div> <img src="#application.url.webroot##stobj.imgPower#" alt="#stobj.title#" title="#stobj.title#" /> #stobj.title#<br /> #stobj.description# </div> </cfoutput> <cfsetting enablecfoutputonly="false" /> |
A UUID property is a single object reference or one-to-many relationship. It behaves in very much the same way as an array property in terms of UI and the library options that are available. The object reference is stored in a simple string field in the database.
<cfproperty name="sidekickid" type="uuid" hint="Super hero sidekick." ftSeq="11" ftFieldset="Related Content" ftWizardStep="Relationships" ftLabel="Sidekick" ftType="uuid" ftJoin="superHero" /> |
Let's create an option to select another hero in the system as a sidekick.
<cfproperty name="sidekickid" type="uuid" hint="Super hero sidekick." ftSeq="11" ftFieldset="Related Content" ftWizardStep="Relationships" ftLabel="Sidekick" ftType="uuid" ftJoin="superHero" /> |
Create your own "super group" content type, complete with an array of super hero objects.
If you are feeling super-keen, add a librarySelected webskin for your Super Hero content type. |