Warning | ||
---|---|---|
| ||
Updating the course for FarCry 6.x. If you can help let us know! Put your notes in the comments for the page. Changes should include:
|
Objectives
Excerpt |
---|
This unit covers the fundamental building blocks of any FarCry application: the Content Type. By the end of this unit you should be able to create and deploy your own content types. |
...
We can invent things as we need them to showcase aspects of the technology without being constrained by the more traditional, user focused goals of a typical application. It also has the potential of being a lot more complex than your average "build a blog in 10 minutes" exercise which appears to be the benchmark for determining the viability of many frameworks.
...
We need a central profile to capture our catalogue of super powered beings, their properties and relationships.
Mockup | ||||||||
---|---|---|---|---|---|---|---|---|
|
The Super Power
Super powers are generally not unique (with some exceptions). It would be nice to have a library of super powers we can assign to super heroes as we add them to the system.
Mockup | ||||||||
---|---|---|---|---|---|---|---|---|
|
The Super Group
We're not talking ABBA here. The super group is a league or association of super heroes; for example, the Sovereign 7, Fantastic Four, and the League of Justice. A super hero could potentially belong to several groups over their lifetime.
Mockup | ||||||||
---|---|---|---|---|---|---|---|---|
|
Building a Content Type
The FarCry content type is a central building block for the FarCry Framework. Developers can extend and change the behaviour of existing content types, create their own content types and group related content types into libraries.
...
Code Block |
---|
<!--- ./packages/types/superHero.cfc ---> <cfcomponent name="superHero" extends="farcry.core.packages.types.types" output="false" displayname="Super Hero"> <cfproperty name="title" type="string" default="" hint="Super hero title." /> <cfproperty name="secretHideout" type="string" hint="The secret hideout location of the super hero" /> <cfproperty name="teaser" type="longchar" default="" hint="Mini intro for super hero biography." /> <cfproperty name="biography" type="longchar" default="" hint="Super hero biography." /> <cfproperty name="imgHero" type="string" hint="The image of the hero" /> </cfcomponent> |
...
FarCry detects that a component exists but hasn't got a corresponding persistence model in the database - the "deploy" options creates all the tables required for this content type. The columns are mapped to their relevant data types, depending on the FarCry data type nominated and the specific relational database you are using.
Tip |
---|
FarCry 5.x supports mySQL, MS SQL, Postgresql and Oracle. |
...
Info |
---|
The integrated FarCry ORM differs from other frameworks that might ordinarily rely on the database schema for metadata, for example Reactor and Transfer. Typically these frameworks will generate components to manage interactions with the database. In contrast, FarCry generates a data schema to manage the data represented by its components. |
FarCry relies on the component to define the required data model definition and has tools to keep the database model in sync with changes to the component property set. Not only will the framework deploy tables it will also alter columns and data-types to match changes in the underlying component as required. The COAPI is even clever enough to set precision on table columns and build indices for better performance.
All properties in the component map to a specific column in the content type table, with the exception of array properties (discussed later on).
Warning |
---|
Tip |
types is an abstract class that contains a number of system attributes/properties inherited from types requiredthat are inherited by any custom content type. |
Walkthrough: Creating Super Hero
...
- Create a new file called superHero.cfc and save this into your project's ./packages/types directory.
- Copy the following code into this file, save and review with the instructor
Code Block <!--- --->title ./myproject/packages/types/superHero.cfc <cfcomponent name="superHero" extends="farcry.core.packages.types.types" output="false" displayname="Super Hero"> <cfproperty name="title" type="string" default="" hint="Super hero title." /> <cfproperty name="secretHideout" type="string" hint="The secret hideout location of the super hero" /> <cfproperty name="teaser" type="longchar" default="" hint="Mini intro for super hero biography." /> <cfproperty name="biography" type="longchar" default="" hint="Super hero biography." /> <cfproperty name="imgHero" type="string" hint="The image of the hero" /> </cfcomponent>
- Go to the FarCry Webtop and deploy the content type: ADMIN > Developer Utilities > COAPI Tools > Types
- Locate your new content type, "superHero" and select DEPLOY.
- Click on the [Scaffold] button now to create an Administration scaffold
- Select the checkbox next to "Create type admin interface",
- put in a title for your administration list
- select label and imgHero as the fields to appear in your list
Info title Basic Scaffolding The Scaffold option for deployed content types generates some sample code you can use to get started right away.
"Create type admin interface" creates a small XML file that generates a menu item for you in the FarCry webtop.
The framework provides a default edit handler and display view so no need to add anything else here just yet.
- Reload your Application. This time you will need to update the [Webtop] option
- Go to the Custom Content Tab. Locate your Super Hero admin and create some Heroes (or Villains!)
Info title Editing Content Types When you created your first superHero object you may have noticed a rudimentary edit handler allowing you to key in details, save and update. That's not actually part of the scaffold code that was generated at all. The edit handler is dynamically generated at run time based on the metadata associated with the superHero component's cfproperty tags. Ok. So its pretty minimalist now but wait.. it's only the beginning.
Warning title Wait Up! Make sure you understand the concept of extends, displayname and property type before the instructor starts babbling on about something else.
...
So without going into the detail behind how formtools works - what's in it for the FarCry developer? Well most of the time you will never have to build an administration interface for your content types. Seriously.
Next we 're going to will extend our simple superHero example content type to leverage these new "formtool" features. IWe'm re focusing on a selection of the individual property tags in superHero.cfc for the sake of brevity so be sure to fill in the gaps.
Check out the code sample on this page, and pay particular attention to the attributes starting with "ft".
Code Block | ||
---|---|---|
| ||
---> <cfcomponent name="superHero" extends="farcry.core.packages.types.types" output="false" displayname="Super Hero"> <cfproperty name="title" type="string" default="" hint="Super hero title." ftSeq="1" ftFieldset="General Details" ftLabel="Title" /> <cfproperty name="secretHideout" type="string" hint="The secret hideout location of the super hero" ftSeq="2" ftFieldset="General Details" ftLabel="Secret Hideout" /> <cfproperty name="teaser" type="longchar" default="" hint="Mini intro for super hero biography." ftSeq="3" ftFieldset="General Details" ftLabel="Teaser" /> <cfproperty name="biography" type="longchar" default="" hint="Super hero biography." ftSeq="4" ftFieldset="General Details" ftLabel="Biography" ftType="richtext" /> <cfproperty name="imgHero" type="string" hint="The source image to upload" ftSeq="10" ftFieldset="Imagery" ftLabel="Hero Image" ftType="image" ftDestination="/images/superHero/imgHero" ftImageWidth="120" ftImageHeight="120" ftAutoGenerateType="fitInside" /> </cfcomponent> |
Form Layout
By modifying he the ftSeq
and ftFieldset
attributes we can order form fields and group them into specific field sets. Every field sharing the same fieldset value will appear in a correctly formatted field grouping in the edit handler.
Tip | ||
---|---|---|
| ||
If you are feeling really adventurous you could add |
Form UI Controls
There are several ft
attributes that are common across all formtools, such as ftLabel
which provides a text label for the form field.
...
Attribute | Description | Value |
---|---|---|
ftType | Type of form control | Defaults to the type value |
ftLabel | Text label for the form element | Defaults to property name if absent |
ftShowLabel | Flag to show/hide text label for the form element | Defaults to true |
ftSeq | Numeric value for form field display order | No default value |
ftFieldset | Text used as a title to group a set of fields | No default value |
ftWizardStep | Allows you to create multi-step forms; set to the title of the step as you would ftFieldset | No default value |
ftStyle | Inline style to apply to form element | No default value |
ftClass | Class to apply to form element | No default value |
ftDisplayOnly | Boolean that prevents the field from being editable | Defaults to false |
ftDefault | Default form field value | No default value |
ftDefaultType | The type of default value: "value", "expression" or "evaluate" | Defaults to "value" |
ftHelpTitle | Title of a fieldset-related inline help section; only works on the first property in a fieldset | No default value |
ftHelpSection | Section text for inline help related to fieldset; only works on the first property in a fieldset | No default value |
ftValidation | A comma-separated list of validation requirements | No default value |
ftHint | A small inline hint that appears below the field to assist users | No default value |
Formtool Validation
...
Info | ||
---|---|---|
| ||
Client side validation options reflect the move to jquery/jqueryui as the standard UI for the webtop |
ftValidation with a comma separated list of validation requirements.
...
Code Block | ||
---|---|---|
| ||
<cfproperty name="Body" type="longchar" hint="Main body of content." required="no" default="" ftSeq="12" ftFieldset="Body" ftWizardStep="Body" ftLabel="Body" ftType="richtext" ftImageArrayField="aObjectIDsaMedia" ftImageTypename="dmImage" ftImageField="StandardImage" ftTemplateTypeList="dmImage,dmFile,dmNavigation,dmHTML" ftTemplateWebskinPrefixList="insertHTML" ftTemplateSnippetWebskinPrefix="insertSnippet" /> <cfproperty name="aObjectIDsaMedia" type="array" hint="Holds objects to be displayed at this particular node. Can be of mixed types." required="no" default="" " required="no" default="" ftSeq="13" ftFieldset="Relationships" ftWizardStep="Body" ftLabel="Associated Media" ftJoin="dmImage,dmFile,dmFlash" bSyncStatus="true" /> |
It won't surprise you to learn that the ftType attribute options begin to describe a whole library form controls that you can leverage to do your bidding including:
...
A complete compendium of formtool controls can be found on the FarCry Developer WIKI at:
- http://docs.farcrycore.org/p600/ – select Formtools
- http://farcry.jira.com/wiki/display/FCDEV40/Form+Tool+Property+MetadataFCDEV50/Formtools
- http://farcry.jira.com/wiki/display/FCDEV50/FormtoolsFCDEV40/Form+Tool+Property+Metadata
Anatomy of a Formtool
Each ftType corresponds to a specific formtool component that comprises of at least an edit, display and validation method.
The edit method defines the relevant form element, any additional semantic markup that might be relevant (such as a label) and any associated JavaScript or UI cleverness needed to render the control.
Standard formtool methods:
Edit
builds the form control with associated smarts.Display
describes the semantic markup required to render a display for the property. For example, an ftType="url" will activate the URL as a link by default.Validation
provides some server side validation, and in the case of complex controls mangles the data into the format the underlying database model expects.
Best of all if you don't like the core library of widgets then you can always make your own. The core formtools can be overridden, and/or supplemented with brand new controls by deploying them through both plugins and your own project. But lets just stick to the basics for now .
Walkthrough: Using Formtools Metadata
- Update your superHero component metadata using the example code above as a guide.
Note title Restarting Your Application Every time you update component metadata you will need to reinitialise the application for FarCry to recognise the change. This can be done by adding updateapp=1 to the end of your projects URL or using the [Reload Application] utility in the webtop or the admin "tray" option.
- Reload the edit form for your "Super Hero" and make sure things are going according to plan.
- Try uploading a few images and discuss with your instructor.
Tip | ||
---|---|---|
| ||
The image quality of the basic image manipulation in FarCry can be relatively poor. The system is designed to work with ColdFusion 7.0.1 by default. However, you can drastically improve image quality by installing one of several image plugins, freely available from the community. For example, if you are running on ColdFusion 8 consider using the farcrycfimage plugin. Image and other plugins are available here: http://farcry.jira.com/wiki/display/FCPLUG/Home |
Wizards
...
| |
FarCry 6.x leverages the underlying ColdFusion 8 CFIMAGE tools. |
Wizards
But what about a multi-step wizard you say? So far the content types have been simple, but what if we have a component with properties up the wazoo or just plain like this wizard caper? Wizards can be defined with simple formtool (aka "ft") metadata as well.
...
- Open the ./packages/superHero.cfc
- Add Wizard Steps using the ftWizardStep formtool metadata
Code Block <!--- ./packages/types/superHero.cfc ---> <cfcomponent name="superHero" extends="farcry.core.packages.types.types" output="false" displayname="Super Hero"> <cfproperty name="title" type="string" default="" hint="Super hero title." ftSeq="1" ftFieldset="General Details" ftWizardStep="Teaser Information" ftLabel="Title" ftValidation="required" /> <cfproperty name="secretHideout" type="string" hint="The secret hideout location of the super hero" ftSeq="2" ftFieldset="General Details" ftWizardStep="Teaser Information" ftLabel="Secret Hideout" /> <cfproperty name="teaser" type="longchar" default="" hint="Mini intro for super hero biography." ftSeq="3" ftFieldset="General Details" ftWizardStep="Teaser Information" ftLabel="Teaser" /> <cfproperty name="biography" type="longchar" default="" hint="Super hero biography." ftSeq="4" ftFieldset="General Details" ftWizardStep="Biography Details" ftLabel="Biography" ftType="richtext" /> <cfproperty name="imgHero" type="string" hint="The source image to upload" ftSeq="10" ftFieldset="Imagery" ftWizardStep="Imagery" ftLabel="Hero Image" ftType="image" ftDestination="/images/superHero/imgHero" ftImageWidth="120" ftImageHeight="120" ftAutoGenerateType="fitInsidecenter" /> </cfcomponent>
- Make sure that each <cfproperty> has a relevant ftWizardStep entry
- Reload the formtool metadata and test that your wizard works.
...
- Create a new ColdFusion component called ./packages/types/SuperPower.cfc
- Create the following properties
- title (string; required... think ftValidation="required")
- description (longchar; try limiting the total characters to 512)
- imgPower (image; 100x100 dimensions, destination: /images/superPower/imgPower)
- Deploy the content type into the database
- Use the Scaffold tool in the COAPI area to create an administration page
- Add a bunch of super powers to your application (ColdFusion, Flex, Flash, Photoshop, etc. ) You will find some content for powers in your media folder
Bonus Lab: Image Sourced from Library
You can easily source images from the global image library. If you have some time on your hands, try implementing the an image sourced from the library with custom crops for your local content item.
Code Block | ||
---|---|---|
| ||
<cfproperty name="imageSourceID" type="string"
ftSeq="2" ftFieldset="General Details" ftLabel="Source Image"
ftType="uuid" ftJoin="dmImage"
ftHint="Select an image from the image library or create a new image.">
<cfproperty name="imageCarousel" type="string"
ftSeq="3" ftFieldset="General Details" ftLabel="Carousel Image"
ftType="image" ftDestination="/images/dmCarouselItem/imageCarousel"
ftAllowUpload="false" ftSourceField="imageSourceID:SourceImage"
ftAutoGenerateType="center" ftImageWidth="620" ftImageHeight="200"
ftQuality="0.8" ftInterpolation="blackman">
<cfproperty name="imageThumbnail" type="string"
ftSeq="4" ftFieldset="General Details" ftLabel="Thumbnail Image"
ftType="image" ftDestination="/images/dmCarouselItem/imageThumbnail"
ftAllowUpload="false" ftSourceField="imageSourceID:SourceImage"
ftAutoGenerateType="center" ftImageWidth="95" ftImageHeight="30"
ftQuality="0.8" ftInterpolation="blackman"
ftHint="">
|